From 0c046d3261d9be6d13b9d9ebb586ed3a436f1800 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Apr 2021 15:05:04 +0100 Subject: [PATCH 1/5] Refactoring to add ctx to db calls --- exp/services/captivecore/internal/api.go | 10 +- exp/services/captivecore/internal/api_test.go | 27 ++-- exp/services/captivecore/internal/server.go | 6 +- exp/tools/dump-ledger-state/main.go | 2 +- handlers/federation/handler.go | 12 +- handlers/federation/handler_test.go | 3 +- handlers/federation/main.go | 5 +- handlers/federation/reverse_sql_driver.go | 9 +- handlers/federation/sql_driver.go | 12 +- ingest/ledgerbackend/captive_core_backend.go | 13 +- .../captive_core_backend_test.go | 56 ++++--- ingest/ledgerbackend/database_backend.go | 13 +- ingest/ledgerbackend/ledger_backend.go | 6 +- ingest/ledgerbackend/ledger_hash_store.go | 5 +- ingest/ledgerbackend/mock_database_backend.go | 3 +- ingest/ledgerbackend/remote_captive_core.go | 32 +++- ingest/stats_change_processor.go | 3 +- ingest/stats_change_processor_test.go | 32 ++-- services/horizon/cmd/db.go | 6 +- services/horizon/cmd/ingest.go | 7 +- .../horizon/internal/action_offers_test.go | 14 +- services/horizon/internal/actions/account.go | 40 ++--- .../horizon/internal/actions/account_data.go | 2 +- .../horizon/internal/actions/account_test.go | 48 +++--- services/horizon/internal/actions/asset.go | 12 +- .../horizon/internal/actions/asset_test.go | 8 +- .../internal/actions/claimable_balance.go | 8 +- .../actions/claimable_balance_test.go | 14 +- services/horizon/internal/actions/effects.go | 23 +-- services/horizon/internal/actions/ledger.go | 4 +- services/horizon/internal/actions/offer.go | 7 +- .../horizon/internal/actions/offer_test.go | 26 ++-- .../horizon/internal/actions/operation.go | 16 +- .../internal/actions/operation_test.go | 4 +- .../horizon/internal/actions/orderbook.go | 2 +- .../internal/actions/orderbook_test.go | 10 +- services/horizon/internal/actions/path.go | 2 +- services/horizon/internal/actions/trade.go | 25 ++-- .../horizon/internal/actions/transaction.go | 21 +-- .../horizon/internal/actions_account_test.go | 6 +- .../horizon/internal/actions_data_test.go | 10 +- .../horizon/internal/actions_effects_test.go | 4 +- .../actions_operation_fee_stats_test.go | 20 +-- .../internal/actions_operation_test.go | 4 +- .../horizon/internal/actions_path_test.go | 16 +- .../horizon/internal/actions_payment_test.go | 8 +- .../horizon/internal/actions_root_test.go | 6 +- .../horizon/internal/actions_trade_test.go | 2 +- .../internal/actions_transaction_test.go | 6 +- services/horizon/internal/app.go | 42 +++--- .../internal/db2/assets/asset_stat_test.go | 3 +- .../horizon/internal/db2/history/account.go | 17 ++- .../internal/db2/history/account_data.go | 33 ++-- .../account_data_batch_insert_builder.go | 10 +- .../account_data_batch_insert_builder_test.go | 6 +- .../internal/db2/history/account_data_test.go | 40 ++--- .../internal/db2/history/account_signers.go | 22 +-- .../account_signers_batch_insert_builder.go | 12 +- .../db2/history/account_signers_test.go | 34 ++--- .../internal/db2/history/account_test.go | 8 +- .../horizon/internal/db2/history/accounts.go | 36 +++-- .../history/accounts_batch_insert_builder.go | 10 +- .../internal/db2/history/accounts_test.go | 110 +++++++------- .../horizon/internal/db2/history/asset.go | 13 +- .../internal/db2/history/asset_stats.go | 27 ++-- .../internal/db2/history/asset_stats_test.go | 54 +++---- .../internal/db2/history/asset_test.go | 8 +- .../db2/history/claimable_balances.go | 45 +++--- ...able_balances_batch_insert_builder_test.go | 6 +- .../db2/history/claimable_balances_test.go | 44 +++--- .../horizon/internal/db2/history/effect.go | 17 ++- .../history/effect_batch_insert_builder.go | 12 +- .../effect_batch_insert_builder_test.go | 8 +- .../internal/db2/history/fee_bump_scenario.go | 20 ++- .../db2/history/history_claimable_balances.go | 43 +++--- .../horizon/internal/db2/history/ingestion.go | 8 +- .../horizon/internal/db2/history/key_value.go | 41 ++--- .../horizon/internal/db2/history/ledger.go | 22 +-- .../internal/db2/history/ledger_cache.go | 6 +- .../internal/db2/history/ledger_cache_test.go | 2 +- .../internal/db2/history/ledger_test.go | 12 +- services/horizon/internal/db2/history/main.go | 141 +++++++++--------- .../horizon/internal/db2/history/main_test.go | 10 +- .../mock_account_data_batch_insert_builder.go | 9 +- ...ck_account_signers_batch_insert_builder.go | 9 +- .../mock_effect_batch_insert_builder.go | 9 +- .../mock_offers_batch_insert_builder.go | 9 +- ...ration_participant_batch_insert_builder.go | 9 +- .../mock_operations_batch_insert_builder.go | 9 +- .../internal/db2/history/mock_q_accounts.go | 13 +- .../db2/history/mock_q_asset_stats.go | 33 ++-- .../db2/history/mock_q_claimable_balances.go | 29 ++-- .../internal/db2/history/mock_q_data.go | 22 +-- .../internal/db2/history/mock_q_effects.go | 5 +- .../mock_q_history_claimable_balances.go | 21 +-- .../internal/db2/history/mock_q_ledgers.go | 9 +- .../internal/db2/history/mock_q_offers.go | 29 ++-- .../db2/history/mock_q_participants.go | 13 +- .../internal/db2/history/mock_q_signers.go | 37 ++--- .../internal/db2/history/mock_q_trades.go | 19 ++- .../db2/history/mock_q_trust_lines.go | 22 +-- .../mock_transactions_batch_insert_builder.go | 10 +- .../horizon/internal/db2/history/offers.go | 55 +++---- .../history/offers_batch_insert_builder.go | 12 +- .../internal/db2/history/offers_test.go | 110 +++++++------- .../horizon/internal/db2/history/operation.go | 33 ++-- .../history/operation_batch_insert_builder.go | 12 +- .../operation_batch_insert_builder_test.go | 10 +- ...ration_participant_batch_insert_builder.go | 12 +- ...n_participant_batch_insert_builder_test.go | 6 +- .../internal/db2/history/operation_test.go | 82 +++++----- .../horizon/internal/db2/history/orderbook.go | 9 +- .../internal/db2/history/orderbook_test.go | 46 +++--- .../internal/db2/history/participants.go | 14 +- .../internal/db2/history/participants_test.go | 8 +- .../internal/db2/history/sequence_provider.go | 6 +- .../db2/history/sequence_provider_test.go | 10 +- .../horizon/internal/db2/history/trade.go | 23 +-- .../db2/history/trade_batch_insert_builder.go | 13 +- .../internal/db2/history/trade_test.go | 40 ++--- .../internal/db2/history/transaction.go | 27 ++-- .../transaction_batch_insert_builder.go | 13 +- .../internal/db2/history/transaction_test.go | 54 +++---- .../internal/db2/history/trust_lines.go | 39 ++--- .../trust_lines_batch_insert_builder.go | 10 +- .../internal/db2/history/trust_lines_test.go | 68 ++++----- services/horizon/internal/health.go | 2 +- services/horizon/internal/health_test.go | 7 +- services/horizon/internal/httpt_test.go | 7 +- services/horizon/internal/httpx/handler.go | 4 +- services/horizon/internal/httpx/middleware.go | 21 ++- .../internal/httpx/stream_handler_test.go | 17 ++- .../internal/ingest/build_state_test.go | 94 ++++++------ .../internal/ingest/db_integration_test.go | 7 +- services/horizon/internal/ingest/fsm.go | 109 +++++++------- .../internal/ingest/group_processors.go | 17 ++- .../internal/ingest/group_processors_test.go | 61 ++++---- .../ingest/ingest_history_range_state_test.go | 122 +++++++-------- .../internal/ingest/init_state_test.go | 108 +++++++------- services/horizon/internal/ingest/main.go | 12 +- services/horizon/internal/ingest/main_test.go | 94 ++++++------ services/horizon/internal/ingest/orderbook.go | 34 ++--- .../horizon/internal/ingest/orderbook_test.go | 121 ++++++++------- .../internal/ingest/processor_runner.go | 22 +-- .../internal/ingest/processor_runner_test.go | 67 +++++---- .../processors/account_data_processor.go | 16 +- .../accounts_data_processor_test.go | 30 ++-- .../ingest/processors/accounts_processor.go | 12 +- .../processors/accounts_processor_test.go | 31 ++-- .../processors/asset_stats_processor.go | 21 +-- .../processors/asset_stats_processor_test.go | 129 ++++++++-------- .../ingest/processors/change_processors.go | 11 +- .../processors/change_processors_test.go | 9 +- .../claimable_balances_change_processor.go | 16 +- ...laimable_balances_change_processor_test.go | 28 ++-- ...laimable_balances_transaction_processor.go | 28 ++-- ...ble_balances_transaction_processor_test.go | 21 +-- .../ingest/processors/effects_processor.go | 19 +-- .../processors/effects_processor_test.go | 32 ++-- .../ingest/processors/ledgers_processor.go | 8 +- .../processors/ledgers_processor_test.go | 15 +- .../processors/mock_change_processor.go | 6 +- .../ingest/processors/offers_processor.go | 22 +-- .../processors/offers_processor_test.go | 84 ++++++----- .../ingest/processors/operations_processor.go | 9 +- .../processors/operations_processor_test.go | 18 ++- .../processors/participants_processor.go | 27 ++-- .../processors/participants_processor_test.go | 111 +++++++------- .../processors/signer_processor_test.go | 77 ++++++---- .../ingest/processors/signers_processor.go | 16 +- .../stats_ledger_transaction_processor.go | 3 +- ...stats_ledger_transaction_processor_test.go | 5 +- .../ingest/processors/trades_processor.go | 13 +- .../processors/trades_processor_test.go | 94 ++++++------ .../processors/transactions_processor.go | 9 +- .../processors/transactions_processor_test.go | 31 ++-- .../processors/trust_lines_processor.go | 12 +- .../processors/trust_lines_processor_test.go | 68 +++++---- .../internal/ingest/resume_state_test.go | 90 +++++------ .../horizon/internal/ingest/stress_test.go | 42 +++--- services/horizon/internal/ingest/verify.go | 51 ++++--- .../ingest/verify_range_state_test.go | 86 +++++------ services/horizon/internal/init.go | 4 +- services/horizon/internal/middleware_test.go | 9 +- services/horizon/internal/reap/system.go | 17 ++- services/horizon/internal/reap/system_test.go | 14 +- services/horizon/internal/test/t.go | 10 +- services/horizon/internal/test/trades/main.go | 11 +- .../horizon/internal/txsub/helpers_test.go | 16 +- services/horizon/internal/txsub/results.go | 15 +- .../horizon/internal/txsub/results_test.go | 6 +- services/horizon/internal/txsub/system.go | 22 +-- .../horizon/internal/txsub/system_test.go | 94 ++++++------ services/ticker/cmd/clean.go | 3 +- services/ticker/cmd/generate.go | 3 +- services/ticker/cmd/ingest.go | 7 +- services/ticker/internal/actions_asset.go | 11 +- services/ticker/internal/actions_market.go | 4 +- services/ticker/internal/actions_orderbook.go | 8 +- services/ticker/internal/actions_trade.go | 15 +- .../ticker/internal/gql/resolvers_asset.go | 5 +- .../ticker/internal/gql/resolvers_issuer.go | 5 +- .../ticker/internal/gql/resolvers_market.go | 9 +- services/ticker/internal/tickerdb/helpers.go | 5 +- services/ticker/internal/tickerdb/main.go | 2 - .../ticker/internal/tickerdb/queries_asset.go | 20 ++- .../internal/tickerdb/queries_issuer.go | 9 +- .../internal/tickerdb/queries_market.go | 17 ++- .../internal/tickerdb/queries_orderbook.go | 8 +- .../ticker/internal/tickerdb/queries_trade.go | 19 +-- .../tickerdb_test/queries_asset_test.go | 32 ++-- .../tickerdb_test/queries_issuer_test.go | 14 +- .../tickerdb_test/queries_market_test.go | 81 +++++----- .../tickerdb_test/queries_orderbook_test.go | 22 +-- .../tickerdb_test/queries_trade_test.go | 62 ++++---- .../tickerdb/tickerdbtest/tickerdbtest.go | 46 +++--- support/db/batch_insert_builder.go | 15 +- support/db/batch_insert_builder_test.go | 37 ++--- support/db/delete_builder.go | 5 +- support/db/delete_builder_test.go | 7 +- support/db/get_builder.go | 5 +- support/db/get_builder_test.go | 4 +- support/db/insert_builder.go | 5 +- support/db/insert_builder_test.go | 13 +- support/db/main.go | 37 ++--- support/db/main_test.go | 3 +- support/db/mock_session.go | 45 +++--- support/db/schema/main.go | 5 +- support/db/select_builder.go | 5 +- support/db/select_builder_test.go | 4 +- support/db/session.go | 107 ++++++------- support/db/session_test.go | 33 ++-- support/db/update_builder.go | 5 +- 233 files changed, 3065 insertions(+), 2701 deletions(-) diff --git a/exp/services/captivecore/internal/api.go b/exp/services/captivecore/internal/api.go index 9e666e565c..4cebd5ff83 100644 --- a/exp/services/captivecore/internal/api.go +++ b/exp/services/captivecore/internal/api.go @@ -63,7 +63,7 @@ func (c *CaptiveCoreAPI) Shutdown() { c.core.Close() } -func (c *CaptiveCoreAPI) startPrepareRange(ledgerRange ledgerbackend.Range) { +func (c *CaptiveCoreAPI) startPrepareRange(ctx context.Context, ledgerRange ledgerbackend.Range) { defer c.wg.Done() err := c.core.PrepareRange(ledgerRange) @@ -100,7 +100,7 @@ func (c *CaptiveCoreAPI) startPrepareRange(ledgerRange ledgerbackend.Range) { } // PrepareRange executes the PrepareRange operation on the captive core instance. -func (c *CaptiveCoreAPI) PrepareRange(ledgerRange ledgerbackend.Range) (ledgerbackend.PrepareRangeResponse, error) { +func (c *CaptiveCoreAPI) PrepareRange(ctx context.Context, ledgerRange ledgerbackend.Range) (ledgerbackend.PrepareRangeResponse, error) { c.activeRequest.Lock() defer c.activeRequest.Unlock() if c.ctx.Err() != nil { @@ -121,7 +121,7 @@ func (c *CaptiveCoreAPI) PrepareRange(ledgerRange ledgerbackend.Range) (ledgerba c.activeRequest.valid = true c.wg.Add(1) - go c.startPrepareRange(ledgerRange) + go c.startPrepareRange(ctx, ledgerRange) return ledgerbackend.PrepareRangeResponse{ LedgerRange: ledgerRange, @@ -140,7 +140,7 @@ func (c *CaptiveCoreAPI) PrepareRange(ledgerRange ledgerbackend.Range) (ledgerba } // GetLatestLedgerSequence determines the latest ledger sequence available on the captive core instance. -func (c *CaptiveCoreAPI) GetLatestLedgerSequence() (ledgerbackend.LatestLedgerSequenceResponse, error) { +func (c *CaptiveCoreAPI) GetLatestLedgerSequence(ctx context.Context) (ledgerbackend.LatestLedgerSequenceResponse, error) { c.activeRequest.Lock() defer c.activeRequest.Unlock() @@ -159,7 +159,7 @@ func (c *CaptiveCoreAPI) GetLatestLedgerSequence() (ledgerbackend.LatestLedgerSe } // GetLedger fetches the ledger with the given sequence number from the captive core instance. -func (c *CaptiveCoreAPI) GetLedger(sequence uint32) (ledgerbackend.LedgerResponse, error) { +func (c *CaptiveCoreAPI) GetLedger(ctx context.Context, sequence uint32) (ledgerbackend.LedgerResponse, error) { c.activeRequest.Lock() defer c.activeRequest.Unlock() diff --git a/exp/services/captivecore/internal/api_test.go b/exp/services/captivecore/internal/api_test.go index 223f5e9bb4..2d6e93ec2d 100644 --- a/exp/services/captivecore/internal/api_test.go +++ b/exp/services/captivecore/internal/api_test.go @@ -1,6 +1,7 @@ package internal import ( + "context" "fmt" "testing" "time" @@ -18,11 +19,13 @@ func TestAPITestSuite(t *testing.T) { type APITestSuite struct { suite.Suite + ctx context.Context ledgerBackend *ledgerbackend.MockDatabaseBackend api CaptiveCoreAPI } func (s *APITestSuite) SetupTest() { + s.ctx = context.Background() s.ledgerBackend = &ledgerbackend.MockDatabaseBackend{} s.api = NewCaptiveCoreAPI(s.ledgerBackend, log.New()) } @@ -32,12 +35,12 @@ func (s *APITestSuite) TearDownTest() { } func (s *APITestSuite) TestLatestSeqActiveRequestInvalid() { - _, err := s.api.GetLatestLedgerSequence() + _, err := s.api.GetLatestLedgerSequence(s.ctx) s.Assert().Equal(err, ErrMissingPrepareRange) } func (s *APITestSuite) TestGetLedgerActiveRequestInvalid() { - _, err := s.api.GetLedger(64) + _, err := s.api.GetLedger(s.ctx, 64) s.Assert().Equal(err, ErrMissingPrepareRange) } @@ -48,7 +51,7 @@ func (s *APITestSuite) runBeforeReady(prepareRangeErr error, f func()) { WaitUntil(waitChan). Return(prepareRangeErr).Once() - response, err := s.api.PrepareRange(ledgerRange) + response, err := s.api.PrepareRange(s.ctx, ledgerRange) s.Assert().NoError(err) s.Assert().False(response.Ready) s.Assert().Equal(response.LedgerRange, ledgerRange) @@ -61,14 +64,14 @@ func (s *APITestSuite) runBeforeReady(prepareRangeErr error, f func()) { func (s *APITestSuite) TestLatestSeqActiveRequestNotReady() { s.runBeforeReady(nil, func() { - _, err := s.api.GetLatestLedgerSequence() + _, err := s.api.GetLatestLedgerSequence(s.ctx) s.Assert().Equal(err, ErrPrepareRangeNotReady) }) } func (s *APITestSuite) TestGetLedgerNotReady() { s.runBeforeReady(nil, func() { - _, err := s.api.GetLedger(64) + _, err := s.api.GetLedger(s.ctx, 64) s.Assert().Equal(err, ErrPrepareRangeNotReady) }) } @@ -77,7 +80,7 @@ func (s *APITestSuite) waitUntilReady(ledgerRange ledgerbackend.Range) { s.ledgerBackend.On("PrepareRange", ledgerRange). Return(nil).Once() - response, err := s.api.PrepareRange(ledgerRange) + response, err := s.api.PrepareRange(s.ctx, ledgerRange) s.Assert().NoError(err) s.Assert().False(response.Ready) s.Assert().Equal(response.LedgerRange, ledgerRange) @@ -91,7 +94,7 @@ func (s *APITestSuite) TestLatestSeqError() { expectedErr := fmt.Errorf("test error") s.ledgerBackend.On("GetLatestLedgerSequence").Return(uint32(0), expectedErr).Once() - _, err := s.api.GetLatestLedgerSequence() + _, err := s.api.GetLatestLedgerSequence(s.ctx) s.Assert().Equal(err, expectedErr) } @@ -102,7 +105,7 @@ func (s *APITestSuite) TestGetLedgerError() { s.ledgerBackend.On("GetLedger", uint32(64)). Return(false, xdr.LedgerCloseMeta{}, expectedErr).Once() - _, err := s.api.GetLedger(64) + _, err := s.api.GetLedger(s.ctx, 64) s.Assert().Equal(err, expectedErr) } @@ -111,7 +114,7 @@ func (s *APITestSuite) TestLatestSeqSucceeds() { expectedSeq := uint32(100) s.ledgerBackend.On("GetLatestLedgerSequence").Return(expectedSeq, nil).Once() - seq, err := s.api.GetLatestLedgerSequence() + seq, err := s.api.GetLatestLedgerSequence(s.ctx) s.Assert().NoError(err) s.Assert().Equal(seq, ledgerbackend.LatestLedgerSequenceResponse{Sequence: expectedSeq}) } @@ -130,7 +133,7 @@ func (s *APITestSuite) TestGetLedgerSucceeds() { } s.ledgerBackend.On("GetLedger", uint32(64)). Return(true, expectedLedger, nil).Once() - seq, err := s.api.GetLedger(64) + seq, err := s.api.GetLedger(s.ctx, 64) s.Assert().NoError(err) s.Assert().Equal(seq, ledgerbackend.LedgerResponse{ @@ -142,7 +145,7 @@ func (s *APITestSuite) TestGetLedgerSucceeds() { func (s *APITestSuite) TestShutDownBeforePrepareRange() { s.ledgerBackend.On("Close").Return(nil).Once() s.api.Shutdown() - _, err := s.api.PrepareRange(ledgerbackend.UnboundedRange(63)) + _, err := s.api.PrepareRange(s.ctx, ledgerbackend.UnboundedRange(63)) s.Assert().EqualError(err, "Cannot prepare range when shut down") } @@ -226,7 +229,7 @@ func (s *APITestSuite) TestRangeAlreadyPrepared() { ledgerbackend.UnboundedRange(100), ledgerbackend.BoundedRange(63, 70), } { - response, err := s.api.PrepareRange(ledgerRange) + response, err := s.api.PrepareRange(s.ctx, ledgerRange) s.Assert().NoError(err) s.Assert().True(response.Ready) s.Assert().Equal(superSetRange, response.LedgerRange) diff --git a/exp/services/captivecore/internal/server.go b/exp/services/captivecore/internal/server.go index b451a35c93..6c0ae43124 100644 --- a/exp/services/captivecore/internal/server.go +++ b/exp/services/captivecore/internal/server.go @@ -39,7 +39,7 @@ func Handler(api CaptiveCoreAPI) http.Handler { mux := supporthttp.NewMux(api.log) mux.Get("/latest-sequence", func(w http.ResponseWriter, r *http.Request) { - response, err := api.GetLatestLedgerSequence() + response, err := api.GetLatestLedgerSequence(r.Context()) serializeResponse(api.log, w, r, response, err) }) @@ -51,7 +51,7 @@ func Handler(api CaptiveCoreAPI) http.Handler { return } - response, err := api.GetLedger(req.Sequence) + response, err := api.GetLedger(r.Context(), req.Sequence) serializeResponse(api.log, w, r, response, err) }) @@ -63,7 +63,7 @@ func Handler(api CaptiveCoreAPI) http.Handler { return } - response, err := api.PrepareRange(ledgerRange) + response, err := api.PrepareRange(r.Context(), ledgerRange) serializeResponse(api.log, w, r, response, err) }) diff --git a/exp/tools/dump-ledger-state/main.go b/exp/tools/dump-ledger-state/main.go index 2fe9f35923..d3292ac1e1 100644 --- a/exp/tools/dump-ledger-state/main.go +++ b/exp/tools/dump-ledger-state/main.go @@ -78,7 +78,7 @@ func (processor csvProcessor) ProcessChange(change ingest.Change) error { if !ok { return nil } - if err := processor.changeStats.ProcessChange(change); err != nil { + if err := processor.changeStats.ProcessChange(context.Background(), change); err != nil { return err } diff --git a/handlers/federation/handler.go b/handlers/federation/handler.go index 97d1822d05..3a7bcfd11e 100644 --- a/handlers/federation/handler.go +++ b/handlers/federation/handler.go @@ -26,9 +26,9 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch typ { case "name": - h.lookupByName(w, q) + h.lookupByName(w, r, q) case "id": - h.lookupByID(w, q) + h.lookupByID(w, r, q) case "forward": h.lookupByForward(w, r.URL.Query()) case "txid": @@ -55,7 +55,7 @@ func (h *Handler) failNotImplemented(w http.ResponseWriter, msg string) { }, http.StatusNotImplemented) } -func (h *Handler) lookupByID(w http.ResponseWriter, q string) { +func (h *Handler) lookupByID(w http.ResponseWriter, r *http.Request, q string) { rd, ok := h.Driver.(ReverseDriver) if !ok { @@ -65,7 +65,7 @@ func (h *Handler) lookupByID(w http.ResponseWriter, q string) { // TODO: validate that `q` is a strkey encoded address - rec, err := rd.LookupReverseRecord(q) + rec, err := rd.LookupReverseRecord(r.Context(), q) if err != nil { h.writeError(w, errors.Wrap(err, "lookup record")) return @@ -81,7 +81,7 @@ func (h *Handler) lookupByID(w http.ResponseWriter, q string) { }, http.StatusOK) } -func (h *Handler) lookupByName(w http.ResponseWriter, q string) { +func (h *Handler) lookupByName(w http.ResponseWriter, r *http.Request, q string) { name, domain, err := address.Split(q) if err != nil { h.writeJSON(w, ErrorResponse{ @@ -91,7 +91,7 @@ func (h *Handler) lookupByName(w http.ResponseWriter, q string) { return } - rec, err := h.Driver.LookupRecord(name, domain) + rec, err := h.Driver.LookupRecord(r.Context(), name, domain) if err != nil { h.writeError(w, errors.Wrap(err, "lookupByName")) return diff --git a/handlers/federation/handler_test.go b/handlers/federation/handler_test.go index 114e4ec605..377831f75b 100644 --- a/handlers/federation/handler_test.go +++ b/handlers/federation/handler_test.go @@ -1,6 +1,7 @@ package federation import ( + "context" "net/http" "net/url" "testing" @@ -200,7 +201,7 @@ func (fd ForwardTestDriver) LookupForwardingRecord(query url.Values) (*Record, e } } -func (fd ForwardTestDriver) LookupRecord(name string, domain string) (*Record, error) { +func (fd ForwardTestDriver) LookupRecord(ctx context.Context, name string, domain string) (*Record, error) { return nil, nil } diff --git a/handlers/federation/main.go b/handlers/federation/main.go index ea120e65d6..00c192713a 100644 --- a/handlers/federation/main.go +++ b/handlers/federation/main.go @@ -11,6 +11,7 @@ package federation import ( + "context" "database/sql" "net/url" "sync" @@ -25,7 +26,7 @@ type Driver interface { // federation request to lookup a `Record` using the provided stellar address. // An implementation should return a nil `*Record` value if the lookup // successfully executed but no result was found. - LookupRecord(name string, domain string) (*Record, error) + LookupRecord(ctx context.Context, name, domain string) (*Record, error) } // ErrorResponse represents the JSON response sent to a client when the request @@ -65,7 +66,7 @@ type ReverseDriver interface { // federation request to lookup a `ReverseRecord` using the provided strkey // encoded accountID. An implementation should return a nil `*ReverseRecord` // value if the lookup successfully executed but no result was found. - LookupReverseRecord(accountID string) (*ReverseRecord, error) + LookupReverseRecord(ctx context.Context, accountID string) (*ReverseRecord, error) } // ForwardDriver represents a data source against which forward queries can diff --git a/handlers/federation/reverse_sql_driver.go b/handlers/federation/reverse_sql_driver.go index 6fdf09f4a4..62059d513f 100644 --- a/handlers/federation/reverse_sql_driver.go +++ b/handlers/federation/reverse_sql_driver.go @@ -1,16 +1,21 @@ package federation -import "github.com/stellar/go/support/errors" +import ( + "context" + + "github.com/stellar/go/support/errors" +) // LookupReverseRecord implements `ReverseDriver` by performing // `drv.LookupReverseRecordQuery` against `drv.DB` using the provided parameter func (drv *ReverseSQLDriver) LookupReverseRecord( + ctx context.Context, accountid string, ) (*ReverseRecord, error) { drv.initDB() var result ReverseRecord - err := drv.db.GetRaw(&result, drv.LookupReverseRecordQuery, accountid) + err := drv.db.GetRaw(ctx, &result, drv.LookupReverseRecordQuery, accountid) if drv.db.NoRows(err) { return nil, nil diff --git a/handlers/federation/sql_driver.go b/handlers/federation/sql_driver.go index 2ecd1ee22a..bab79bc62b 100644 --- a/handlers/federation/sql_driver.go +++ b/handlers/federation/sql_driver.go @@ -1,15 +1,19 @@ package federation -import "github.com/stellar/go/support/db" -import "github.com/stellar/go/support/errors" +import ( + "context" + + "github.com/stellar/go/support/db" + "github.com/stellar/go/support/errors" +) // LookupRecord implements `Driver` by performing `drv.LookupRecordQuery` // against `drv.DB` using the provided parameters -func (drv *SQLDriver) LookupRecord(name, domain string) (*Record, error) { +func (drv *SQLDriver) LookupRecord(ctx context.Context, name, domain string) (*Record, error) { drv.initDB() var result Record - err := drv.db.GetRaw(&result, drv.LookupRecordQuery, name, domain) + err := drv.db.GetRaw(ctx, &result, drv.LookupRecordQuery, name, domain) if drv.db.NoRows(err) { return nil, nil diff --git a/ingest/ledgerbackend/captive_core_backend.go b/ingest/ledgerbackend/captive_core_backend.go index 3730e01d1d..86fc26d259 100644 --- a/ingest/ledgerbackend/captive_core_backend.go +++ b/ingest/ledgerbackend/captive_core_backend.go @@ -241,7 +241,7 @@ func (c *CaptiveStellarCore) openOfflineReplaySubprocess(from, to uint32) error return nil } -func (c *CaptiveStellarCore) openOnlineReplaySubprocess(from uint32) error { +func (c *CaptiveStellarCore) openOnlineReplaySubprocess(ctx context.Context, from uint32) error { latestCheckpointSequence, err := c.getLatestCheckpointSequence() if err != nil { return errors.Wrap(err, "error getting latest checkpoint sequence") @@ -269,7 +269,7 @@ func (c *CaptiveStellarCore) openOnlineReplaySubprocess(from uint32) error { c.stellarCoreRunner = runner } - runFrom, ledgerHash, nextLedger, err := c.runFromParams(from) + runFrom, ledgerHash, nextLedger, err := c.runFromParams(ctx, from) if err != nil { return errors.Wrap(err, "error calculating ledger and hash for stelar-core run") } @@ -300,7 +300,7 @@ func (c *CaptiveStellarCore) openOnlineReplaySubprocess(from uint32) error { } // runFromParams receives a ledger sequence and calculates the required values to call stellar-core run with --start-ledger and --start-hash -func (c *CaptiveStellarCore) runFromParams(from uint32) (runFrom uint32, ledgerHash string, nextLedger uint32, err error) { +func (c *CaptiveStellarCore) runFromParams(ctx context.Context, from uint32) (runFrom uint32, ledgerHash string, nextLedger uint32, err error) { if from == 1 { // Trying to start-from 1 results in an error from Stellar-Core: // Target ledger 1 is not newer than last closed ledger 1 - nothing to do @@ -357,7 +357,7 @@ func (c *CaptiveStellarCore) runFromParams(from uint32) (runFrom uint32, ledgerH return } -func (c *CaptiveStellarCore) startPreparingRange(ledgerRange Range) (bool, error) { +func (c *CaptiveStellarCore) startPreparingRange(ctx context.Context, ledgerRange Range) (bool, error) { c.stellarCoreLock.Lock() defer c.stellarCoreLock.Unlock() @@ -375,7 +375,7 @@ func (c *CaptiveStellarCore) startPreparingRange(ledgerRange Range) (bool, error if ledgerRange.bounded { err = c.openOfflineReplaySubprocess(ledgerRange.from, ledgerRange.to) } else { - err = c.openOnlineReplaySubprocess(ledgerRange.from) + err = c.openOnlineReplaySubprocess(ctx, ledgerRange.from) } if err != nil { return false, errors.Wrap(err, "opening subprocess") @@ -394,7 +394,8 @@ func (c *CaptiveStellarCore) startPreparingRange(ledgerRange Range) (bool, error // Please note that using a BoundedRange, currently, requires a full-trust on // history archive. This issue is being fixed in Stellar-Core. func (c *CaptiveStellarCore) PrepareRange(ledgerRange Range) error { - if alreadyPrepared, err := c.startPreparingRange(ledgerRange); err != nil { + ctx := context.TODO() + if alreadyPrepared, err := c.startPreparingRange(ctx, ledgerRange); err != nil { return errors.Wrap(err, "error starting prepare range") } else if alreadyPrepared { return nil diff --git a/ingest/ledgerbackend/captive_core_backend_test.go b/ingest/ledgerbackend/captive_core_backend_test.go index 6fbf873ec9..af4bcdc14b 100644 --- a/ingest/ledgerbackend/captive_core_backend_test.go +++ b/ingest/ledgerbackend/captive_core_backend_test.go @@ -162,10 +162,11 @@ func TestCaptivePrepareRange(t *testing.T) { } } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(100), uint32(200)).Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockArchive := &historyarchive.MockArchive{} mockArchive. @@ -199,12 +200,13 @@ func TestCaptivePrepareRange(t *testing.T) { func TestCaptivePrepareRangeCrash(t *testing.T) { metaChan := make(chan metaResult) close(metaChan) + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(100), uint32(200)).Return(nil).Once() mockRunner.On("getProcessExitError").Return(true, errors.New("exit code -1")) mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) mockRunner.On("close").Return(nil).Once() - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockArchive := &historyarchive.MockArchive{} mockArchive. @@ -239,10 +241,11 @@ func TestCaptivePrepareRangeTerminated(t *testing.T) { } } close(metaChan) + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(100), uint32(200)).Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockArchive := &historyarchive.MockArchive{} mockArchive. @@ -266,9 +269,10 @@ func TestCaptivePrepareRangeTerminated(t *testing.T) { } func TestCaptivePrepareRange_ErrClosingSession(t *testing.T) { + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("close").Return(fmt.Errorf("transient error")) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) captiveBackend := CaptiveStellarCore{ nextLedger: 300, @@ -336,10 +340,11 @@ func TestCaptivePrepareRange_ToIsAheadOfRootHAS(t *testing.T) { } } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(100), uint32(192)).Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockArchive := &historyarchive.MockArchive{} mockArchive. @@ -448,10 +453,11 @@ func TestCaptivePrepareRangeUnboundedRange_ReuseSession(t *testing.T) { } } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("runFrom", uint32(62), "0000000000000000000000000000000000000000000000000000000000000000").Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockArchive := &historyarchive.MockArchive{} mockArchive. @@ -494,10 +500,11 @@ func TestGetLatestLedgerSequence(t *testing.T) { } } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("runFrom", uint32(62), "0000000000000000000000000000000000000000000000000000000000000000").Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockArchive := &historyarchive.MockArchive{} mockArchive. @@ -540,7 +547,8 @@ func TestCaptiveGetLedger(t *testing.T) { } } - ctx, cancel := context.WithCancel(context.Background()) + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(65), uint32(66)).Return(nil) mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) @@ -685,10 +693,11 @@ func TestCaptiveGetLedger_NextLedgerIsDifferentToLedgerFromBuffer(t *testing.T) } } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(65), uint32(66)).Return(nil) mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockRunner.On("close").Return(nil) mockArchive := &historyarchive.MockArchive{} @@ -769,10 +778,11 @@ func TestCaptiveGetLedger_ErrReadingMetaResult(t *testing.T) { err: fmt.Errorf("unmarshalling error"), } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(65), uint32(66)).Return(nil) mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(ctx) mockRunner.On("context").Return(ctx) mockRunner.On("getProcessExitError").Return(false, nil) mockRunner.On("close").Return(nil).Run(func(args mock.Arguments) { @@ -825,10 +835,11 @@ func TestCaptiveGetLedger_ErrClosingAfterLastLedger(t *testing.T) { } } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(65), uint32(66)).Return(nil) mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockRunner.On("close").Return(fmt.Errorf("transient error")).Once() mockArchive := &historyarchive.MockArchive{} @@ -920,10 +931,11 @@ func TestGetLedgerBoundsCheck(t *testing.T) { } } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(128), uint32(130)).Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockArchive := &historyarchive.MockArchive{} mockArchive. @@ -1021,10 +1033,11 @@ func TestCaptiveGetLedgerTerminatedUnexpectedly(t *testing.T) { } close(metaChan) + ctx := testCase.ctx mockRunner := &stellarCoreRunnerMock{} mockRunner.On("catchup", uint32(64), uint32(100)).Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockRunner.On("getProcessExitError").Return(testCase.processExited, testCase.processExitedError) mockRunner.On("close").Return(nil).Once() @@ -1070,6 +1083,7 @@ func TestCaptiveUseOfLedgerHashStore(t *testing.T) { }, }, nil) + ctx := context.Background() mockLedgerHashStore := &MockLedgerHashStore{} mockLedgerHashStore.On("GetLedgerHash", uint32(1022)). Return("", false, fmt.Errorf("transient error")).Once() @@ -1088,28 +1102,28 @@ func TestCaptiveUseOfLedgerHashStore(t *testing.T) { checkpointManager: historyarchive.NewCheckpointManager(64), } - runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(24) + runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(ctx, 24) assert.NoError(t, err) assert.Equal(t, uint32(2), runFrom) assert.Equal(t, "mnb", ledgerHash) assert.Equal(t, uint32(2), nextLedger) - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(86) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 86) assert.NoError(t, err) assert.Equal(t, uint32(62), runFrom) assert.Equal(t, "cde", ledgerHash) assert.Equal(t, uint32(2), nextLedger) - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(128) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 128) assert.NoError(t, err) assert.Equal(t, uint32(126), runFrom) assert.Equal(t, "ghi", ledgerHash) assert.Equal(t, uint32(64), nextLedger) - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(1050) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 1050) assert.EqualError(t, err, "error trying to read ledger hash 1022: transient error") - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(300) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 300) assert.NoError(t, err) assert.Equal(t, uint32(254), runFrom, "runFrom") assert.Equal(t, "0101010100000000000000000000000000000000000000000000000000000000", ledgerHash) @@ -1149,6 +1163,7 @@ func TestCaptiveRunFromParams(t *testing.T) { for _, tc := range tests { t.Run(fmt.Sprintf("from_%d", tc.from), func(t *testing.T) { tt := assert.New(t) + ctx := context.Background() mockArchive := &historyarchive.MockArchive{} mockArchive. On("GetLedgerHeader", uint32(tc.ledgerArchives)). @@ -1163,7 +1178,7 @@ func TestCaptiveRunFromParams(t *testing.T) { checkpointManager: historyarchive.NewCheckpointManager(64), } - runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(tc.from) + runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(ctx, tc.from) tt.NoError(err) tt.Equal(tc.runFrom, runFrom, "runFrom") tt.Equal("0101010100000000000000000000000000000000000000000000000000000000", ledgerHash) @@ -1249,10 +1264,11 @@ func TestCaptivePreviousLedgerCheck(t *testing.T) { } + ctx := context.Background() mockRunner := &stellarCoreRunnerMock{} mockRunner.On("runFrom", uint32(254), "0101010100000000000000000000000000000000000000000000000000000000").Return(nil).Once() mockRunner.On("getMetaPipe").Return((<-chan metaResult)(metaChan)) - mockRunner.On("context").Return(context.Background()) + mockRunner.On("context").Return(ctx) mockRunner.On("close").Return(nil).Once() mockArchive := &historyarchive.MockArchive{} diff --git a/ingest/ledgerbackend/database_backend.go b/ingest/ledgerbackend/database_backend.go index 25bbfc8a6b..f1a9166b18 100644 --- a/ingest/ledgerbackend/database_backend.go +++ b/ingest/ledgerbackend/database_backend.go @@ -1,6 +1,7 @@ package ledgerbackend import ( + "context" "database/sql" "sort" "time" @@ -74,8 +75,9 @@ func (*DatabaseBackend) IsPrepared(ledgerRange Range) (bool, error) { // GetLatestLedgerSequence returns the most recent ledger sequence number present in the database. func (dbb *DatabaseBackend) GetLatestLedgerSequence() (uint32, error) { + ctx := context.TODO() var ledger []ledgerHeader - err := dbb.session.SelectRaw(&ledger, latestLedgerSeqQuery) + err := dbb.session.SelectRaw(ctx, &ledger, latestLedgerSeqQuery) if err != nil { return 0, errors.Wrap(err, "couldn't select ledger sequence") } @@ -140,6 +142,7 @@ func (dbb *DatabaseBackend) GetLedgerBlocking(sequence uint32) (xdr.LedgerCloseM // GetLedger returns the LedgerCloseMeta for the given ledger sequence number. // The first returned value is false when the ledger does not exist in the database. func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMeta, error) { + ctx := context.TODO() lcm := xdr.LedgerCloseMeta{ V0: &xdr.LedgerCloseMetaV0{}, } @@ -147,7 +150,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - ledgerheader var lRow ledgerHeaderHistory - err := dbb.session.GetRaw(&lRow, ledgerHeaderQuery, sequence) + err := dbb.session.GetRaw(ctx, &lRow, ledgerHeaderQuery, sequence) // Return errors... if err != nil { switch err { @@ -168,7 +171,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - txhistory var txhRows []txHistory - err = dbb.session.SelectRaw(&txhRows, txHistoryQuery+orderBy, sequence) + err = dbb.session.SelectRaw(ctx, &txhRows, txHistoryQuery+orderBy, sequence) // Return errors... if err != nil { return false, lcm, errors.Wrap(err, "Error getting txHistory") @@ -194,7 +197,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - txfeehistory var txfhRows []txFeeHistory - err = dbb.session.SelectRaw(&txfhRows, txFeeHistoryQuery+orderBy, sequence) + err = dbb.session.SelectRaw(ctx, &txfhRows, txFeeHistoryQuery+orderBy, sequence) // Return errors... if err != nil { return false, lcm, errors.Wrap(err, "Error getting txFeeHistory") @@ -211,7 +214,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - upgradehistory var upgradeHistoryRows []upgradeHistory - err = dbb.session.SelectRaw(&upgradeHistoryRows, upgradeHistoryQuery, sequence) + err = dbb.session.SelectRaw(ctx, &upgradeHistoryRows, upgradeHistoryQuery, sequence) // Return errors... if err != nil { return false, lcm, errors.Wrap(err, "Error getting upgradeHistoryRows") diff --git a/ingest/ledgerbackend/ledger_backend.go b/ingest/ledgerbackend/ledger_backend.go index 7a7c1eda81..2e2a7db1de 100644 --- a/ingest/ledgerbackend/ledger_backend.go +++ b/ingest/ledgerbackend/ledger_backend.go @@ -1,6 +1,8 @@ package ledgerbackend import ( + "context" + "github.com/stellar/go/xdr" ) @@ -25,8 +27,8 @@ type LedgerBackend interface { // session is the interface needed to access a persistent database session. // TODO can't use this until we add Close() to the existing db.Session object type session interface { - GetRaw(dest interface{}, query string, args ...interface{}) error - SelectRaw(dest interface{}, query string, args ...interface{}) error + GetRaw(ctx context.Context, dest interface{}, query string, args ...interface{}) error + SelectRaw(ctx context.Context, dest interface{}, query string, args ...interface{}) error Close() error } diff --git a/ingest/ledgerbackend/ledger_hash_store.go b/ingest/ledgerbackend/ledger_hash_store.go index 00fa4e224b..e1709e5f74 100644 --- a/ingest/ledgerbackend/ledger_hash_store.go +++ b/ingest/ledgerbackend/ledger_hash_store.go @@ -1,6 +1,8 @@ package ledgerbackend import ( + "context" + sq "github.com/Masterminds/squirrel" "github.com/stretchr/testify/mock" @@ -27,11 +29,12 @@ func NewHorizonDBLedgerHashStore(session *db.Session) TrustedLedgerHashStore { // GetLedgerHash returns the ledger hash for the given sequence number func (h HorizonDBLedgerHashStore) GetLedgerHash(seq uint32) (string, bool, error) { + ctx := context.TODO() sql := sq.Select("hl.ledger_hash").From("history_ledgers hl"). Limit(1).Where("sequence = ?", seq) var hash string - err := h.session.Get(&hash, sql) + err := h.session.Get(ctx, &hash, sql) if h.session.NoRows(err) { return hash, false, nil } diff --git a/ingest/ledgerbackend/mock_database_backend.go b/ingest/ledgerbackend/mock_database_backend.go index b60c93bd67..67d9a367d7 100644 --- a/ingest/ledgerbackend/mock_database_backend.go +++ b/ingest/ledgerbackend/mock_database_backend.go @@ -1,8 +1,9 @@ package ledgerbackend import ( - "github.com/stellar/go/xdr" "github.com/stretchr/testify/mock" + + "github.com/stellar/go/xdr" ) var _ LedgerBackend = (*MockDatabaseBackend)(nil) diff --git a/ingest/ledgerbackend/remote_captive_core.go b/ingest/ledgerbackend/remote_captive_core.go index 49553ae92c..5e25a187ef 100644 --- a/ingest/ledgerbackend/remote_captive_core.go +++ b/ingest/ledgerbackend/remote_captive_core.go @@ -128,10 +128,17 @@ func decodeResponse(response *http.Response, payload interface{}) error { // the latest sequence closed by the network. It's always the last value available // in the backend. func (c RemoteCaptiveStellarCore) GetLatestLedgerSequence() (sequence uint32, err error) { + // TODO: Should we use c.createContext here? + ctx := context.TODO() u := *c.url u.Path = path.Join(u.Path, "latest-sequence") - response, err := c.client.Get(u.String()) + request, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + if err != nil { + return 0, errors.Wrap(err, "failed to build request") + } + + response, err := c.client.Do(request) if err != nil { return 0, errors.Wrap(err, "failed to execute request") } @@ -154,7 +161,7 @@ func (c RemoteCaptiveStellarCore) Close() error { return nil } -func (c RemoteCaptiveStellarCore) createContext() context.Context { +func (c RemoteCaptiveStellarCore) createContext(background context.Context) context.Context { c.lock.Lock() defer c.lock.Unlock() @@ -162,7 +169,7 @@ func (c RemoteCaptiveStellarCore) createContext() context.Context { c.cancel() } - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(background) c.cancel = cancel return ctx } @@ -177,7 +184,7 @@ func (c RemoteCaptiveStellarCore) createContext() context.Context { // Please note that using a BoundedRange, currently, requires a full-trust on // history archive. This issue is being fixed in Stellar-Core. func (c RemoteCaptiveStellarCore) PrepareRange(ledgerRange Range) error { - ctx := c.createContext() + ctx := c.createContext(context.TODO()) u := *c.url u.Path = path.Join(u.Path, "prepare-range") rangeBytes, err := json.Marshal(ledgerRange) @@ -220,6 +227,8 @@ func (c RemoteCaptiveStellarCore) PrepareRange(ledgerRange Range) error { // IsPrepared returns true if a given ledgerRange is prepared. func (c RemoteCaptiveStellarCore) IsPrepared(ledgerRange Range) (bool, error) { + ctx := c.createContext(context.TODO()) + u := *c.url u.Path = path.Join(u.Path, "prepare-range") rangeBytes, err := json.Marshal(ledgerRange) @@ -227,9 +236,14 @@ func (c RemoteCaptiveStellarCore) IsPrepared(ledgerRange Range) (bool, error) { return false, errors.Wrap(err, "cannot serialize range") } body := bytes.NewReader(rangeBytes) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), body) + if err != nil { + return false, errors.Wrap(err, "failed to build request") + } + req.Header.Add("Content-Type", "application/json; charset=utf-8") var response *http.Response - response, err = c.client.Post(u.String(), "application/json; charset=utf-8", body) + response, err = c.client.Do(req) if err != nil { return false, errors.Wrap(err, "failed to execute request") } @@ -260,10 +274,16 @@ func (c RemoteCaptiveStellarCore) IsPrepared(ledgerRange Range) (bool, error) { // the first argument equal false. // This is done to provide maximum performance when streaming old ledgers. func (c RemoteCaptiveStellarCore) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMeta, error) { + ctx := c.createContext(context.TODO()) + u := *c.url u.Path = path.Join(u.Path, "ledger", strconv.FormatUint(uint64(sequence), 10)) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + if err != nil { + return false, xdr.LedgerCloseMeta{}, errors.Wrap(err, "failed to build request") + } - response, err := c.client.Get(u.String()) + response, err := c.client.Do(req) if err != nil { return false, xdr.LedgerCloseMeta{}, errors.Wrap(err, "failed to execute request") } diff --git a/ingest/stats_change_processor.go b/ingest/stats_change_processor.go index 929922126d..4dd744a95a 100644 --- a/ingest/stats_change_processor.go +++ b/ingest/stats_change_processor.go @@ -1,6 +1,7 @@ package ingest import ( + "context" "github.com/stellar/go/xdr" ) @@ -33,7 +34,7 @@ type StatsChangeProcessorResults struct { TrustLinesRemoved int64 } -func (p *StatsChangeProcessor) ProcessChange(change Change) error { +func (p *StatsChangeProcessor) ProcessChange(ctx context.Context, change Change) error { switch change.Type { case xdr.LedgerEntryTypeAccount: switch change.LedgerEntryChangeType() { diff --git a/ingest/stats_change_processor_test.go b/ingest/stats_change_processor_test.go index a17a74de62..d39ac092e0 100644 --- a/ingest/stats_change_processor_test.go +++ b/ingest/stats_change_processor_test.go @@ -1,6 +1,7 @@ package ingest import ( + "context" "testing" "github.com/stellar/go/xdr" @@ -8,96 +9,97 @@ import ( ) func TestStatsChangeProcessor(t *testing.T) { + ctx := context.Background() processor := &StatsChangeProcessor{} // Created - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: nil, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeData, Pre: nil, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeOffer, Pre: nil, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{}, })) // Updated - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{}, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &xdr.LedgerEntry{}, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeData, Pre: &xdr.LedgerEntry{}, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{}, Post: &xdr.LedgerEntry{}, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{}, Post: &xdr.LedgerEntry{}, })) // Removed - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{}, Post: nil, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &xdr.LedgerEntry{}, Post: nil, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeData, Pre: &xdr.LedgerEntry{}, Post: nil, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{}, Post: nil, })) - assert.NoError(t, processor.ProcessChange(Change{ + assert.NoError(t, processor.ProcessChange(ctx, Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{}, Post: nil, diff --git a/services/horizon/cmd/db.go b/services/horizon/cmd/db.go index 640a94e742..67323cd3f0 100644 --- a/services/horizon/cmd/db.go +++ b/services/horizon/cmd/db.go @@ -1,6 +1,7 @@ package cmd import ( + "context" "database/sql" "fmt" "go/types" @@ -113,8 +114,9 @@ var dbReapCmd = &cobra.Command{ Long: "reap removes any historical data that is earlier than the configured retention cutoff", Run: func(cmd *cobra.Command, args []string) { app := horizon.NewAppFromFlags(config, flags) - app.UpdateLedgerState() - err := app.DeleteUnretainedHistory() + ctx := context.Background() + app.UpdateLedgerState(ctx) + err := app.DeleteUnretainedHistory(ctx) if err != nil { log.Fatal(err) } diff --git a/services/horizon/cmd/ingest.go b/services/horizon/cmd/ingest.go index 1063941463..d66aad2676 100644 --- a/services/horizon/cmd/ingest.go +++ b/services/horizon/cmd/ingest.go @@ -1,6 +1,7 @@ package cmd import ( + "context" "fmt" "go/types" "net/http" @@ -227,6 +228,7 @@ var ingestTriggerStateRebuildCmd = &cobra.Command{ Use: "trigger-state-rebuild", Short: "updates a database to trigger state rebuild, state will be rebuilt by a running Horizon instance, DO NOT RUN production DB, some endpoints will be unavailable until state is rebuilt", Run: func(cmd *cobra.Command, args []string) { + ctx := context.Background() horizon.ApplyFlags(config, flags) horizonSession, err := db.Open("postgres", config.DatabaseURL) @@ -235,7 +237,7 @@ var ingestTriggerStateRebuildCmd = &cobra.Command{ } historyQ := &history.Q{horizonSession} - err = historyQ.UpdateIngestVersion(0) + err = historyQ.UpdateIngestVersion(ctx, 0) if err != nil { log.Fatalf("cannot trigger state rebuild: %v", err) } @@ -248,6 +250,7 @@ var ingestInitGenesisStateCmd = &cobra.Command{ Use: "init-genesis-state", Short: "ingests genesis state (ledger 1)", Run: func(cmd *cobra.Command, args []string) { + ctx := context.Background() horizon.ApplyFlags(config, flags) horizonSession, err := db.Open("postgres", config.DatabaseURL) @@ -257,7 +260,7 @@ var ingestInitGenesisStateCmd = &cobra.Command{ historyQ := &history.Q{horizonSession} - lastIngestedLedger, err := historyQ.GetLastLedgerIngestNonBlocking() + lastIngestedLedger, err := historyQ.GetLastLedgerIngestNonBlocking(ctx) if err != nil { log.Fatalf("cannot get last ledger value: %v", err) } diff --git a/services/horizon/internal/action_offers_test.go b/services/horizon/internal/action_offers_test.go index b354e71ad1..737afe2fac 100644 --- a/services/horizon/internal/action_offers_test.go +++ b/services/horizon/internal/action_offers_test.go @@ -1,6 +1,7 @@ package horizon import ( + "context" "encoding/json" "testing" "time" @@ -15,14 +16,15 @@ func TestOfferActions_Show(t *testing.T) { ht := StartHTTPTestWithoutScenario(t) defer ht.Finish() q := &history.Q{ht.HorizonSession()} + ctx := context.Background() - err := q.UpdateLastLedgerIngest(100) + err := q.UpdateLastLedgerIngest(ctx, 100) ht.Assert.NoError(err) - err = q.UpdateIngestVersion(ingest.CurrentVersion) + err = q.UpdateIngestVersion(ctx, ingest.CurrentVersion) ht.Assert.NoError(err) ledgerCloseTime := time.Now().Unix() - _, err = q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + _, err = q.InsertLedger(ctx, xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ LedgerSeq: 100, ScpValue: xdr.StellarValue{ @@ -67,11 +69,11 @@ func TestOfferActions_Show(t *testing.T) { } batch := q.NewOffersBatchInsertBuilder(3) - err = batch.Add(eurOffer) + err = batch.Add(ctx, eurOffer) ht.Assert.NoError(err) - err = batch.Add(usdOffer) + err = batch.Add(ctx, usdOffer) ht.Assert.NoError(err) - ht.Assert.NoError(batch.Exec()) + ht.Assert.NoError(batch.Exec(ctx)) w := ht.Get("/offers") if ht.Assert.Equal(200, w.Code) { diff --git a/services/horizon/internal/actions/account.go b/services/horizon/internal/actions/account.go index 3555c6619a..a6d4278fc6 100644 --- a/services/horizon/internal/actions/account.go +++ b/services/horizon/internal/actions/account.go @@ -26,27 +26,27 @@ func AccountInfo(ctx context.Context, hq *history.Q, addr string) (*protocol.Acc resouce protocol.Account ) - record, err := hq.GetAccountByID(addr) + record, err := hq.GetAccountByID(ctx, addr) if err != nil { return nil, errors.Wrap(err, "getting history account record") } - data, err = hq.GetAccountDataByAccountID(addr) + data, err = hq.GetAccountDataByAccountID(ctx, addr) if err != nil { return nil, errors.Wrap(err, "getting history account data") } - signers, err = hq.GetAccountSignersByAccountID(addr) + signers, err = hq.GetAccountSignersByAccountID(ctx, addr) if err != nil { return nil, errors.Wrap(err, "getting history signers") } - trustlines, err = hq.GetSortedTrustLinesByAccountID(addr) + trustlines, err = hq.GetSortedTrustLinesByAccountID(ctx, addr) if err != nil { return nil, errors.Wrap(err, "getting history trustlines") } - ledger, err := getLedgerBySequence(hq, int32(record.LastModifiedLedger)) + ledger, err := getLedgerBySequence(ctx, hq, int32(record.LastModifiedLedger)) if err != nil { return nil, err } @@ -149,17 +149,17 @@ func (handler GetAccountsHandler) GetResourcePage( var records []history.AccountEntry if len(qp.Sponsor) > 0 { - records, err = historyQ.AccountsForSponsor(qp.Sponsor, pq) + records, err = historyQ.AccountsForSponsor(ctx, qp.Sponsor, pq) if err != nil { return nil, errors.Wrap(err, "loading account records") } } else if len(qp.Signer) > 0 { - records, err = historyQ.AccountEntriesForSigner(qp.Signer, pq) + records, err = historyQ.AccountEntriesForSigner(ctx, qp.Signer, pq) if err != nil { return nil, errors.Wrap(err, "loading account records") } } else { - records, err = historyQ.AccountsForAsset(*qp.Asset(), pq) + records, err = historyQ.AccountsForAsset(ctx, *qp.Asset(), pq) if err != nil { return nil, errors.Wrap(err, "loading account records") } @@ -177,17 +177,17 @@ func (handler GetAccountsHandler) GetResourcePage( accountIDs = append(accountIDs, record.AccountID) } - signers, err := handler.loadSigners(historyQ, accountIDs) + signers, err := handler.loadSigners(ctx, historyQ, accountIDs) if err != nil { return nil, err } - trustlines, err := handler.loadTrustlines(historyQ, accountIDs) + trustlines, err := handler.loadTrustlines(ctx, historyQ, accountIDs) if err != nil { return nil, err } - data, err := handler.loadData(historyQ, accountIDs) + data, err := handler.loadData(ctx, historyQ, accountIDs) if err != nil { return nil, err } @@ -197,7 +197,7 @@ func (handler GetAccountsHandler) GetResourcePage( ledgerCache.Queue(int32(record.LastModifiedLedger)) } - if err := ledgerCache.Load(historyQ); err != nil { + if err := ledgerCache.Load(ctx, historyQ); err != nil { return nil, errors.Wrap(err, "failed to load ledger batch") } @@ -218,10 +218,10 @@ func (handler GetAccountsHandler) GetResourcePage( return accounts, nil } -func (handler GetAccountsHandler) loadData(historyQ *history.Q, accounts []string) (map[string][]history.Data, error) { +func (handler GetAccountsHandler) loadData(ctx context.Context, historyQ *history.Q, accounts []string) (map[string][]history.Data, error) { data := make(map[string][]history.Data) - records, err := historyQ.GetAccountDataByAccountsID(accounts) + records, err := historyQ.GetAccountDataByAccountsID(ctx, accounts) if err != nil { return data, errors.Wrap(err, "loading account data records by accounts id") } @@ -233,10 +233,10 @@ func (handler GetAccountsHandler) loadData(historyQ *history.Q, accounts []strin return data, nil } -func (handler GetAccountsHandler) loadTrustlines(historyQ *history.Q, accounts []string) (map[string][]history.TrustLine, error) { +func (handler GetAccountsHandler) loadTrustlines(ctx context.Context, historyQ *history.Q, accounts []string) (map[string][]history.TrustLine, error) { trustLines := make(map[string][]history.TrustLine) - records, err := historyQ.GetSortedTrustLinesByAccountIDs(accounts) + records, err := historyQ.GetSortedTrustLinesByAccountIDs(ctx, accounts) if err != nil { return trustLines, errors.Wrap(err, "loading trustline records by accounts") } @@ -248,10 +248,10 @@ func (handler GetAccountsHandler) loadTrustlines(historyQ *history.Q, accounts [ return trustLines, nil } -func (handler GetAccountsHandler) loadSigners(historyQ *history.Q, accounts []string) (map[string][]history.AccountSigner, error) { +func (handler GetAccountsHandler) loadSigners(ctx context.Context, historyQ *history.Q, accounts []string) (map[string][]history.AccountSigner, error) { signers := make(map[string][]history.AccountSigner) - records, err := historyQ.SignersForAccounts(accounts) + records, err := historyQ.SignersForAccounts(ctx, accounts) if err != nil { return signers, errors.Wrap(err, "loading account signers by account") } @@ -263,9 +263,9 @@ func (handler GetAccountsHandler) loadSigners(historyQ *history.Q, accounts []st return signers, nil } -func getLedgerBySequence(hq *history.Q, sequence int32) (*history.Ledger, error) { +func getLedgerBySequence(ctx context.Context, hq *history.Q, sequence int32) (*history.Ledger, error) { ledger := &history.Ledger{} - err := hq.LedgerBySequence(ledger, sequence) + err := hq.LedgerBySequence(ctx, ledger, sequence) switch { case hq.NoRows(err): return nil, nil diff --git a/services/horizon/internal/actions/account_data.go b/services/horizon/internal/actions/account_data.go index f0a3224e35..9b3e7e499c 100644 --- a/services/horizon/internal/actions/account_data.go +++ b/services/horizon/internal/actions/account_data.go @@ -60,7 +60,7 @@ func loadAccountData(r *http.Request) (history.Data, error) { if err != nil { return history.Data{}, err } - data, err := historyQ.GetAccountDataByName(qp.AccountID, qp.Key) + data, err := historyQ.GetAccountDataByName(r.Context(), qp.AccountID, qp.Key) if err != nil { return history.Data{}, err } diff --git a/services/horizon/internal/actions/account_test.go b/services/horizon/internal/actions/account_test.go index a192d8ce0f..7695394a72 100644 --- a/services/horizon/internal/actions/account_test.go +++ b/services/horizon/internal/actions/account_test.go @@ -240,13 +240,13 @@ func TestAccountInfo(t *testing.T) { }, } batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(accountEntry) + err := batch.Add(tt.Ctx, accountEntry) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) tt.Assert.NoError(err) - _, err = q.InsertTrustLine(xdr.LedgerEntry{ + _, err = q.InsertTrustLine(tt.Ctx, xdr.LedgerEntry{ LastModifiedLedgerSeq: 6, Data: xdr.LedgerEntryData{ Type: xdr.LedgerEntryTypeTrustline, @@ -264,7 +264,7 @@ func TestAccountInfo(t *testing.T) { }) assert.NoError(t, err) - _, err = q.InsertTrustLine(xdr.LedgerEntry{ + _, err = q.InsertTrustLine(tt.Ctx, xdr.LedgerEntry{ LastModifiedLedgerSeq: 1234, Data: xdr.LedgerEntryData{ Type: xdr.LedgerEntryTypeTrustline, @@ -283,7 +283,7 @@ func TestAccountInfo(t *testing.T) { assert.NoError(t, err) ledgerFourCloseTime := time.Now().Unix() - _, err = q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + _, err = q.InsertLedger(tt.Ctx, xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ LedgerSeq: 4, ScpValue: xdr.StellarValue{ @@ -355,16 +355,16 @@ func TestGetAccountsHandlerPageResultsBySigner(t *testing.T) { handler := &GetAccountsHandler{} batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - err = batch.Add(account3) + err = batch.Add(tt.Ctx, account3) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) for _, row := range accountSigners { - q.CreateAccountSigner(row.Account, row.Signer, row.Weight, nil) + q.CreateAccountSigner(tt.Ctx, row.Account, row.Signer, row.Weight, nil) } records, err := handler.GetResourcePage( @@ -435,16 +435,16 @@ func TestGetAccountsHandlerPageResultsBySponsor(t *testing.T) { handler := &GetAccountsHandler{} batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - err = batch.Add(account3) + err = batch.Add(tt.Ctx, account3) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) for _, row := range accountSigners { - q.CreateAccountSigner(row.Account, row.Signer, row.Weight, nil) + q.CreateAccountSigner(tt.Ctx, row.Account, row.Signer, row.Weight, nil) } records, err := handler.GetResourcePage( @@ -473,13 +473,13 @@ func TestGetAccountsHandlerPageResultsByAsset(t *testing.T) { handler := &GetAccountsHandler{} batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) ledgerCloseTime := time.Now().Unix() - _, err = q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + _, err = q.InsertLedger(tt.Ctx, xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ LedgerSeq: 1234, ScpValue: xdr.StellarValue{ @@ -490,13 +490,13 @@ func TestGetAccountsHandlerPageResultsByAsset(t *testing.T) { assert.NoError(t, err) for _, row := range accountSigners { - _, err = q.CreateAccountSigner(row.Account, row.Signer, row.Weight, nil) + _, err = q.CreateAccountSigner(tt.Ctx, row.Account, row.Signer, row.Weight, nil) tt.Assert.NoError(err) } - _, err = q.InsertAccountData(data1) + _, err = q.InsertAccountData(tt.Ctx, data1) assert.NoError(t, err) - _, err = q.InsertAccountData(data2) + _, err = q.InsertAccountData(tt.Ctx, data2) assert.NoError(t, err) var assetType, code, issuer string @@ -518,9 +518,9 @@ func TestGetAccountsHandlerPageResultsByAsset(t *testing.T) { tt.Assert.NoError(err) tt.Assert.Equal(0, len(records)) - _, err = q.InsertTrustLine(eurTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, eurTrustLine) assert.NoError(t, err) - _, err = q.InsertTrustLine(usdTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, usdTrustLine) assert.NoError(t, err) records, err = handler.GetResourcePage( diff --git a/services/horizon/internal/actions/asset.go b/services/horizon/internal/actions/asset.go index 8b014dc1d1..86dee222e3 100644 --- a/services/horizon/internal/actions/asset.go +++ b/services/horizon/internal/actions/asset.go @@ -1,12 +1,13 @@ package actions import ( + "context" "fmt" "net/http" "strings" "github.com/stellar/go/protocols/horizon" - "github.com/stellar/go/services/horizon/internal/context" + horizonContext "github.com/stellar/go/services/horizon/internal/context" "github.com/stellar/go/services/horizon/internal/db2" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/ledger" @@ -78,6 +79,7 @@ func (handler AssetStatsHandler) validateAssetParams(code, issuer string, pq db2 } func (handler AssetStatsHandler) findIssuersForAssets( + ctx context.Context, historyQ *history.Q, assetStats []history.ExpAssetStat, ) (map[string]history.AccountEntry, error) { @@ -92,7 +94,7 @@ func (handler AssetStatsHandler) findIssuersForAssets( } accountsByID := map[string]history.AccountEntry{} - accounts, err := historyQ.GetAccountsByIDs(issuers) + accounts, err := historyQ.GetAccountsByIDs(ctx, issuers) if err != nil { return nil, err } @@ -134,17 +136,17 @@ func (handler AssetStatsHandler) GetResourcePage( return nil, err } - historyQ, err := context.HistoryQFromRequest(r) + historyQ, err := horizonContext.HistoryQFromRequest(r) if err != nil { return nil, err } - assetStats, err := historyQ.GetAssetStats(code, issuer, pq) + assetStats, err := historyQ.GetAssetStats(ctx, code, issuer, pq) if err != nil { return nil, err } - issuerAccounts, err := handler.findIssuersForAssets(historyQ, assetStats) + issuerAccounts, err := handler.findIssuersForAssets(ctx, historyQ, assetStats) if err != nil { return nil, err } diff --git a/services/horizon/internal/actions/asset_test.go b/services/horizon/internal/actions/asset_test.go index c8416a5292..12969da2b5 100644 --- a/services/horizon/internal/actions/asset_test.go +++ b/services/horizon/internal/actions/asset_test.go @@ -303,7 +303,7 @@ func TestAssetStats(t *testing.T) { otherUSDAssetStat, usdAssetStat, } { - numChanged, err := q.InsertAssetStat(assetStat) + numChanged, err := q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.NoError(err) tt.Assert.Equal(numChanged, int64(1)) } @@ -326,9 +326,9 @@ func TestAssetStats(t *testing.T) { t.Fatalf("unexpected error %v", err) } batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(accountEntry) + err := batch.Add(tt.Ctx, accountEntry) tt.Assert.NoError(err) - tt.Assert.NoError(batch.Exec()) + tt.Assert.NoError(batch.Exec(tt.Ctx)) } for _, testCase := range []struct { @@ -446,7 +446,7 @@ func TestAssetStatsIssuerDoesNotExist(t *testing.T) { Amount: "1", NumAccounts: 2, } - numChanged, err := q.InsertAssetStat(usdAssetStat) + numChanged, err := q.InsertAssetStat(tt.Ctx, usdAssetStat) tt.Assert.NoError(err) tt.Assert.Equal(numChanged, int64(1)) diff --git a/services/horizon/internal/actions/claimable_balance.go b/services/horizon/internal/actions/claimable_balance.go index 9e6bbea6e2..c5953d13a9 100644 --- a/services/horizon/internal/actions/claimable_balance.go +++ b/services/horizon/internal/actions/claimable_balance.go @@ -64,12 +64,12 @@ func (handler GetClaimableBalanceByIDHandler) GetResource(w HeaderWriter, r *htt if err != nil { return nil, err } - cb, err := historyQ.FindClaimableBalanceByID(balanceID) + cb, err := historyQ.FindClaimableBalanceByID(ctx, balanceID) if err != nil { return nil, err } ledger := &history.Ledger{} - err = historyQ.LedgerBySequence( + err = historyQ.LedgerBySequence(ctx, ledger, int32(cb.LastModifiedLedger), ) @@ -179,7 +179,7 @@ func (handler GetClaimableBalancesHandler) GetResourcePage( } func getClaimableBalancesPage(ctx context.Context, historyQ *history.Q, query history.ClaimableBalancesQuery) ([]hal.Pageable, error) { - records, err := historyQ.GetClaimableBalances(query) + records, err := historyQ.GetClaimableBalances(ctx, query) if err != nil { return nil, err } @@ -188,7 +188,7 @@ func getClaimableBalancesPage(ctx context.Context, historyQ *history.Q, query hi for _, record := range records { ledgerCache.Queue(int32(record.LastModifiedLedger)) } - if err := ledgerCache.Load(historyQ); err != nil { + if err := ledgerCache.Load(ctx, historyQ); err != nil { return nil, errors.Wrap(err, "failed to load ledger batch") } diff --git a/services/horizon/internal/actions/claimable_balance_test.go b/services/horizon/internal/actions/claimable_balance_test.go index d50f27ac53..5cc3ea466b 100644 --- a/services/horizon/internal/actions/claimable_balance_test.go +++ b/services/horizon/internal/actions/claimable_balance_test.go @@ -52,10 +52,10 @@ func TestGetClaimableBalanceByID(t *testing.T) { builder := q.NewClaimableBalancesBatchInsertBuilder(2) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) tt.Assert.NoError(err) @@ -200,11 +200,11 @@ func TestGetClaimableBalances(t *testing.T) { for _, e := range entriesMeta { entry := buildClaimableBalance(e.id, e.accountID, e.ledger, e.asset) entries = append(entries, entry) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) } - err := builder.Exec() + err := builder.Exec(tt.Ctx) tt.Assert.NoError(err) handler := GetClaimableBalancesHandler{} @@ -293,7 +293,7 @@ func TestGetClaimableBalances(t *testing.T) { SponsoringId: xdr.MustAddressPtr("GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML"), } entryToBeUpdated.LastModifiedLedgerSeq = xdr.Uint32(1238) - q.UpdateClaimableBalance(entryToBeUpdated) + q.UpdateClaimableBalance(tt.Ctx, entryToBeUpdated) entriesMeta = []struct { id xdr.Hash @@ -319,10 +319,10 @@ func TestGetClaimableBalances(t *testing.T) { for _, e := range entriesMeta { entry := buildClaimableBalance(e.id, e.accountID, e.ledger, e.asset) entries = append(entries, entry) - tt.Assert.NoError(builder.Add(&entry)) + tt.Assert.NoError(builder.Add(tt.Ctx, &entry)) } - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) response, err = handler.GetResourcePage(httptest.NewRecorder(), makeRequest( diff --git a/services/horizon/internal/actions/effects.go b/services/horizon/internal/actions/effects.go index aaa0d502f3..4625583f64 100644 --- a/services/horizon/internal/actions/effects.go +++ b/services/horizon/internal/actions/effects.go @@ -1,9 +1,10 @@ package actions import ( + "context" "net/http" - "github.com/stellar/go/services/horizon/internal/context" + horizonContext "github.com/stellar/go/services/horizon/internal/context" "github.com/stellar/go/services/horizon/internal/db2" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/ledger" @@ -64,17 +65,17 @@ func (handler GetEffectsHandler) GetResourcePage(w HeaderWriter, r *http.Request return nil, err } - historyQ, err := context.HistoryQFromRequest(r) + historyQ, err := horizonContext.HistoryQFromRequest(r) if err != nil { return nil, err } - records, err := loadEffectRecords(historyQ, qp.AccountID, int64(qp.OperationID), qp.TxHash, qp.LedgerID, pq) + records, err := loadEffectRecords(r.Context(), historyQ, qp.AccountID, int64(qp.OperationID), qp.TxHash, qp.LedgerID, pq) if err != nil { return nil, errors.Wrap(err, "loading transaction records") } - ledgers, err := loadEffectLedgers(historyQ, records) + ledgers, err := loadEffectLedgers(r.Context(), historyQ, records) if err != nil { return nil, errors.Wrap(err, "loading ledgers") } @@ -91,35 +92,35 @@ func (handler GetEffectsHandler) GetResourcePage(w HeaderWriter, r *http.Request return result, nil } -func loadEffectRecords(hq *history.Q, accountID string, operationID int64, transactionHash string, ledgerID uint32, +func loadEffectRecords(ctx context.Context, hq *history.Q, accountID string, operationID int64, transactionHash string, ledgerID uint32, pq db2.PageQuery) ([]history.Effect, error) { effects := hq.Effects() switch { case accountID != "": - effects.ForAccount(accountID) + effects.ForAccount(ctx, accountID) case ledgerID > 0: - effects.ForLedger(int32(ledgerID)) + effects.ForLedger(ctx, int32(ledgerID)) case operationID > 0: effects.ForOperation(operationID) case transactionHash != "": - effects.ForTransaction(transactionHash) + effects.ForTransaction(ctx, transactionHash) } var result []history.Effect - err := effects.Page(pq).Select(&result) + err := effects.Page(pq).Select(ctx, &result) return result, err } -func loadEffectLedgers(hq *history.Q, effects []history.Effect) (map[int32]history.Ledger, error) { +func loadEffectLedgers(ctx context.Context, hq *history.Q, effects []history.Effect) (map[int32]history.Ledger, error) { ledgers := &history.LedgerCache{} for _, e := range effects { ledgers.Queue(e.LedgerSequence()) } - if err := ledgers.Load(hq); err != nil { + if err := ledgers.Load(ctx, hq); err != nil { return nil, err } return ledgers.Records, nil diff --git a/services/horizon/internal/actions/ledger.go b/services/horizon/internal/actions/ledger.go index db1ead097d..37fddb5bd9 100644 --- a/services/horizon/internal/actions/ledger.go +++ b/services/horizon/internal/actions/ledger.go @@ -33,7 +33,7 @@ func (handler GetLedgersHandler) GetResourcePage(w HeaderWriter, r *http.Request } var records []history.Ledger - if err = historyQ.Ledgers().Page(pq).Select(&records); err != nil { + if err = historyQ.Ledgers().Page(pq).Select(r.Context(), &records); err != nil { return nil, err } @@ -73,7 +73,7 @@ func (handler GetLedgerByIDHandler) GetResource(w HeaderWriter, r *http.Request) return nil, err } var ledger history.Ledger - err = historyQ.LedgerBySequence(&ledger, int32(qp.LedgerID)) + err = historyQ.LedgerBySequence(r.Context(), &ledger, int32(qp.LedgerID)) if err != nil { return nil, err } diff --git a/services/horizon/internal/actions/offer.go b/services/horizon/internal/actions/offer.go index a8456dda2e..c5de593c4b 100644 --- a/services/horizon/internal/actions/offer.go +++ b/services/horizon/internal/actions/offer.go @@ -35,13 +35,14 @@ func (handler GetOfferByID) GetResource(w HeaderWriter, r *http.Request) (interf return nil, err } - record, err := historyQ.GetOfferByID(int64(qp.OfferID)) + record, err := historyQ.GetOfferByID(r.Context(), int64(qp.OfferID)) if err != nil { return nil, err } ledger := &history.Ledger{} err = historyQ.LedgerBySequence( + r.Context(), ledger, int32(record.LastModifiedLedger), ) @@ -181,7 +182,7 @@ func (handler GetAccountOffersHandler) GetResourcePage( } func getOffersPage(ctx context.Context, historyQ *history.Q, query history.OffersQuery) ([]hal.Pageable, error) { - records, err := historyQ.GetOffers(query) + records, err := historyQ.GetOffers(ctx, query) if err != nil { return nil, err } @@ -191,7 +192,7 @@ func getOffersPage(ctx context.Context, historyQ *history.Q, query history.Offer ledgerCache.Queue(int32(record.LastModifiedLedger)) } - if err := ledgerCache.Load(historyQ); err != nil { + if err := ledgerCache.Load(ctx, historyQ); err != nil { return nil, errors.Wrap(err, "failed to load ledger batch") } diff --git a/services/horizon/internal/actions/offer_test.go b/services/horizon/internal/actions/offer_test.go index 19bff5c350..11c5f63f5b 100644 --- a/services/horizon/internal/actions/offer_test.go +++ b/services/horizon/internal/actions/offer_test.go @@ -79,7 +79,7 @@ func TestGetOfferByIDHandler(t *testing.T) { handler := GetOfferByID{} ledgerCloseTime := time.Now().Unix() - _, err := q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + _, err := q.InsertLedger(tt.Ctx, xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ LedgerSeq: 3, ScpValue: xdr.StellarValue{ @@ -90,11 +90,11 @@ func TestGetOfferByIDHandler(t *testing.T) { tt.Assert.NoError(err) batch := q.NewOffersBatchInsertBuilder(0) - err = batch.Add(eurOffer) + err = batch.Add(tt.Ctx, eurOffer) tt.Assert.NoError(err) - err = batch.Add(usdOffer) + err = batch.Add(tt.Ctx, usdOffer) tt.Assert.NoError(err) - tt.Assert.NoError(batch.Exec()) + tt.Assert.NoError(batch.Exec(tt.Ctx)) for _, testCase := range []struct { name string @@ -190,7 +190,7 @@ func TestGetOffersHandler(t *testing.T) { handler := GetOffersHandler{} ledgerCloseTime := time.Now().Unix() - _, err := q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + _, err := q.InsertLedger(tt.Ctx, xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ LedgerSeq: 3, ScpValue: xdr.StellarValue{ @@ -201,13 +201,13 @@ func TestGetOffersHandler(t *testing.T) { tt.Assert.NoError(err) batch := q.NewOffersBatchInsertBuilder(0) - err = batch.Add(eurOffer) + err = batch.Add(tt.Ctx, eurOffer) tt.Assert.NoError(err) - err = batch.Add(twoEurOffer) + err = batch.Add(tt.Ctx, twoEurOffer) tt.Assert.NoError(err) - err = batch.Add(usdOffer) + err = batch.Add(tt.Ctx, usdOffer) tt.Assert.NoError(err) - tt.Assert.NoError(batch.Exec()) + tt.Assert.NoError(batch.Exec(tt.Ctx)) t.Run("No filter", func(t *testing.T) { records, err := handler.GetResourcePage( @@ -478,12 +478,12 @@ func TestGetAccountOffersHandler(t *testing.T) { handler := GetAccountOffersHandler{} batch := q.NewOffersBatchInsertBuilder(0) - err := batch.Add(eurOffer) - err = batch.Add(twoEurOffer) + err := batch.Add(tt.Ctx, eurOffer) + err = batch.Add(tt.Ctx, twoEurOffer) tt.Assert.NoError(err) - err = batch.Add(usdOffer) + err = batch.Add(tt.Ctx, usdOffer) tt.Assert.NoError(err) - tt.Assert.NoError(batch.Exec()) + tt.Assert.NoError(batch.Exec(tt.Ctx)) records, err := handler.GetResourcePage( httptest.NewRecorder(), diff --git a/services/horizon/internal/actions/operation.go b/services/horizon/internal/actions/operation.go index 8bc16dc5de..505ebd08d8 100644 --- a/services/horizon/internal/actions/operation.go +++ b/services/horizon/internal/actions/operation.go @@ -94,17 +94,17 @@ func (handler GetOperationsHandler) GetResourcePage(w HeaderWriter, r *http.Requ switch { case qp.AccountID != "": - query.ForAccount(qp.AccountID) + query.ForAccount(ctx, qp.AccountID) case qp.ClaimableBalanceID != "": cbID, parseErr := balanceIDHex2XDR(qp.ClaimableBalanceID, "claimable_balance_id") if parseErr != nil { return nil, parseErr } - query.ForClaimableBalance(cbID) + query.ForClaimableBalance(ctx, cbID) case qp.LedgerID > 0: - query.ForLedger(int32(qp.LedgerID)) + query.ForLedger(ctx, int32(qp.LedgerID)) case qp.TransactionHash != "": - query.ForTransaction(qp.TransactionHash) + query.ForTransaction(ctx, qp.TransactionHash) } // When querying operations for transaction return both successful // and failed operations. We assume that because the user is querying @@ -121,7 +121,7 @@ func (handler GetOperationsHandler) GetResourcePage(w HeaderWriter, r *http.Requ query.OnlyPayments() } - ops, txs, err := query.Page(pq).Fetch() + ops, txs, err := query.Page(pq).Fetch(ctx) if err != nil { return nil, err } @@ -165,13 +165,13 @@ func (handler GetOperationByIDHandler) GetResource(w HeaderWriter, r *http.Reque if err != nil { return nil, err } - op, tx, err := historyQ.OperationByID(qp.IncludeTransactions(), int64(qp.ID)) + op, tx, err := historyQ.OperationByID(ctx, qp.IncludeTransactions(), int64(qp.ID)) if err != nil { return nil, err } var ledger history.Ledger - err = historyQ.LedgerBySequence(&ledger, op.LedgerSequence()) + err = historyQ.LedgerBySequence(ctx, &ledger, op.LedgerSequence()) if err != nil { return nil, err } @@ -191,7 +191,7 @@ func buildOperationsPage(ctx context.Context, historyQ *history.Q, operations [] ledgerCache.Queue(record.LedgerSequence()) } - if err := ledgerCache.Load(historyQ); err != nil { + if err := ledgerCache.Load(ctx, historyQ); err != nil { return nil, errors.Wrap(err, "failed to load ledger batch") } diff --git a/services/horizon/internal/actions/operation_test.go b/services/horizon/internal/actions/operation_test.go index 555236a475..7af114a964 100644 --- a/services/horizon/internal/actions/operation_test.go +++ b/services/horizon/internal/actions/operation_test.go @@ -294,7 +294,7 @@ func TestGetOperationsIncludeFailed(t *testing.T) { } // NULL value - _, err = tt.HorizonSession().ExecRaw( + _, err = tt.HorizonSession().ExecRaw(tt.Ctx, `UPDATE history_transactions SET successful = NULL WHERE transaction_hash = ?`, "56e3216045d579bea40f2d35a09406de3a894ecb5be70dbda5ec9c0427a0d5a1", ) @@ -504,7 +504,7 @@ func TestOperation_CreatedAt(t *testing.T) { tt.Assert.NoError(err) l := history.Ledger{} - tt.Assert.NoError(q.LedgerBySequence(&l, 3)) + tt.Assert.NoError(q.LedgerBySequence(tt.Ctx, &l, 3)) record := records[0].(operations.Payment) diff --git a/services/horizon/internal/actions/orderbook.go b/services/horizon/internal/actions/orderbook.go index aca7a8ed68..c00d5ceae4 100644 --- a/services/horizon/internal/actions/orderbook.go +++ b/services/horizon/internal/actions/orderbook.go @@ -100,7 +100,7 @@ func (handler GetOrderbookHandler) GetResource(w HeaderWriter, r *http.Request) return nil, err } - summary, err := historyQ.GetOrderBookSummary(selling, buying, int(limit)) + summary, err := historyQ.GetOrderBookSummary(r.Context(), selling, buying, int(limit)) if err != nil { return nil, err } diff --git a/services/horizon/internal/actions/orderbook_test.go b/services/horizon/internal/actions/orderbook_test.go index 3c1c25f28d..0b1d4de0c0 100644 --- a/services/horizon/internal/actions/orderbook_test.go +++ b/services/horizon/internal/actions/orderbook_test.go @@ -574,19 +574,19 @@ func TestOrderbookGetResource(t *testing.T) { otherSellEurOffer, } - assert.NoError(t, q.TruncateTables([]string{"offers"})) + assert.NoError(t, q.TruncateTables(tt.Ctx, []string{"offers"})) batch := q.NewOffersBatchInsertBuilder(0) for _, offer := range offers { - assert.NoError(t, batch.Add(offer)) + assert.NoError(t, batch.Add(tt.Ctx, offer)) } - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - assert.NoError(t, q.BeginTx(&sql.TxOptions{ + assert.NoError(t, q.BeginTx(tt.Ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, })) - defer q.Rollback() + defer q.Rollback(tt.Ctx) fullResponse := empty fullResponse.Asks = []protocol.PriceLevel{ diff --git a/services/horizon/internal/actions/path.go b/services/horizon/internal/actions/path.go index 680b99332d..6ea093cba6 100644 --- a/services/horizon/internal/actions/path.go +++ b/services/horizon/internal/actions/path.go @@ -334,5 +334,5 @@ func assetsForAddress(r *http.Request, addy string) ([]xdr.Asset, []xdr.Int64, e if err != nil { return nil, nil, err } - return historyQ.AssetsForAddress(addy) + return historyQ.AssetsForAddress(r.Context(), addy) } diff --git a/services/horizon/internal/actions/trade.go b/services/horizon/internal/actions/trade.go index 5cce1cd2a3..2d639afb11 100644 --- a/services/horizon/internal/actions/trade.go +++ b/services/horizon/internal/actions/trade.go @@ -1,13 +1,14 @@ package actions import ( + "context" "fmt" "net/http" "strconv" gTime "time" "github.com/stellar/go/protocols/horizon" - "github.com/stellar/go/services/horizon/internal/context" + horizonContext "github.com/stellar/go/services/horizon/internal/context" "github.com/stellar/go/services/horizon/internal/db2" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/ledger" @@ -125,7 +126,7 @@ func (handler GetTradesHandler) GetResourcePage(w HeaderWriter, r *http.Request) return nil, err } - historyQ, err := context.HistoryQFromRequest(r) + historyQ, err := horizonContext.HistoryQFromRequest(r) if err != nil { return nil, err } @@ -133,7 +134,7 @@ func (handler GetTradesHandler) GetResourcePage(w HeaderWriter, r *http.Request) trades := historyQ.Trades() if qp.AccountID != "" { - trades.ForAccount(qp.AccountID) + trades.ForAccount(ctx, qp.AccountID) } baseAsset, err := qp.Base() @@ -142,7 +143,7 @@ func (handler GetTradesHandler) GetResourcePage(w HeaderWriter, r *http.Request) } if baseAsset != nil { - baseAssetID, err2 := historyQ.GetAssetID(*baseAsset) + baseAssetID, err2 := historyQ.GetAssetID(ctx, *baseAsset) if err2 != nil { return nil, err2 } @@ -152,7 +153,7 @@ func (handler GetTradesHandler) GetResourcePage(w HeaderWriter, r *http.Request) return nil, err2 } - counterAssetID, err2 := historyQ.GetAssetID(*counterAsset) + counterAssetID, err2 := historyQ.GetAssetID(ctx, *counterAsset) if err2 != nil { return nil, err2 } @@ -164,7 +165,7 @@ func (handler GetTradesHandler) GetResourcePage(w HeaderWriter, r *http.Request) } var records []history.Trade - if err = trades.Page(pq).Select(&records); err != nil { + if err = trades.Page(ctx, pq).Select(ctx, &records); err != nil { return nil, err } var response []hal.Pageable @@ -256,12 +257,12 @@ func (handler GetTradeAggregationsHandler) GetResource(w HeaderWriter, r *http.R return nil, err } - historyQ, err := context.HistoryQFromRequest(r) + historyQ, err := horizonContext.HistoryQFromRequest(r) if err != nil { return nil, err } - records, err := handler.fetchRecords(historyQ, qp, pq) + records, err := handler.fetchRecords(ctx, historyQ, qp, pq) if err != nil { return nil, err } @@ -279,13 +280,13 @@ func (handler GetTradeAggregationsHandler) GetResource(w HeaderWriter, r *http.R return handler.buildPage(r, aggregations) } -func (handler GetTradeAggregationsHandler) fetchRecords(historyQ *history.Q, qp TradeAggregationsQuery, pq db2.PageQuery) ([]history.TradeAggregation, error) { +func (handler GetTradeAggregationsHandler) fetchRecords(ctx context.Context, historyQ *history.Q, qp TradeAggregationsQuery, pq db2.PageQuery) ([]history.TradeAggregation, error) { baseAsset, err := qp.Base() if err != nil { return nil, err } - baseAssetID, err := historyQ.GetAssetID(*baseAsset) + baseAssetID, err := historyQ.GetAssetID(ctx, *baseAsset) if err != nil { p := problem.BadRequest if historyQ.NoRows(err) { @@ -304,7 +305,7 @@ func (handler GetTradeAggregationsHandler) fetchRecords(historyQ *history.Q, qp return nil, err } - counterAssetID, err := historyQ.GetAssetID(*counterAsset) + counterAssetID, err := historyQ.GetAssetID(ctx, *counterAsset) if err != nil { p := problem.BadRequest if historyQ.NoRows(err) { @@ -358,7 +359,7 @@ func (handler GetTradeAggregationsHandler) fetchRecords(historyQ *history.Q, qp } var records []history.TradeAggregation - err = historyQ.Select(&records, tradeAggregationsQ.GetSql()) + err = historyQ.Select(ctx, &records, tradeAggregationsQ.GetSql()) if err != nil { return nil, err } diff --git a/services/horizon/internal/actions/transaction.go b/services/horizon/internal/actions/transaction.go index 392ab69f1d..1491878e38 100644 --- a/services/horizon/internal/actions/transaction.go +++ b/services/horizon/internal/actions/transaction.go @@ -1,10 +1,11 @@ package actions import ( + "context" "net/http" "github.com/stellar/go/protocols/horizon" - "github.com/stellar/go/services/horizon/internal/context" + horizonContext "github.com/stellar/go/services/horizon/internal/context" "github.com/stellar/go/services/horizon/internal/db2" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/ledger" @@ -33,7 +34,7 @@ func (handler GetTransactionByHashHandler) GetResource(w HeaderWriter, r *http.R return nil, err } - historyQ, err := context.HistoryQFromRequest(r) + historyQ, err := horizonContext.HistoryQFromRequest(r) if err != nil { return nil, err } @@ -43,7 +44,7 @@ func (handler GetTransactionByHashHandler) GetResource(w HeaderWriter, r *http.R resource horizon.Transaction ) - err = historyQ.TransactionByHash(&record, qp.TransactionHash) + err = historyQ.TransactionByHash(ctx, &record, qp.TransactionHash) if err != nil { return resource, errors.Wrap(err, "loading transaction record") } @@ -109,7 +110,7 @@ func (handler GetTransactionsHandler) GetResourcePage(w HeaderWriter, r *http.Re return nil, err } - historyQ, err := context.HistoryQFromRequest(r) + historyQ, err := horizonContext.HistoryQFromRequest(r) if err != nil { return nil, err } @@ -123,7 +124,7 @@ func (handler GetTransactionsHandler) GetResourcePage(w HeaderWriter, r *http.Re } cbID = &cb } - records, err := loadTransactionRecords(historyQ, qp.AccountID, cbID, int32(qp.LedgerID), qp.IncludeFailedTransactions, pq) + records, err := loadTransactionRecords(ctx, historyQ, qp.AccountID, cbID, int32(qp.LedgerID), qp.IncludeFailedTransactions, pq) if err != nil { return nil, errors.Wrap(err, "loading transaction records") } @@ -145,7 +146,7 @@ func (handler GetTransactionsHandler) GetResourcePage(w HeaderWriter, r *http.Re // loadTransactionRecords returns a slice of transaction records of an // account/ledger identified by accountID/ledgerID based on pq and // includeFailedTx. -func loadTransactionRecords(hq *history.Q, accountID string, cbID *xdr.ClaimableBalanceId, ledgerID int32, includeFailedTx bool, pq db2.PageQuery) ([]history.Transaction, error) { +func loadTransactionRecords(ctx context.Context, hq *history.Q, accountID string, cbID *xdr.ClaimableBalanceId, ledgerID int32, includeFailedTx bool, pq db2.PageQuery) ([]history.Transaction, error) { if accountID != "" && ledgerID != 0 { return nil, errors.New("conflicting exclusive fields are present: account_id and ledger_id") } @@ -155,18 +156,18 @@ func loadTransactionRecords(hq *history.Q, accountID string, cbID *xdr.Claimable txs := hq.Transactions() switch { case accountID != "": - txs.ForAccount(accountID) + txs.ForAccount(ctx, accountID) case cbID != nil: - txs.ForClaimableBalance(*cbID) + txs.ForClaimableBalance(ctx, *cbID) case ledgerID > 0: - txs.ForLedger(ledgerID) + txs.ForLedger(ctx, ledgerID) } if includeFailedTx { txs.IncludeFailed() } - err := txs.Page(pq).Select(&records) + err := txs.Page(pq).Select(ctx, &records) if err != nil { return nil, errors.Wrap(err, "executing transaction records query") } diff --git a/services/horizon/internal/actions_account_test.go b/services/horizon/internal/actions_account_test.go index c83b27bec3..541300c3a6 100644 --- a/services/horizon/internal/actions_account_test.go +++ b/services/horizon/internal/actions_account_test.go @@ -14,11 +14,11 @@ func TestAccountActions_InvalidID(t *testing.T) { // Makes StateMiddleware happy q := history.Q{ht.HorizonSession()} - err := q.UpdateLastLedgerIngest(100) + err := q.UpdateLastLedgerIngest(ht.Ctx, 100) ht.Assert.NoError(err) - err = q.UpdateIngestVersion(ingest.CurrentVersion) + err = q.UpdateIngestVersion(ht.Ctx, ingest.CurrentVersion) ht.Assert.NoError(err) - _, err = q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + _, err = q.InsertLedger(ht.Ctx, xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ LedgerSeq: 100, }, diff --git a/services/horizon/internal/actions_data_test.go b/services/horizon/internal/actions_data_test.go index 2c2590af29..137087aedf 100644 --- a/services/horizon/internal/actions_data_test.go +++ b/services/horizon/internal/actions_data_test.go @@ -53,22 +53,22 @@ func TestDataActions_Show(t *testing.T) { q := &history.Q{ht.HorizonSession()} // Makes StateMiddleware happy - err := q.UpdateLastLedgerIngest(100) + err := q.UpdateLastLedgerIngest(ht.Ctx, 100) ht.Assert.NoError(err) - err = q.UpdateIngestVersion(ingest.CurrentVersion) + err = q.UpdateIngestVersion(ht.Ctx, ingest.CurrentVersion) ht.Assert.NoError(err) - _, err = q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + _, err = q.InsertLedger(ht.Ctx, xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ LedgerSeq: 100, }, }, 0, 0, 0, 0, 0) ht.Assert.NoError(err) - rows, err := q.InsertAccountData(data1) + rows, err := q.InsertAccountData(ht.Ctx, data1) assert.NoError(t, err) ht.Assert.Equal(int64(1), rows) - rows, err = q.InsertAccountData(data2) + rows, err = q.InsertAccountData(ht.Ctx, data2) assert.NoError(t, err) ht.Assert.Equal(int64(1), rows) diff --git a/services/horizon/internal/actions_effects_test.go b/services/horizon/internal/actions_effects_test.go index 1a82df7092..176368b1d4 100644 --- a/services/horizon/internal/actions_effects_test.go +++ b/services/horizon/internal/actions_effects_test.go @@ -43,9 +43,9 @@ func TestEffectActions_Index(t *testing.T) { // Makes StateMiddleware happy q := history.Q{ht.HorizonSession()} - err := q.UpdateLastLedgerIngest(3) + err := q.UpdateLastLedgerIngest(ht.Ctx, 3) ht.Assert.NoError(err) - err = q.UpdateIngestVersion(ingest.CurrentVersion) + err = q.UpdateIngestVersion(ht.Ctx, ingest.CurrentVersion) ht.Assert.NoError(err) // checks if empty param returns 404 instead of all payments diff --git a/services/horizon/internal/actions_operation_fee_stats_test.go b/services/horizon/internal/actions_operation_fee_stats_test.go index a4b451200f..c1556dee71 100644 --- a/services/horizon/internal/actions_operation_fee_stats_test.go +++ b/services/horizon/internal/actions_operation_fee_stats_test.go @@ -151,10 +151,10 @@ func TestOperationFeeTestsActions_Show(t *testing.T) { defer ht.Finish() // Update max_tx_set_size on ledgers - _, err := ht.HorizonSession().ExecRaw("UPDATE history_ledgers SET max_tx_set_size = 50") + _, err := ht.HorizonSession().ExecRaw(ht.Ctx, "UPDATE history_ledgers SET max_tx_set_size = 50") ht.Require.NoError(err) - ht.App.UpdateFeeStatsState() + ht.App.UpdateFeeStatsState(ht.Ctx) w := ht.Get("/fee_stats") @@ -205,14 +205,14 @@ func TestOperationFeeTestsActions_ShowMultiOp(t *testing.T) { defer ht.Finish() // Update max_tx_set_size on ledgers - _, err := ht.HorizonSession().ExecRaw("UPDATE history_ledgers SET max_tx_set_size = 50") + _, err := ht.HorizonSession().ExecRaw(ht.Ctx, "UPDATE history_ledgers SET max_tx_set_size = 50") ht.Require.NoError(err) // Update number of ops on each transaction - _, err = ht.HorizonSession().ExecRaw("UPDATE history_transactions SET operation_count = operation_count * 2") + _, err = ht.HorizonSession().ExecRaw(ht.Ctx, "UPDATE history_transactions SET operation_count = operation_count * 2") ht.Require.NoError(err) - ht.App.UpdateFeeStatsState() + ht.App.UpdateFeeStatsState(ht.Ctx) w := ht.Get("/fee_stats") @@ -271,14 +271,14 @@ func TestOperationFeeTestsActions_NotInterpolating(t *testing.T) { defer ht.Finish() // Update max_tx_set_size on ledgers - _, err := ht.HorizonSession().ExecRaw("UPDATE history_ledgers SET max_tx_set_size = 50") + _, err := ht.HorizonSession().ExecRaw(ht.Ctx, "UPDATE history_ledgers SET max_tx_set_size = 50") ht.Require.NoError(err) // Update one tx to a huge fee - _, err = ht.HorizonSession().ExecRaw("UPDATE history_transactions SET max_fee = 256000, operation_count = 16 WHERE transaction_hash = '6a349e7331e93a251367287e274fb1699abaf723bde37aebe96248c76fd3071a'") + _, err = ht.HorizonSession().ExecRaw(ht.Ctx, "UPDATE history_transactions SET max_fee = 256000, operation_count = 16 WHERE transaction_hash = '6a349e7331e93a251367287e274fb1699abaf723bde37aebe96248c76fd3071a'") ht.Require.NoError(err) - ht.App.UpdateFeeStatsState() + ht.App.UpdateFeeStatsState(ht.Ctx) w := ht.Get("/fee_stats") @@ -326,13 +326,13 @@ func TestOperationFeeTestsActions_FeeBump(t *testing.T) { defer ht.Finish() // Update one tx to be a fee bump - result, err := ht.HorizonSession().ExecRaw("UPDATE history_transactions SET max_fee = 10, new_max_fee = 1000, fee_charged = 200 WHERE transaction_hash = '6a349e7331e93a251367287e274fb1699abaf723bde37aebe96248c76fd3071a'") + result, err := ht.HorizonSession().ExecRaw(ht.Ctx, "UPDATE history_transactions SET max_fee = 10, new_max_fee = 1000, fee_charged = 200 WHERE transaction_hash = '6a349e7331e93a251367287e274fb1699abaf723bde37aebe96248c76fd3071a'") ht.Require.NoError(err) rowsAffected, err := result.RowsAffected() ht.Require.NoError(err) ht.Require.Equal(int64(1), rowsAffected) - ht.App.UpdateFeeStatsState() + ht.App.UpdateFeeStatsState(ht.Ctx) w := ht.Get("/fee_stats") diff --git a/services/horizon/internal/actions_operation_test.go b/services/horizon/internal/actions_operation_test.go index de3a37c2f9..f1ab63901a 100644 --- a/services/horizon/internal/actions_operation_test.go +++ b/services/horizon/internal/actions_operation_test.go @@ -169,7 +169,7 @@ func TestOperationActions_Show_Failed(t *testing.T) { } // NULL value - _, err := ht.HorizonSession().ExecRaw( + _, err := ht.HorizonSession().ExecRaw(ht.Ctx, `UPDATE history_transactions SET successful = NULL WHERE transaction_hash = ?`, "56e3216045d579bea40f2d35a09406de3a894ecb5be70dbda5ec9c0427a0d5a1", ) @@ -280,7 +280,7 @@ func TestOperation_CreatedAt(t *testing.T) { l := history.Ledger{} hq := history.Q{Session: ht.HorizonSession()} - ht.Require.NoError(hq.LedgerBySequence(&l, 3)) + ht.Require.NoError(hq.LedgerBySequence(ht.Ctx, &l, 3)) ht.Assert.WithinDuration(l.ClosedAt, records[0].LedgerCloseTime, 1*time.Second) } diff --git a/services/horizon/internal/actions_path_test.go b/services/horizon/internal/actions_path_test.go index cab47284f4..07794d05ce 100644 --- a/services/horizon/internal/actions_path_test.go +++ b/services/horizon/internal/actions_path_test.go @@ -50,11 +50,11 @@ func mockPathFindingClient( router.Use(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { s := session.Clone() - s.BeginTx(&sql.TxOptions{ + s.BeginTx(tt.Ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }) - defer s.Rollback() + defer s.Rollback(tt.Ctx) ctx := context.WithValue( r.Context(), @@ -168,9 +168,9 @@ func TestPathActionsStrictReceive(t *testing.T) { } batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account) + err := batch.Add(tt.Ctx, account) assert.NoError(t, err) - err = batch.Exec() + err = batch.Exec(tt.Ctx) assert.NoError(t, err) assetsByKeys := map[string]xdr.Asset{} @@ -204,7 +204,7 @@ func TestPathActionsStrictReceive(t *testing.T) { }, } - rows, err1 := q.InsertTrustLine(trustline) + rows, err1 := q.InsertTrustLine(tt.Ctx, trustline) assert.NoError(t, err1) assert.Equal(t, int64(1), rows) } @@ -526,9 +526,9 @@ func TestPathActionsStrictSend(t *testing.T) { } batch := historyQ.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account) + err := batch.Add(tt.Ctx, account) assert.NoError(t, err) - err = batch.Exec() + err = batch.Exec(tt.Ctx) assert.NoError(t, err) assetsByKeys := map[string]xdr.Asset{} @@ -562,7 +562,7 @@ func TestPathActionsStrictSend(t *testing.T) { }, } - rows, err := historyQ.InsertTrustLine(trustline) + rows, err := historyQ.InsertTrustLine(tt.Ctx, trustline) assert.NoError(t, err) assert.Equal(t, int64(1), rows) } diff --git a/services/horizon/internal/actions_payment_test.go b/services/horizon/internal/actions_payment_test.go index f96aea04f4..839e8efe9e 100644 --- a/services/horizon/internal/actions_payment_test.go +++ b/services/horizon/internal/actions_payment_test.go @@ -35,9 +35,9 @@ func TestPaymentActions(t *testing.T) { // Makes StateMiddleware happy initializeStateMiddleware := func() { q := history.Q{ht.HorizonSession()} - err := q.UpdateLastLedgerIngest(3) + err := q.UpdateLastLedgerIngest(ht.Ctx, 3) ht.Assert.NoError(err) - err = q.UpdateIngestVersion(ingest.CurrentVersion) + err = q.UpdateIngestVersion(ht.Ctx, ingest.CurrentVersion) ht.Assert.NoError(err) } initializeStateMiddleware() @@ -212,7 +212,7 @@ func TestPaymentActions_Show_Failed(t *testing.T) { } // NULL value - _, err := ht.HorizonSession().ExecRaw( + _, err := ht.HorizonSession().ExecRaw(ht.Ctx, `UPDATE history_transactions SET successful = NULL WHERE transaction_hash = ?`, "56e3216045d579bea40f2d35a09406de3a894ecb5be70dbda5ec9c0427a0d5a1", ) @@ -241,7 +241,7 @@ func TestPayment_CreatedAt(t *testing.T) { l := history.Ledger{} hq := history.Q{Session: ht.HorizonSession()} - ht.Require.NoError(hq.LedgerBySequence(&l, 3)) + ht.Require.NoError(hq.LedgerBySequence(ht.Ctx, &l, 3)) ht.Assert.WithinDuration(l.ClosedAt, records[0].LedgerCloseTime, 1*time.Second) } diff --git a/services/horizon/internal/actions_root_test.go b/services/horizon/internal/actions_root_test.go index 8a7897037f..8066beaa6d 100644 --- a/services/horizon/internal/actions_root_test.go +++ b/services/horizon/internal/actions_root_test.go @@ -28,8 +28,8 @@ func TestRootAction(t *testing.T) { ht.App.config.StellarCoreURL = server.URL ht.App.config.NetworkPassphrase = "test" - ht.App.UpdateStellarCoreInfo() - ht.App.UpdateLedgerState() + ht.App.UpdateStellarCoreInfo(ht.Ctx) + ht.App.UpdateLedgerState(ht.Ctx) w := ht.Get("/") @@ -94,7 +94,7 @@ func TestRootCoreClientInfoErrored(t *testing.T) { defer server.Close() ht.App.config.StellarCoreURL = server.URL - ht.App.UpdateLedgerState() + ht.App.UpdateLedgerState(ht.Ctx) w := ht.Get("/") diff --git a/services/horizon/internal/actions_trade_test.go b/services/horizon/internal/actions_trade_test.go index d86f813ad4..03978d44c5 100644 --- a/services/horizon/internal/actions_trade_test.go +++ b/services/horizon/internal/actions_trade_test.go @@ -36,7 +36,7 @@ func TestTradeActions_Index(t *testing.T) { // ensure created_at is populated correctly l := history.Ledger{} hq := history.Q{Session: ht.HorizonSession()} - ht.Require.NoError(hq.LedgerBySequence(&l, 9)) + ht.Require.NoError(hq.LedgerBySequence(ht.Ctx, &l, 9)) ht.Assert.WithinDuration(l.ClosedAt, records[0].LedgerCloseTime, 1*time.Second) } diff --git a/services/horizon/internal/actions_transaction_test.go b/services/horizon/internal/actions_transaction_test.go index d2f3c9a89c..caefe2846c 100644 --- a/services/horizon/internal/actions_transaction_test.go +++ b/services/horizon/internal/actions_transaction_test.go @@ -145,7 +145,7 @@ func TestTransactionActions_Show_Failed(t *testing.T) { } // NULL value - _, err := ht.HorizonSession().ExecRaw( + _, err := ht.HorizonSession().ExecRaw(ht.Ctx, `UPDATE history_transactions SET successful = NULL WHERE transaction_hash = ?`, "56e3216045d579bea40f2d35a09406de3a894ecb5be70dbda5ec9c0427a0d5a1", ) @@ -193,9 +193,9 @@ func TestTransactionActions_Index(t *testing.T) { // Makes StateMiddleware happy q := history.Q{ht.HorizonSession()} - err := q.UpdateLastLedgerIngest(100) + err := q.UpdateLastLedgerIngest(ht.Ctx, 100) ht.Assert.NoError(err) - err = q.UpdateIngestVersion(ingest.CurrentVersion) + err = q.UpdateIngestVersion(ht.Ctx, ingest.CurrentVersion) ht.Assert.NoError(err) // checks if empty param returns 404 instead of all payments diff --git a/services/horizon/internal/app.go b/services/horizon/internal/app.go index 10bca22743..1aaa529cda 100644 --- a/services/horizon/internal/app.go +++ b/services/horizon/internal/app.go @@ -194,14 +194,14 @@ func (a *App) Ingestion() ingest.System { } // HorizonSession returns a new session that loads data from the horizon -// database. The returned session is bound to `ctx`. -func (a *App) HorizonSession(ctx context.Context) *db.Session { - return &db.Session{DB: a.historyQ.Session.DB, Ctx: ctx} +// database. +func (a *App) HorizonSession() *db.Session { + return &db.Session{DB: a.historyQ.Session.DB} } // UpdateLedgerState triggers a refresh of several metrics gauges, such as open // db connections and ledger state -func (a *App) UpdateLedgerState() { +func (a *App) UpdateLedgerState(ctx context.Context) { var next ledger.Status logErr := func(err error, msg string) { @@ -221,19 +221,19 @@ func (a *App) UpdateLedgerState() { next.CoreLatest = int32(coreInfo.Info.Ledger.Num) next.HistoryLatest, next.HistoryLatestClosedAt, err = - a.HistoryQ().LatestLedgerSequenceClosedAt() + a.HistoryQ().LatestLedgerSequenceClosedAt(ctx) if err != nil { logErr(err, "failed to load the latest known ledger state from history DB") return } - err = a.HistoryQ().ElderLedger(&next.HistoryElder) + err = a.HistoryQ().ElderLedger(ctx, &next.HistoryElder) if err != nil { logErr(err, "failed to load the oldest known ledger state from history DB") return } - next.ExpHistoryLatest, err = a.HistoryQ().GetLastLedgerIngestNonBlocking() + next.ExpHistoryLatest, err = a.HistoryQ().GetLastLedgerIngestNonBlocking(ctx) if err != nil { logErr(err, "failed to load the oldest known exp ledger state from history DB") return @@ -243,7 +243,7 @@ func (a *App) UpdateLedgerState() { } // UpdateFeeStatsState triggers a refresh of several operation fee metrics. -func (a *App) UpdateFeeStatsState() { +func (a *App) UpdateFeeStatsState(ctx context.Context) { var ( next operationfeestats.State latest history.LatestLedger @@ -262,7 +262,7 @@ func (a *App) UpdateFeeStatsState() { cur, ok := operationfeestats.CurrentState() - err := a.HistoryQ().LatestLedgerBaseFeeAndSequence(&latest) + err := a.HistoryQ().LatestLedgerBaseFeeAndSequence(ctx, &latest) if err != nil { logErr(err, "failed to load the latest known ledger's base fee and sequence number") return @@ -276,13 +276,13 @@ func (a *App) UpdateFeeStatsState() { next.LastBaseFee = int64(latest.BaseFee) next.LastLedger = uint32(latest.Sequence) - err = a.HistoryQ().FeeStats(latest.Sequence, &feeStats) + err = a.HistoryQ().FeeStats(ctx, latest.Sequence, &feeStats) if err != nil { logErr(err, "failed to load operation fee stats") return } - err = a.HistoryQ().LedgerCapacityUsageStats(latest.Sequence, &capacityStats) + err = a.HistoryQ().LedgerCapacityUsageStats(ctx, latest.Sequence, &capacityStats) if err != nil { logErr(err, "failed to load ledger capacity usage stats") return @@ -365,7 +365,7 @@ func (a *App) UpdateFeeStatsState() { // UpdateStellarCoreInfo updates the value of CoreVersion, // CurrentProtocolVersion, and CoreSupportedProtocolVersion from the Stellar // core API. -func (a *App) UpdateStellarCoreInfo() { +func (a *App) UpdateStellarCoreInfo(ctx context.Context) { if a.config.StellarCoreURL == "" { return } @@ -374,7 +374,7 @@ func (a *App) UpdateStellarCoreInfo() { URL: a.config.StellarCoreURL, } - resp, err := core.Info(context.Background()) + resp, err := core.Info(ctx) if err != nil { log.Warnf("could not load stellar-core info: %s", err) return @@ -396,8 +396,8 @@ func (a *App) UpdateStellarCoreInfo() { // DeleteUnretainedHistory forwards to the app's reaper. See // `reap.DeleteUnretainedHistory` for details -func (a *App) DeleteUnretainedHistory() error { - return a.reaper.DeleteUnretainedHistory() +func (a *App) DeleteUnretainedHistory(ctx context.Context) error { + return a.reaper.DeleteUnretainedHistory(ctx) } // Tick triggers horizon to update all of it's background processes such as @@ -407,13 +407,13 @@ func (a *App) Tick() { log.Debug("ticking app") // update ledger state, operation fee state, and stellar-core info in parallel wg.Add(3) - go func() { a.UpdateLedgerState(); wg.Done() }() - go func() { a.UpdateFeeStatsState(); wg.Done() }() - go func() { a.UpdateStellarCoreInfo(); wg.Done() }() + go func() { a.UpdateLedgerState(a.ctx); wg.Done() }() + go func() { a.UpdateFeeStatsState(a.ctx); wg.Done() }() + go func() { a.UpdateStellarCoreInfo(a.ctx); wg.Done() }() wg.Wait() wg.Add(2) - go func() { a.reaper.Tick(); wg.Done() }() + go func() { a.reaper.Tick(a.ctx); wg.Done() }() go func() { a.submitter.Tick(a.ctx); wg.Done() }() wg.Wait() @@ -437,7 +437,7 @@ func (a *App) init() error { initLogglyLog(a) // stellarCoreInfo - a.UpdateStellarCoreInfo() + a.UpdateStellarCoreInfo(a.ctx) // horizon-db and core-db mustInitHorizonDB(a) @@ -452,7 +452,7 @@ func (a *App) init() error { initSubmissionSystem(a) // reaper - a.reaper = reap.New(a.config.HistoryRetentionCount, a.HorizonSession(context.Background()), a.ledgerState) + a.reaper = reap.New(a.config.HistoryRetentionCount, a.HorizonSession(), a.ledgerState) // metrics and log.metrics a.prometheusRegistry = prometheus.NewRegistry() diff --git a/services/horizon/internal/db2/assets/asset_stat_test.go b/services/horizon/internal/db2/assets/asset_stat_test.go index 9408d10b60..c7ef50fe90 100644 --- a/services/horizon/internal/db2/assets/asset_stat_test.go +++ b/services/horizon/internal/db2/assets/asset_stat_test.go @@ -1,6 +1,7 @@ package assets import ( + "context" "strconv" "testing" @@ -91,7 +92,7 @@ func TestAssetsStatsQExec(t *testing.T) { tt.Require.NoError(err) var results []AssetStatsR - err = history.Q{Session: tt.HorizonSession()}.Select(&results, sql) + err = history.Q{Session: tt.HorizonSession()}.Select(context.Background(), &results, sql) tt.Require.NoError(err) if !tt.Assert.Equal(3, len(results)) { return diff --git a/services/horizon/internal/db2/history/account.go b/services/horizon/internal/db2/history/account.go index 6bd10e3487..6f5c921ea8 100644 --- a/services/horizon/internal/db2/history/account.go +++ b/services/horizon/internal/db2/history/account.go @@ -1,6 +1,7 @@ package history import ( + "context" "sort" sq "github.com/Masterminds/squirrel" @@ -10,22 +11,22 @@ import ( ) // AccountByAddress loads a row from `history_accounts`, by address -func (q *Q) AccountByAddress(dest interface{}, addy string) error { +func (q *Q) AccountByAddress(ctx context.Context, dest interface{}, addy string) error { sql := selectAccount.Limit(1).Where("ha.address = ?", addy) - return q.Get(dest, sql) + return q.Get(ctx, dest, sql) } // AccountsByAddresses loads a rows from `history_accounts`, by addresses -func (q *Q) AccountsByAddresses(dest interface{}, addresses []string) error { +func (q *Q) AccountsByAddresses(ctx context.Context, dest interface{}, addresses []string) error { sql := selectAccount.Where(map[string]interface{}{ "ha.address": addresses, // ha.address IN (...) }) - return q.Select(dest, sql) + return q.Select(ctx, dest, sql) } // CreateAccounts creates rows in the history_accounts table for a given list of addresses. // CreateAccounts returns a mapping of account address to its corresponding id in the history_accounts table -func (q *Q) CreateAccounts(addresses []string, batchSize int) (map[string]int64, error) { +func (q *Q) CreateAccounts(ctx context.Context, addresses []string, batchSize int) (map[string]int64, error) { builder := &db.BatchInsertBuilder{ Table: q.GetTable("history_accounts"), MaxBatchSize: batchSize, @@ -36,7 +37,7 @@ func (q *Q) CreateAccounts(addresses []string, batchSize int) (map[string]int64, // https://github.com/stellar/go/issues/2370 sort.Strings(addresses) for _, address := range addresses { - err := builder.Row(map[string]interface{}{ + err := builder.Row(ctx, map[string]interface{}{ "address": address, }) if err != nil { @@ -44,7 +45,7 @@ func (q *Q) CreateAccounts(addresses []string, batchSize int) (map[string]int64, } } - err := builder.Exec() + err := builder.Exec(ctx) if err != nil { return nil, errors.Wrap(err, "could not exec asset insert builder") } @@ -60,7 +61,7 @@ func (q *Q) CreateAccounts(addresses []string, batchSize int) (map[string]int64, } subset := addresses[i:end] - if err := q.AccountsByAddresses(&accounts, subset); err != nil { + if err := q.AccountsByAddresses(ctx, &accounts, subset); err != nil { return nil, errors.Wrap(err, "could not select accounts") } diff --git a/services/horizon/internal/db2/history/account_data.go b/services/horizon/internal/db2/history/account_data.go index 827e2be72c..290d686156 100644 --- a/services/horizon/internal/db2/history/account_data.go +++ b/services/horizon/internal/db2/history/account_data.go @@ -1,6 +1,7 @@ package history import ( + "context" "encoding/base64" sq "github.com/Masterminds/squirrel" @@ -8,11 +9,11 @@ import ( "github.com/stellar/go/xdr" ) -func (q *Q) CountAccountsData() (int, error) { +func (q *Q) CountAccountsData(ctx context.Context) (int, error) { sql := sq.Select("count(*)").From("accounts_data") var count int - if err := q.Get(&count, sql); err != nil { + if err := q.Get(ctx, &count, sql); err != nil { return 0, errors.Wrap(err, "could not run select query") } @@ -20,26 +21,26 @@ func (q *Q) CountAccountsData() (int, error) { } // GetAccountDataByName loads account data for a given account ID and data name -func (q *Q) GetAccountDataByName(id, name string) (Data, error) { +func (q *Q) GetAccountDataByName(ctx context.Context, id, name string) (Data, error) { var data Data sql := selectAccountData.Where(sq.Eq{ "account_id": id, "name": name, }).Limit(1) - err := q.Get(&data, sql) + err := q.Get(ctx, &data, sql) return data, err } // GetAccountDataByAccountID loads account data for a given account ID -func (q *Q) GetAccountDataByAccountID(id string) ([]Data, error) { +func (q *Q) GetAccountDataByAccountID(ctx context.Context, id string) ([]Data, error) { var data []Data sql := selectAccountData.Where(sq.Eq{"account_id": id}) - err := q.Select(&data, sql) + err := q.Select(ctx, &data, sql) return data, err } // GetAccountDataByKeys loads a row from the `accounts_data` table, selected by multiple keys. -func (q *Q) GetAccountDataByKeys(keys []xdr.LedgerKeyData) ([]Data, error) { +func (q *Q) GetAccountDataByKeys(ctx context.Context, keys []xdr.LedgerKeyData) ([]Data, error) { var data []Data lkeys := make([]string, 0, len(keys)) for _, key := range keys { @@ -50,7 +51,7 @@ func (q *Q) GetAccountDataByKeys(keys []xdr.LedgerKeyData) ([]Data, error) { lkeys = append(lkeys, lkey) } sql := selectAccountData.Where(map[string]interface{}{"accounts_data.ledger_key": lkeys}) - err := q.Select(&data, sql) + err := q.Select(ctx, &data, sql) return data, err } @@ -80,7 +81,7 @@ func dataEntryToLedgerKeyString(entry xdr.LedgerEntry) (string, error) { // InsertAccountData creates a row in the accounts_data table. // Returns number of rows affected and error. -func (q *Q) InsertAccountData(entry xdr.LedgerEntry) (int64, error) { +func (q *Q) InsertAccountData(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { data := entry.Data.MustData() // Add lkey only when inserting rows @@ -100,7 +101,7 @@ func (q *Q) InsertAccountData(entry xdr.LedgerEntry) (int64, error) { ledgerEntrySponsorToNullString(entry), ) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -110,7 +111,7 @@ func (q *Q) InsertAccountData(entry xdr.LedgerEntry) (int64, error) { // UpdateAccountData updates a row in the accounts_data table. // Returns number of rows affected and error. -func (q *Q) UpdateAccountData(entry xdr.LedgerEntry) (int64, error) { +func (q *Q) UpdateAccountData(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { data := entry.Data.MustData() key, err := dataEntryToLedgerKeyString(entry) @@ -124,7 +125,7 @@ func (q *Q) UpdateAccountData(entry xdr.LedgerEntry) (int64, error) { "sponsor": ledgerEntrySponsorToNullString(entry), }). Where(sq.Eq{"ledger_key": key}) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -134,7 +135,7 @@ func (q *Q) UpdateAccountData(entry xdr.LedgerEntry) (int64, error) { // RemoveAccountData deletes a row in the accounts_data table. // Returns number of rows affected and error. -func (q *Q) RemoveAccountData(key xdr.LedgerKeyData) (int64, error) { +func (q *Q) RemoveAccountData(ctx context.Context, key xdr.LedgerKeyData) (int64, error) { lkey, err := ledgerKeyDataToString(key) if err != nil { return 0, errors.Wrap(err, "Error running ledgerKeyDataToString") @@ -142,7 +143,7 @@ func (q *Q) RemoveAccountData(key xdr.LedgerKeyData) (int64, error) { sql := sq.Delete("accounts_data"). Where(sq.Eq{"ledger_key": lkey}) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -151,10 +152,10 @@ func (q *Q) RemoveAccountData(key xdr.LedgerKeyData) (int64, error) { } // GetAccountDataByAccountsID loads account data for a list of account ID -func (q *Q) GetAccountDataByAccountsID(id []string) ([]Data, error) { +func (q *Q) GetAccountDataByAccountsID(ctx context.Context, id []string) ([]Data, error) { var data []Data sql := selectAccountData.Where(sq.Eq{"account_id": id}) - err := q.Select(&data, sql) + err := q.Select(ctx, &data, sql) return data, err } diff --git a/services/horizon/internal/db2/history/account_data_batch_insert_builder.go b/services/horizon/internal/db2/history/account_data_batch_insert_builder.go index e1a1e6f38b..be3ac4c24e 100644 --- a/services/horizon/internal/db2/history/account_data_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/account_data_batch_insert_builder.go @@ -1,11 +1,13 @@ package history import ( + "context" + "github.com/stellar/go/support/errors" "github.com/stellar/go/xdr" ) -func (i *accountDataBatchInsertBuilder) Add(entry xdr.LedgerEntry) error { +func (i *accountDataBatchInsertBuilder) Add(ctx context.Context, entry xdr.LedgerEntry) error { data := entry.Data.MustData() // Add ledger_key only when inserting rows key, err := dataEntryToLedgerKeyString(entry) @@ -13,7 +15,7 @@ func (i *accountDataBatchInsertBuilder) Add(entry xdr.LedgerEntry) error { return errors.Wrap(err, "Error running dataEntryToLedgerKeyString") } - return i.builder.Row(map[string]interface{}{ + return i.builder.Row(ctx, map[string]interface{}{ "ledger_key": key, "account_id": data.AccountId.Address(), "name": data.DataName, @@ -23,6 +25,6 @@ func (i *accountDataBatchInsertBuilder) Add(entry xdr.LedgerEntry) error { }) } -func (i *accountDataBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *accountDataBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/account_data_batch_insert_builder_test.go b/services/horizon/internal/db2/history/account_data_batch_insert_builder_test.go index 4920532819..6198281398 100644 --- a/services/horizon/internal/db2/history/account_data_batch_insert_builder_test.go +++ b/services/horizon/internal/db2/history/account_data_batch_insert_builder_test.go @@ -35,13 +35,13 @@ func TestDataBatchInsertBuilderAdd(t *testing.T) { builder := q.NewAccountDataBatchInsertBuilder(2) - err := builder.Add(entry) + err := builder.Add(tt.Ctx, entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) - record, err := q.GetAccountDataByName(accountID.Address(), "foo") + record, err := q.GetAccountDataByName(tt.Ctx, accountID.Address(), "foo") tt.Assert.NoError(err) tt.Assert.Equal(data.DataName, xdr.String64(record.Name)) diff --git a/services/horizon/internal/db2/history/account_data_test.go b/services/horizon/internal/db2/history/account_data_test.go index a8482da55f..9300f024b7 100644 --- a/services/horizon/internal/db2/history/account_data_test.go +++ b/services/horizon/internal/db2/history/account_data_test.go @@ -47,11 +47,11 @@ func TestInsertAccountData(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - rows, err := q.InsertAccountData(data1) + rows, err := q.InsertAccountData(tt.Ctx, data1) assert.NoError(t, err) tt.Assert.Equal(int64(1), rows) - rows, err = q.InsertAccountData(data2) + rows, err = q.InsertAccountData(tt.Ctx, data2) assert.NoError(t, err) tt.Assert.Equal(int64(1), rows) @@ -60,7 +60,7 @@ func TestInsertAccountData(t *testing.T) { {AccountId: data2.Data.Data.AccountId, DataName: data2.Data.Data.DataName}, } - datas, err := q.GetAccountDataByKeys(keys) + datas, err := q.GetAccountDataByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, datas, 2) @@ -79,21 +79,21 @@ func TestUpdateAccountData(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - rows, err := q.InsertAccountData(data1) + rows, err := q.InsertAccountData(tt.Ctx, data1) assert.NoError(t, err) tt.Assert.Equal(int64(1), rows) modifiedData := data1 modifiedData.Data.Data.DataValue[0] = 1 - rows, err = q.UpdateAccountData(modifiedData) + rows, err = q.UpdateAccountData(tt.Ctx, modifiedData) assert.NoError(t, err) tt.Assert.Equal(int64(1), rows) keys := []xdr.LedgerKeyData{ {AccountId: data1.Data.Data.AccountId, DataName: data1.Data.Data.DataName}, } - datas, err := q.GetAccountDataByKeys(keys) + datas, err := q.GetAccountDataByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, datas, 1) @@ -108,21 +108,21 @@ func TestRemoveAccountData(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - rows, err := q.InsertAccountData(data1) + rows, err := q.InsertAccountData(tt.Ctx, data1) assert.NoError(t, err) tt.Assert.Equal(int64(1), rows) key := xdr.LedgerKeyData{AccountId: data1.Data.Data.AccountId, DataName: data1.Data.Data.DataName} - rows, err = q.RemoveAccountData(key) + rows, err = q.RemoveAccountData(tt.Ctx, key) assert.NoError(t, err) tt.Assert.Equal(int64(1), rows) - datas, err := q.GetAccountDataByKeys([]xdr.LedgerKeyData{key}) + datas, err := q.GetAccountDataByKeys(tt.Ctx, []xdr.LedgerKeyData{key}) assert.NoError(t, err) assert.Len(t, datas, 0) // Doesn't exist anymore - rows, err = q.RemoveAccountData(key) + rows, err = q.RemoveAccountData(tt.Ctx, key) assert.NoError(t, err) tt.Assert.Equal(int64(0), rows) } @@ -133,16 +133,16 @@ func TestGetAccountDataByAccountsID(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, err := q.InsertAccountData(data1) + _, err := q.InsertAccountData(tt.Ctx, data1) assert.NoError(t, err) - _, err = q.InsertAccountData(data2) + _, err = q.InsertAccountData(tt.Ctx, data2) assert.NoError(t, err) ids := []string{ data1.Data.Data.AccountId.Address(), data2.Data.Data.AccountId.Address(), } - datas, err := q.GetAccountDataByAccountsID(ids) + datas, err := q.GetAccountDataByAccountsID(tt.Ctx, ids) assert.NoError(t, err) assert.Len(t, datas, 2) @@ -159,12 +159,12 @@ func TestGetAccountDataByAccountID(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, err := q.InsertAccountData(data1) + _, err := q.InsertAccountData(tt.Ctx, data1) assert.NoError(t, err) - _, err = q.InsertAccountData(data2) + _, err = q.InsertAccountData(tt.Ctx, data2) assert.NoError(t, err) - records, err := q.GetAccountDataByAccountID(data1.Data.Data.AccountId.Address()) + records, err := q.GetAccountDataByAccountID(tt.Ctx, data1.Data.Data.AccountId.Address()) assert.NoError(t, err) assert.Len(t, records, 2) @@ -181,17 +181,17 @@ func TestGetAccountDataByName(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, err := q.InsertAccountData(data1) + _, err := q.InsertAccountData(tt.Ctx, data1) assert.NoError(t, err) - _, err = q.InsertAccountData(data2) + _, err = q.InsertAccountData(tt.Ctx, data2) assert.NoError(t, err) - record, err := q.GetAccountDataByName(data1.Data.Data.AccountId.Address(), string(data1.Data.Data.DataName)) + record, err := q.GetAccountDataByName(tt.Ctx, data1.Data.Data.AccountId.Address(), string(data1.Data.Data.DataName)) assert.NoError(t, err) tt.Assert.Equal(data1.Data.Data.DataName, xdr.String64(record.Name)) tt.Assert.Equal([]byte(data1.Data.Data.DataValue), []byte(record.Value)) - record, err = q.GetAccountDataByName(data1.Data.Data.AccountId.Address(), string(data2.Data.Data.DataName)) + record, err = q.GetAccountDataByName(tt.Ctx, data1.Data.Data.AccountId.Address(), string(data2.Data.Data.DataName)) assert.NoError(t, err) tt.Assert.Equal(data2.Data.Data.DataName, xdr.String64(record.Name)) tt.Assert.Equal([]byte(data2.Data.Data.DataValue), []byte(record.Value)) diff --git a/services/horizon/internal/db2/history/account_signers.go b/services/horizon/internal/db2/history/account_signers.go index bcc6b00cf1..32c6cdc583 100644 --- a/services/horizon/internal/db2/history/account_signers.go +++ b/services/horizon/internal/db2/history/account_signers.go @@ -1,31 +1,33 @@ package history import ( + "context" + sq "github.com/Masterminds/squirrel" "github.com/stellar/go/services/horizon/internal/db2" "github.com/stellar/go/support/errors" ) -func (q *Q) GetAccountSignersByAccountID(id string) ([]AccountSigner, error) { +func (q *Q) GetAccountSignersByAccountID(ctx context.Context, id string) ([]AccountSigner, error) { sql := selectAccountSigners. Where(sq.Eq{"accounts_signers.account_id": id}). OrderBy("accounts_signers.signer asc") var results []AccountSigner - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } return results, nil } -func (q *Q) SignersForAccounts(accounts []string) ([]AccountSigner, error) { +func (q *Q) SignersForAccounts(ctx context.Context, accounts []string) ([]AccountSigner, error) { sql := selectAccountSigners. Where(map[string]interface{}{"accounts_signers.account_id": accounts}) var results []AccountSigner - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } @@ -33,7 +35,7 @@ func (q *Q) SignersForAccounts(accounts []string) ([]AccountSigner, error) { } // AccountsForSigner returns a list of `AccountSigner` rows for a given signer -func (q *Q) AccountsForSigner(signer string, page db2.PageQuery) ([]AccountSigner, error) { +func (q *Q) AccountsForSigner(ctx context.Context, signer string, page db2.PageQuery) ([]AccountSigner, error) { sql := selectAccountSigners.Where("accounts_signers.signer = ?", signer) sql, err := page.ApplyToUsingCursor(sql, "accounts_signers.account_id", page.Cursor) if err != nil { @@ -41,7 +43,7 @@ func (q *Q) AccountsForSigner(signer string, page db2.PageQuery) ([]AccountSigne } var results []AccountSigner - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } @@ -50,12 +52,12 @@ func (q *Q) AccountsForSigner(signer string, page db2.PageQuery) ([]AccountSigne // CreateAccountSigner creates a row in the accounts_signers table. // Returns number of rows affected and error. -func (q *Q) CreateAccountSigner(account, signer string, weight int32, sponsor *string) (int64, error) { +func (q *Q) CreateAccountSigner(ctx context.Context, account, signer string, weight int32, sponsor *string) (int64, error) { sql := sq.Insert("accounts_signers"). Columns("account_id", "signer", "weight", "sponsor"). Values(account, signer, weight, sponsor) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -65,13 +67,13 @@ func (q *Q) CreateAccountSigner(account, signer string, weight int32, sponsor *s // RemoveAccountSigner deletes a row in the accounts_signers table. // Returns number of rows affected and error. -func (q *Q) RemoveAccountSigner(account, signer string) (int64, error) { +func (q *Q) RemoveAccountSigner(ctx context.Context, account, signer string) (int64, error) { sql := sq.Delete("accounts_signers").Where(sq.Eq{ "account_id": account, "signer": signer, }) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } diff --git a/services/horizon/internal/db2/history/account_signers_batch_insert_builder.go b/services/horizon/internal/db2/history/account_signers_batch_insert_builder.go index 203b84288b..fd1cab291c 100644 --- a/services/horizon/internal/db2/history/account_signers_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/account_signers_batch_insert_builder.go @@ -1,7 +1,11 @@ package history -func (i *accountSignersBatchInsertBuilder) Add(signer AccountSigner) error { - return i.builder.Row(map[string]interface{}{ +import ( + "context" +) + +func (i *accountSignersBatchInsertBuilder) Add(ctx context.Context, signer AccountSigner) error { + return i.builder.Row(ctx, map[string]interface{}{ "account_id": signer.Account, "signer": signer.Signer, "weight": signer.Weight, @@ -9,6 +13,6 @@ func (i *accountSignersBatchInsertBuilder) Add(signer AccountSigner) error { }) } -func (i *accountSignersBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *accountSignersBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/account_signers_test.go b/services/horizon/internal/db2/history/account_signers_test.go index 31d2ea87c5..bf4183396b 100644 --- a/services/horizon/internal/db2/history/account_signers_test.go +++ b/services/horizon/internal/db2/history/account_signers_test.go @@ -15,7 +15,7 @@ func TestQueryEmptyAccountSigners(t *testing.T) { q := &Q{tt.HorizonSession()} signer := "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO0" - results, err := q.AccountsForSigner(signer, db2.PageQuery{Order: "asc", Limit: 10}) + results, err := q.AccountsForSigner(tt.Ctx, signer, db2.PageQuery{Order: "asc", Limit: 10}) tt.Assert.NoError(err) tt.Assert.Len(results, 0) } @@ -29,7 +29,7 @@ func TestInsertAccountSigner(t *testing.T) { account := "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2" signer := "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4" weight := int32(123) - rowsAffected, err := q.CreateAccountSigner(account, signer, weight, nil) + rowsAffected, err := q.CreateAccountSigner(tt.Ctx, account, signer, weight, nil) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), rowsAffected) @@ -38,13 +38,13 @@ func TestInsertAccountSigner(t *testing.T) { Signer: signer, Weight: weight, } - results, err := q.AccountsForSigner(signer, db2.PageQuery{Order: "asc", Limit: 10}) + results, err := q.AccountsForSigner(tt.Ctx, signer, db2.PageQuery{Order: "asc", Limit: 10}) tt.Assert.NoError(err) tt.Assert.Len(results, 1) tt.Assert.Equal(expected, results[0]) weight = 321 - _, err = q.CreateAccountSigner(account, signer, weight, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account, signer, weight, nil) tt.Assert.Error(err) tt.Assert.EqualError(err, `exec failed: pq: duplicate key value violates unique constraint "accounts_signers_pkey"`) } @@ -59,7 +59,7 @@ func TestInsertAccountSignerSponsor(t *testing.T) { signer := "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4" weight := int32(123) sponsor := "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H" - rowsAffected, err := q.CreateAccountSigner(account, signer, weight, &sponsor) + rowsAffected, err := q.CreateAccountSigner(tt.Ctx, account, signer, weight, &sponsor) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), rowsAffected) @@ -69,7 +69,7 @@ func TestInsertAccountSignerSponsor(t *testing.T) { Weight: weight, Sponsor: null.StringFrom(sponsor), } - results, err := q.AccountsForSigner(signer, db2.PageQuery{Order: "asc", Limit: 10}) + results, err := q.AccountsForSigner(tt.Ctx, signer, db2.PageQuery{Order: "asc", Limit: 10}) tt.Assert.NoError(err) tt.Assert.Len(results, 1) tt.Assert.Equal(expected, results[0]) @@ -84,13 +84,13 @@ func TestMultipleAccountsForSigner(t *testing.T) { account := "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH1" signer := "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO2" weight := int32(123) - rowsAffected, err := q.CreateAccountSigner(account, signer, weight, nil) + rowsAffected, err := q.CreateAccountSigner(tt.Ctx, account, signer, weight, nil) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), rowsAffected) anotherAccount := "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H" anotherWeight := int32(321) - rowsAffected, err = q.CreateAccountSigner(anotherAccount, signer, anotherWeight, nil) + rowsAffected, err = q.CreateAccountSigner(tt.Ctx, anotherAccount, signer, anotherWeight, nil) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), rowsAffected) @@ -106,7 +106,7 @@ func TestMultipleAccountsForSigner(t *testing.T) { Weight: anotherWeight, }, } - results, err := q.AccountsForSigner(signer, db2.PageQuery{Order: "asc", Limit: 10}) + results, err := q.AccountsForSigner(tt.Ctx, signer, db2.PageQuery{Order: "asc", Limit: 10}) tt.Assert.NoError(err) tt.Assert.Len(results, 2) tt.Assert.Equal(expected, results) @@ -120,7 +120,7 @@ func TestRemoveNonExistantAccountSigner(t *testing.T) { account := "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH3" signer := "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO5" - rowsAffected, err := q.RemoveAccountSigner(account, signer) + rowsAffected, err := q.RemoveAccountSigner(tt.Ctx, account, signer) tt.Assert.NoError(err) tt.Assert.Equal(int64(0), rowsAffected) } @@ -134,7 +134,7 @@ func TestRemoveAccountSigner(t *testing.T) { account := "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH6" signer := "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO7" weight := int32(123) - _, err := q.CreateAccountSigner(account, signer, weight, nil) + _, err := q.CreateAccountSigner(tt.Ctx, account, signer, weight, nil) tt.Assert.NoError(err) expected := AccountSigner{ @@ -142,16 +142,16 @@ func TestRemoveAccountSigner(t *testing.T) { Signer: signer, Weight: weight, } - results, err := q.AccountsForSigner(signer, db2.PageQuery{Order: "asc", Limit: 10}) + results, err := q.AccountsForSigner(tt.Ctx, signer, db2.PageQuery{Order: "asc", Limit: 10}) tt.Assert.NoError(err) tt.Assert.Len(results, 1) tt.Assert.Equal(expected, results[0]) - rowsAffected, err := q.RemoveAccountSigner(account, signer) + rowsAffected, err := q.RemoveAccountSigner(tt.Ctx, account, signer) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), rowsAffected) - results, err = q.AccountsForSigner(signer, db2.PageQuery{Order: "asc", Limit: 10}) + results, err = q.AccountsForSigner(tt.Ctx, signer, db2.PageQuery{Order: "asc", Limit: 10}) tt.Assert.NoError(err) tt.Assert.Len(results, 0) } @@ -165,13 +165,13 @@ func TestGetAccountSignersByAccountID(t *testing.T) { account := "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH6" signer := "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO7" weight := int32(123) - _, err := q.CreateAccountSigner(account, signer, weight, nil) + _, err := q.CreateAccountSigner(tt.Ctx, account, signer, weight, nil) tt.Assert.NoError(err) signer2 := "GC2WJF6YWMAEHGGAK2UOMZCIOMH4RU7KY2CQEWZQJV2ZQJVXJ335ZSXG" weight2 := int32(100) sponsor := "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H" - _, err = q.CreateAccountSigner(account, signer2, weight2, &sponsor) + _, err = q.CreateAccountSigner(tt.Ctx, account, signer2, weight2, &sponsor) tt.Assert.NoError(err) expected := []AccountSigner{ @@ -187,7 +187,7 @@ func TestGetAccountSignersByAccountID(t *testing.T) { Sponsor: null.StringFrom(sponsor), }, } - results, err := q.GetAccountSignersByAccountID(account) + results, err := q.GetAccountSignersByAccountID(tt.Ctx, account) tt.Assert.NoError(err) tt.Assert.Len(results, 2) tt.Assert.Equal(expected, results) diff --git a/services/horizon/internal/db2/history/account_test.go b/services/horizon/internal/db2/history/account_test.go index 1e69aea215..c74571c4b6 100644 --- a/services/horizon/internal/db2/history/account_test.go +++ b/services/horizon/internal/db2/history/account_test.go @@ -60,7 +60,7 @@ func TestCreateAccountsSortedOrder(t *testing.T) { "GBYSBDAJZMHL5AMD7QXQ3JEP3Q4GLKADWIJURAAHQALNAWD6Z5XF2RAC", "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB", } - accounts, err := q.CreateAccounts(addresses, 1) + accounts, err := q.CreateAccounts(tt.Ctx, addresses, 1) tt.Assert.NoError(err) idToAddress := map[int64]string{} @@ -93,12 +93,12 @@ func TestCreateAccounts(t *testing.T) { "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB", "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H", } - accounts, err := q.CreateAccounts(addresses, 1) + accounts, err := q.CreateAccounts(tt.Ctx, addresses, 1) tt.Assert.NoError(err) tt.Assert.Len(accounts, 2) assertAccountsContainAddresses(tt, accounts, addresses) - dupAccounts, err := q.CreateAccounts([]string{ + dupAccounts, err := q.CreateAccounts(tt.Ctx, []string{ "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB", "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H", }, 2) @@ -111,7 +111,7 @@ func TestCreateAccounts(t *testing.T) { "GCYVFGI3SEQJGBNQQG7YCMFWEYOHK3XPVOVPA6C566PXWN4SN7LILZSM", "GBYSBDAJZMHL5AMD7QXQ3JEP3Q4GLKADWIJURAAHQALNAWD6Z5XF2RAC", } - accounts, err = q.CreateAccounts(addresses, 1) + accounts, err = q.CreateAccounts(tt.Ctx, addresses, 1) tt.Assert.NoError(err) assertAccountsContainAddresses(tt, accounts, addresses) for address, accountID := range dupAccounts { diff --git a/services/horizon/internal/db2/history/accounts.go b/services/horizon/internal/db2/history/accounts.go index 250139dcce..73cb182618 100644 --- a/services/horizon/internal/db2/history/accounts.go +++ b/services/horizon/internal/db2/history/accounts.go @@ -1,6 +1,8 @@ package history import ( + "context" + sq "github.com/Masterminds/squirrel" "github.com/guregu/null" "github.com/lib/pq" @@ -34,28 +36,28 @@ func (account AccountEntry) IsAuthClawbackEnabled() bool { return xdr.AccountFlags(account.Flags).IsAuthClawbackEnabled() } -func (q *Q) CountAccounts() (int, error) { +func (q *Q) CountAccounts(ctx context.Context) (int, error) { sql := sq.Select("count(*)").From("accounts") var count int - if err := q.Get(&count, sql); err != nil { + if err := q.Get(ctx, &count, sql); err != nil { return 0, errors.Wrap(err, "could not run select query") } return count, nil } -func (q *Q) GetAccountByID(id string) (AccountEntry, error) { +func (q *Q) GetAccountByID(ctx context.Context, id string) (AccountEntry, error) { var account AccountEntry sql := selectAccounts.Where(sq.Eq{"account_id": id}) - err := q.Get(&account, sql) + err := q.Get(ctx, &account, sql) return account, err } -func (q *Q) GetAccountsByIDs(ids []string) ([]AccountEntry, error) { +func (q *Q) GetAccountsByIDs(ctx context.Context, ids []string) ([]AccountEntry, error) { var accounts []AccountEntry sql := selectAccounts.Where(map[string]interface{}{"accounts.account_id": ids}) - err := q.Select(&accounts, sql) + err := q.Select(ctx, &accounts, sql) return accounts, err } @@ -93,7 +95,7 @@ func accountToMap(entry xdr.LedgerEntry) map[string]interface{} { // There's currently no limit of the number of accounts this method can // accept other than 2GB limit of the query string length what should be enough // for each ledger with the current limits. -func (q *Q) UpsertAccounts(accounts []xdr.LedgerEntry) error { +func (q *Q) UpsertAccounts(ctx context.Context, accounts []xdr.LedgerEntry) error { var accountID, inflationDestination []string var homeDomain []xdr.String32 var balance, buyingLiabilities, sellingLiabilities []xdr.Int64 @@ -187,7 +189,9 @@ func (q *Q) UpsertAccounts(accounts []xdr.LedgerEntry) error { num_sponsored = excluded.num_sponsored, num_sponsoring = excluded.num_sponsoring` - _, err := q.ExecRaw(sql, + _, err := q.ExecRaw( + ctx, + sql, pq.Array(accountID), pq.Array(balance), pq.Array(buyingLiabilities), @@ -211,9 +215,9 @@ func (q *Q) UpsertAccounts(accounts []xdr.LedgerEntry) error { // RemoveAccount deletes a row in the accounts table. // Returns number of rows affected and error. -func (q *Q) RemoveAccount(accountID string) (int64, error) { +func (q *Q) RemoveAccount(ctx context.Context, accountID string) (int64, error) { sql := sq.Delete("accounts").Where(sq.Eq{"account_id": accountID}) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -223,7 +227,7 @@ func (q *Q) RemoveAccount(accountID string) (int64, error) { // AccountsForAsset returns a list of `AccountEntry` rows who are trustee to an // asset -func (q *Q) AccountsForAsset(asset xdr.Asset, page db2.PageQuery) ([]AccountEntry, error) { +func (q *Q) AccountsForAsset(ctx context.Context, asset xdr.Asset, page db2.PageQuery) ([]AccountEntry, error) { var assetType, code, issuer string asset.MustExtract(&assetType, &code, &issuer) @@ -243,7 +247,7 @@ func (q *Q) AccountsForAsset(asset xdr.Asset, page db2.PageQuery) ([]AccountEntr } var results []AccountEntry - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } @@ -296,7 +300,7 @@ func selectUnionBySponsor(tables []string, sponsor string, page db2.PageQuery) ( // AccountsForSponsor return all the accounts where `sponsor`` is sponsoring the account entry or // any of its subentries (trust lines, signers, data, or account entry) -func (q *Q) AccountsForSponsor(sponsor string, page db2.PageQuery) ([]AccountEntry, error) { +func (q *Q) AccountsForSponsor(ctx context.Context, sponsor string, page db2.PageQuery) ([]AccountEntry, error) { sql, err := selectUnionBySponsor( []string{"accounts", "accounts_data", "accounts_signers", "trust_lines"}, sponsor, @@ -307,7 +311,7 @@ func (q *Q) AccountsForSponsor(sponsor string, page db2.PageQuery) ([]AccountEnt } var results []AccountEntry - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } @@ -315,7 +319,7 @@ func (q *Q) AccountsForSponsor(sponsor string, page db2.PageQuery) ([]AccountEnt } // AccountEntriesForSigner returns a list of `AccountEntry` rows for a given signer -func (q *Q) AccountEntriesForSigner(signer string, page db2.PageQuery) ([]AccountEntry, error) { +func (q *Q) AccountEntriesForSigner(ctx context.Context, signer string, page db2.PageQuery) ([]AccountEntry, error) { sql := sq. Select("accounts.*"). From("accounts"). @@ -330,7 +334,7 @@ func (q *Q) AccountEntriesForSigner(signer string, page db2.PageQuery) ([]Accoun } var results []AccountEntry - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } diff --git a/services/horizon/internal/db2/history/accounts_batch_insert_builder.go b/services/horizon/internal/db2/history/accounts_batch_insert_builder.go index b3ed471674..7c4e0abddc 100644 --- a/services/horizon/internal/db2/history/accounts_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/accounts_batch_insert_builder.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stellar/go/support/db" "github.com/stellar/go/xdr" ) @@ -10,10 +12,10 @@ type accountsBatchInsertBuilder struct { builder db.BatchInsertBuilder } -func (i *accountsBatchInsertBuilder) Add(entry xdr.LedgerEntry) error { - return i.builder.Row(accountToMap(entry)) +func (i *accountsBatchInsertBuilder) Add(ctx context.Context, entry xdr.LedgerEntry) error { + return i.builder.Row(ctx, accountToMap(entry)) } -func (i *accountsBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *accountsBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/accounts_test.go b/services/horizon/internal/db2/history/accounts_test.go index b2eca16453..c8a6f0b2da 100644 --- a/services/horizon/internal/db2/history/accounts_test.go +++ b/services/horizon/internal/db2/history/accounts_test.go @@ -111,13 +111,13 @@ func TestInsertAccount(t *testing.T) { q := &Q{tt.HorizonSession()} batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - accounts, err := q.GetAccountsByIDs([]string{ + accounts, err := q.GetAccountsByIDs(tt.Ctx, []string{ "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB", "GCT2NQM5KJJEF55NPMY444C6M6CA7T33HRNCMA6ZFBIIXKNCRO6J25K7", }) @@ -153,7 +153,7 @@ func TestUpsertAccount(t *testing.T) { q := &Q{tt.HorizonSession()} ledgerEntries := []xdr.LedgerEntry{account1, account2} - err := q.UpsertAccounts(ledgerEntries) + err := q.UpsertAccounts(tt.Ctx, ledgerEntries) assert.NoError(t, err) modifiedAccount := xdr.LedgerEntry{ @@ -182,14 +182,14 @@ func TestUpsertAccount(t *testing.T) { }, } - err = q.UpsertAccounts([]xdr.LedgerEntry{modifiedAccount}) + err = q.UpsertAccounts(tt.Ctx, []xdr.LedgerEntry{modifiedAccount}) assert.NoError(t, err) keys := []string{ account1.Data.Account.AccountId.Address(), account2.Data.Account.AccountId.Address(), } - accounts, err := q.GetAccountsByIDs(keys) + accounts, err := q.GetAccountsByIDs(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, accounts, 2) @@ -201,7 +201,7 @@ func TestUpsertAccount(t *testing.T) { assert.Equal(t, uint32(0), accounts[1].NumSponsoring) assert.Equal(t, null.String{}, accounts[1].Sponsor) - accounts, err = q.GetAccountsByIDs([]string{account1.Data.Account.AccountId.Address()}) + accounts, err = q.GetAccountsByIDs(tt.Ctx, []string{account1.Data.Account.AccountId.Address()}) assert.NoError(t, err) assert.Len(t, accounts, 1) @@ -238,7 +238,7 @@ func TestUpsertAccount(t *testing.T) { assert.Equal(t, expectedBinary, actualBinary) assert.Equal(t, uint32(1234), accounts[0].LastModifiedLedger) - accounts, err = q.GetAccountsByIDs([]string{account2.Data.Account.AccountId.Address()}) + accounts, err = q.GetAccountsByIDs(tt.Ctx, []string{account2.Data.Account.AccountId.Address()}) assert.NoError(t, err) assert.Len(t, accounts, 1) @@ -283,21 +283,21 @@ func TestRemoveAccount(t *testing.T) { q := &Q{tt.HorizonSession()} batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) var rows int64 - rows, err = q.RemoveAccount("GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB") + rows, err = q.RemoveAccount(tt.Ctx, "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB") assert.NoError(t, err) assert.Equal(t, int64(1), rows) - accounts, err := q.GetAccountsByIDs([]string{"GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB"}) + accounts, err := q.GetAccountsByIDs(tt.Ctx, []string{"GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB"}) assert.NoError(t, err) assert.Len(t, accounts, 0) // Doesn't exist anymore - rows, err = q.RemoveAccount("GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB") + rows, err = q.RemoveAccount(tt.Ctx, "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB") assert.NoError(t, err) assert.Equal(t, int64(0), rows) } @@ -312,15 +312,15 @@ func TestAccountsForAsset(t *testing.T) { usdTrustLine.Data.TrustLine.AccountId = account2.Data.Account.AccountId batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - _, err = q.InsertTrustLine(eurTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, eurTrustLine) tt.Assert.NoError(err) - _, err = q.InsertTrustLine(usdTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, usdTrustLine) tt.Assert.NoError(err) pq := db2.PageQuery{ @@ -329,18 +329,18 @@ func TestAccountsForAsset(t *testing.T) { Cursor: "", } - accounts, err := q.AccountsForAsset(eurTrustLine.Data.TrustLine.Asset, pq) + accounts, err := q.AccountsForAsset(tt.Ctx, eurTrustLine.Data.TrustLine.Asset, pq) assert.NoError(t, err) tt.Assert.Len(accounts, 1) tt.Assert.Equal(account1.Data.Account.AccountId.Address(), accounts[0].AccountID) - accounts, err = q.AccountsForAsset(usdTrustLine.Data.TrustLine.Asset, pq) + accounts, err = q.AccountsForAsset(tt.Ctx, usdTrustLine.Data.TrustLine.Asset, pq) assert.NoError(t, err) tt.Assert.Len(accounts, 1) tt.Assert.Equal(account2.Data.Account.AccountId.Address(), accounts[0].AccountID) pq.Cursor = account2.Data.Account.AccountId.Address() - accounts, err = q.AccountsForAsset(usdTrustLine.Data.TrustLine.Asset, pq) + accounts, err = q.AccountsForAsset(tt.Ctx, usdTrustLine.Data.TrustLine.Asset, pq) assert.NoError(t, err) tt.Assert.Len(accounts, 0) @@ -350,7 +350,7 @@ func TestAccountsForAsset(t *testing.T) { Cursor: "", } - accounts, err = q.AccountsForAsset(eurTrustLine.Data.TrustLine.Asset, pq) + accounts, err = q.AccountsForAsset(tt.Ctx, eurTrustLine.Data.TrustLine.Asset, pq) assert.NoError(t, err) tt.Assert.Len(accounts, 1) } @@ -365,28 +365,28 @@ func TestAccountsForSponsor(t *testing.T) { usdTrustLine.Data.TrustLine.AccountId = account2.Data.Account.AccountId batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - err = batch.Add(account3) + err = batch.Add(tt.Ctx, account3) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - _, err = q.InsertTrustLine(eurTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, eurTrustLine) tt.Assert.NoError(err) - _, err = q.InsertTrustLine(usdTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, usdTrustLine) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account1.Data.Account.AccountId.Address(), account1.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account1.Data.Account.AccountId.Address(), account1.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account2.Data.Account.AccountId.Address(), account2.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account2.Data.Account.AccountId.Address(), account2.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account3.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account3.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account1.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account1.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account2.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account2.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) pq := db2.PageQuery{ @@ -395,7 +395,7 @@ func TestAccountsForSponsor(t *testing.T) { Cursor: "", } - accounts, err := q.AccountsForSponsor(sponsor.Address(), pq) + accounts, err := q.AccountsForSponsor(tt.Ctx, sponsor.Address(), pq) assert.NoError(t, err) tt.Assert.Len(accounts, 2) tt.Assert.Equal(account1.Data.Account.AccountId.Address(), accounts[0].AccountID) @@ -412,28 +412,28 @@ func TestAccountEntriesForSigner(t *testing.T) { usdTrustLine.Data.TrustLine.AccountId = account2.Data.Account.AccountId batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - err = batch.Add(account3) + err = batch.Add(tt.Ctx, account3) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - _, err = q.InsertTrustLine(eurTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, eurTrustLine) tt.Assert.NoError(err) - _, err = q.InsertTrustLine(usdTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, usdTrustLine) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account1.Data.Account.AccountId.Address(), account1.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account1.Data.Account.AccountId.Address(), account1.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account2.Data.Account.AccountId.Address(), account2.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account2.Data.Account.AccountId.Address(), account2.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account3.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account3.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account1.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account1.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) - _, err = q.CreateAccountSigner(account2.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) + _, err = q.CreateAccountSigner(tt.Ctx, account2.Data.Account.AccountId.Address(), account3.Data.Account.AccountId.Address(), 1, nil) tt.Assert.NoError(err) pq := db2.PageQuery{ @@ -442,12 +442,12 @@ func TestAccountEntriesForSigner(t *testing.T) { Cursor: "", } - accounts, err := q.AccountEntriesForSigner(account1.Data.Account.AccountId.Address(), pq) + accounts, err := q.AccountEntriesForSigner(tt.Ctx, account1.Data.Account.AccountId.Address(), pq) assert.NoError(t, err) tt.Assert.Len(accounts, 1) tt.Assert.Equal(account1.Data.Account.AccountId.Address(), accounts[0].AccountID) - accounts, err = q.AccountEntriesForSigner(account2.Data.Account.AccountId.Address(), pq) + accounts, err = q.AccountEntriesForSigner(tt.Ctx, account2.Data.Account.AccountId.Address(), pq) assert.NoError(t, err) tt.Assert.Len(accounts, 1) tt.Assert.Equal(account2.Data.Account.AccountId.Address(), accounts[0].AccountID) @@ -458,7 +458,7 @@ func TestAccountEntriesForSigner(t *testing.T) { account3.Data.Account.AccountId.Address(): true, } - accounts, err = q.AccountEntriesForSigner(account3.Data.Account.AccountId.Address(), pq) + accounts, err = q.AccountEntriesForSigner(tt.Ctx, account3.Data.Account.AccountId.Address(), pq) assert.NoError(t, err) tt.Assert.Len(accounts, 3) @@ -470,12 +470,12 @@ func TestAccountEntriesForSigner(t *testing.T) { tt.Assert.Len(want, 0) pq.Cursor = accounts[len(accounts)-1].AccountID - accounts, err = q.AccountEntriesForSigner(account3.Data.Account.AccountId.Address(), pq) + accounts, err = q.AccountEntriesForSigner(tt.Ctx, account3.Data.Account.AccountId.Address(), pq) assert.NoError(t, err) tt.Assert.Len(accounts, 0) pq.Order = "desc" - accounts, err = q.AccountEntriesForSigner(account3.Data.Account.AccountId.Address(), pq) + accounts, err = q.AccountEntriesForSigner(tt.Ctx, account3.Data.Account.AccountId.Address(), pq) assert.NoError(t, err) tt.Assert.Len(accounts, 2) @@ -485,7 +485,7 @@ func TestAccountEntriesForSigner(t *testing.T) { Cursor: "", } - accounts, err = q.AccountEntriesForSigner(account1.Data.Account.AccountId.Address(), pq) + accounts, err = q.AccountEntriesForSigner(tt.Ctx, account1.Data.Account.AccountId.Address(), pq) assert.NoError(t, err) tt.Assert.Len(accounts, 1) } @@ -497,11 +497,11 @@ func TestGetAccountByID(t *testing.T) { q := &Q{tt.HorizonSession()} batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - resultAccount, err := q.GetAccountByID(account1.Data.Account.AccountId.Address()) + resultAccount, err := q.GetAccountByID(tt.Ctx, account1.Data.Account.AccountId.Address()) assert.NoError(t, err) assert.Equal(t, "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB", resultAccount.AccountID) diff --git a/services/horizon/internal/db2/history/asset.go b/services/horizon/internal/db2/history/asset.go index 09bd34da50..f6a73b819e 100644 --- a/services/horizon/internal/db2/history/asset.go +++ b/services/horizon/internal/db2/history/asset.go @@ -1,6 +1,7 @@ package history import ( + "context" "sort" sq "github.com/Masterminds/squirrel" @@ -10,7 +11,7 @@ import ( ) // GetAssetID fetches the id for an Asset -func (q *Q) GetAssetID(asset xdr.Asset) (id int64, err error) { +func (q *Q) GetAssetID(ctx context.Context, asset xdr.Asset) (id int64, err error) { var ( assetType string assetCode string @@ -27,12 +28,12 @@ func (q *Q) GetAssetID(asset xdr.Asset) (id int64, err error) { "asset_code": assetCode, "asset_issuer": assetIssuer}) - err = q.Get(&id, sql) + err = q.Get(ctx, &id, sql) return } // CreateAssets creates rows in the history_assets table for a given list of assets. -func (q *Q) CreateAssets(assets []xdr.Asset, batchSize int) (map[string]Asset, error) { +func (q *Q) CreateAssets(ctx context.Context, assets []xdr.Asset, batchSize int) (map[string]Asset, error) { searchStrings := make([]string, 0, len(assets)) assetToKey := map[[3]string]string{} @@ -54,7 +55,7 @@ func (q *Q) CreateAssets(assets []xdr.Asset, batchSize int) (map[string]Asset, e return nil, errors.Wrap(err, "could not extract asset details") } - err = builder.Row(map[string]interface{}{ + err = builder.Row(ctx, map[string]interface{}{ "asset_type": assetType, "asset_code": assetCode, "asset_issuer": assetIssuer, @@ -74,7 +75,7 @@ func (q *Q) CreateAssets(assets []xdr.Asset, batchSize int) (map[string]Asset, e } } - err := builder.Exec() + err := builder.Exec(ctx) if err != nil { return nil, errors.Wrap(err, "could not exec asset insert builder") } @@ -89,7 +90,7 @@ func (q *Q) CreateAssets(assets []xdr.Asset, batchSize int) (map[string]Asset, e } subset := searchStrings[i:end] - err = q.Select(&rows, sq.Select("*").From("history_assets").Where(sq.Eq{ + err = q.Select(ctx, &rows, sq.Select("*").From("history_assets").Where(sq.Eq{ "concat(asset_type, '/', asset_code, '/', asset_issuer)": subset, })) if err != nil { diff --git a/services/horizon/internal/db2/history/asset_stats.go b/services/horizon/internal/db2/history/asset_stats.go index 81174b676a..e24f3fe887 100644 --- a/services/horizon/internal/db2/history/asset_stats.go +++ b/services/horizon/internal/db2/history/asset_stats.go @@ -1,6 +1,7 @@ package history import ( + "context" "fmt" "strings" @@ -32,19 +33,19 @@ func assetStatToPrimaryKeyMap(assetStat ExpAssetStat) map[string]interface{} { } // InsertAssetStats a set of asset stats into the exp_asset_stats -func (q *Q) InsertAssetStats(assetStats []ExpAssetStat, batchSize int) error { +func (q *Q) InsertAssetStats(ctx context.Context, assetStats []ExpAssetStat, batchSize int) error { builder := &db.BatchInsertBuilder{ Table: q.GetTable("exp_asset_stats"), MaxBatchSize: batchSize, } for _, assetStat := range assetStats { - if err := builder.Row(assetStatToMap(assetStat)); err != nil { + if err := builder.Row(ctx, assetStatToMap(assetStat)); err != nil { return errors.Wrap(err, "could not insert asset assetStat row") } } - if err := builder.Exec(); err != nil { + if err := builder.Exec(ctx); err != nil { return errors.Wrap(err, "could not exec asset assetStats insert builder") } @@ -53,9 +54,9 @@ func (q *Q) InsertAssetStats(assetStats []ExpAssetStat, batchSize int) error { // InsertAssetStat a single asset assetStat row into the exp_asset_stats // Returns number of rows affected and error. -func (q *Q) InsertAssetStat(assetStat ExpAssetStat) (int64, error) { +func (q *Q) InsertAssetStat(ctx context.Context, assetStat ExpAssetStat) (int64, error) { sql := sq.Insert("exp_asset_stats").SetMap(assetStatToMap(assetStat)) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -65,11 +66,11 @@ func (q *Q) InsertAssetStat(assetStat ExpAssetStat) (int64, error) { // UpdateAssetStat updates a row in the exp_asset_stats table. // Returns number of rows affected and error. -func (q *Q) UpdateAssetStat(assetStat ExpAssetStat) (int64, error) { +func (q *Q) UpdateAssetStat(ctx context.Context, assetStat ExpAssetStat) (int64, error) { sql := sq.Update("exp_asset_stats"). SetMap(assetStatToMap(assetStat)). Where(assetStatToPrimaryKeyMap(assetStat)) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -78,14 +79,14 @@ func (q *Q) UpdateAssetStat(assetStat ExpAssetStat) (int64, error) { } // RemoveAssetStat removes a row in the exp_asset_stats table. -func (q *Q) RemoveAssetStat(assetType xdr.AssetType, assetCode, assetIssuer string) (int64, error) { +func (q *Q) RemoveAssetStat(ctx context.Context, assetType xdr.AssetType, assetCode, assetIssuer string) (int64, error) { sql := sq.Delete("exp_asset_stats"). Where(map[string]interface{}{ "asset_type": assetType, "asset_code": assetCode, "asset_issuer": assetIssuer, }) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -94,14 +95,14 @@ func (q *Q) RemoveAssetStat(assetType xdr.AssetType, assetCode, assetIssuer stri } // GetAssetStat returns a row in the exp_asset_stats table. -func (q *Q) GetAssetStat(assetType xdr.AssetType, assetCode, assetIssuer string) (ExpAssetStat, error) { +func (q *Q) GetAssetStat(ctx context.Context, assetType xdr.AssetType, assetCode, assetIssuer string) (ExpAssetStat, error) { sql := selectAssetStats.Where(map[string]interface{}{ "asset_type": assetType, "asset_code": assetCode, "asset_issuer": assetIssuer, }) var assetStat ExpAssetStat - err := q.Get(&assetStat, sql) + err := q.Get(ctx, &assetStat, sql) return assetStat, err } @@ -137,7 +138,7 @@ func parseAssetStatsCursor(cursor string) (string, string, error) { } // GetAssetStats returns a page of exp_asset_stats rows. -func (q *Q) GetAssetStats(assetCode, assetIssuer string, page db2.PageQuery) ([]ExpAssetStat, error) { +func (q *Q) GetAssetStats(ctx context.Context, assetCode, assetIssuer string, page db2.PageQuery) ([]ExpAssetStat, error) { sql := selectAssetStats filters := map[string]interface{}{} if assetCode != "" { @@ -173,7 +174,7 @@ func (q *Q) GetAssetStats(assetCode, assetIssuer string, page db2.PageQuery) ([] sql = sql.OrderBy("(asset_code, asset_issuer) " + orderBy).Limit(page.Limit) var results []ExpAssetStat - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } diff --git a/services/horizon/internal/db2/history/asset_stats_test.go b/services/horizon/internal/db2/history/asset_stats_test.go index 63d478a583..9a813e4b4c 100644 --- a/services/horizon/internal/db2/history/asset_stats_test.go +++ b/services/horizon/internal/db2/history/asset_stats_test.go @@ -14,7 +14,7 @@ func TestInsertAssetStats(t *testing.T) { defer tt.Finish() test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - tt.Assert.NoError(q.InsertAssetStats([]ExpAssetStat{}, 1)) + tt.Assert.NoError(q.InsertAssetStats(tt.Ctx, []ExpAssetStat{}, 1)) assetStats := []ExpAssetStat{ { @@ -52,10 +52,10 @@ func TestInsertAssetStats(t *testing.T) { NumAccounts: 1, }, } - tt.Assert.NoError(q.InsertAssetStats(assetStats, 1)) + tt.Assert.NoError(q.InsertAssetStats(tt.Ctx, assetStats, 1)) for _, assetStat := range assetStats { - got, err := q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + got, err := q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.NoError(err) tt.Assert.Equal(got, assetStat) } @@ -105,11 +105,11 @@ func TestInsertAssetStat(t *testing.T) { } for _, assetStat := range assetStats { - numChanged, err := q.InsertAssetStat(assetStat) + numChanged, err := q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.NoError(err) tt.Assert.Equal(numChanged, int64(1)) - got, err := q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + got, err := q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.NoError(err) tt.Assert.Equal(got, assetStat) } @@ -139,23 +139,23 @@ func TestInsertAssetStatAlreadyExistsError(t *testing.T) { NumAccounts: 2, } - numChanged, err := q.InsertAssetStat(assetStat) + numChanged, err := q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.NoError(err) tt.Assert.Equal(numChanged, int64(1)) - numChanged, err = q.InsertAssetStat(assetStat) + numChanged, err = q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.Error(err) tt.Assert.Equal(numChanged, int64(0)) assetStat.NumAccounts = 4 assetStat.Amount = "3" - numChanged, err = q.InsertAssetStat(assetStat) + numChanged, err = q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.Error(err) tt.Assert.Equal(numChanged, int64(0)) assetStat.NumAccounts = 2 assetStat.Amount = "1" - got, err := q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + got, err := q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.NoError(err) tt.Assert.Equal(got, assetStat) } @@ -184,11 +184,11 @@ func TestUpdateAssetStatDoesNotExistsError(t *testing.T) { NumAccounts: 2, } - numChanged, err := q.UpdateAssetStat(assetStat) + numChanged, err := q.UpdateAssetStat(tt.Ctx, assetStat) tt.Assert.Nil(err) tt.Assert.Equal(numChanged, int64(0)) - _, err = q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + _, err = q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.Equal(err, sql.ErrNoRows) } @@ -217,22 +217,22 @@ func TestUpdateStat(t *testing.T) { NumAccounts: 2, } - numChanged, err := q.InsertAssetStat(assetStat) + numChanged, err := q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.NoError(err) tt.Assert.Equal(numChanged, int64(1)) - got, err := q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + got, err := q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.NoError(err) tt.Assert.Equal(got, assetStat) assetStat.NumAccounts = 50 assetStat.Amount = "23" - numChanged, err = q.UpdateAssetStat(assetStat) + numChanged, err = q.UpdateAssetStat(tt.Ctx, assetStat) tt.Assert.Nil(err) tt.Assert.Equal(numChanged, int64(1)) - got, err = q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + got, err = q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.NoError(err) tt.Assert.Equal(got, assetStat) } @@ -261,7 +261,7 @@ func TestGetAssetStatDoesNotExist(t *testing.T) { NumAccounts: 2, } - _, err := q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + _, err := q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.Equal(err, sql.ErrNoRows) } @@ -290,7 +290,7 @@ func TestRemoveAssetStat(t *testing.T) { NumAccounts: 2, } - numChanged, err := q.RemoveAssetStat( + numChanged, err := q.RemoveAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer, @@ -298,15 +298,15 @@ func TestRemoveAssetStat(t *testing.T) { tt.Assert.Nil(err) tt.Assert.Equal(numChanged, int64(0)) - numChanged, err = q.InsertAssetStat(assetStat) + numChanged, err = q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.NoError(err) tt.Assert.Equal(numChanged, int64(1)) - got, err := q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + got, err := q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.NoError(err) tt.Assert.Equal(got, assetStat) - numChanged, err = q.RemoveAssetStat( + numChanged, err = q.RemoveAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer, @@ -314,7 +314,7 @@ func TestRemoveAssetStat(t *testing.T) { tt.Assert.Nil(err) tt.Assert.Equal(numChanged, int64(1)) - _, err = q.GetAssetStat(assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) + _, err = q.GetAssetStat(tt.Ctx, assetStat.AssetType, assetStat.AssetCode, assetStat.AssetIssuer) tt.Assert.Equal(err, sql.ErrNoRows) } @@ -367,7 +367,7 @@ func TestGetAssetStatsCursorValidation(t *testing.T) { Order: "asc", Limit: 5, } - results, err := q.GetAssetStats("", "", page) + results, err := q.GetAssetStats(tt.Ctx, "", "", page) tt.Assert.Empty(results) tt.Assert.NotNil(err) tt.Assert.Contains(err.Error(), testCase.expectedError) @@ -386,7 +386,7 @@ func TestGetAssetStatsOrderValidation(t *testing.T) { Order: "invalid", Limit: 5, } - results, err := q.GetAssetStats("", "", page) + results, err := q.GetAssetStats(tt.Ctx, "", "", page) tt.Assert.Empty(results) tt.Assert.NotNil(err) tt.Assert.Contains(err.Error(), "invalid page order") @@ -481,7 +481,7 @@ func TestGetAssetStatsFiltersAndCursor(t *testing.T) { usdAssetStat, } for _, assetStat := range assetStats { - numChanged, err := q.InsertAssetStat(assetStat) + numChanged, err := q.InsertAssetStat(tt.Ctx, assetStat) tt.Assert.NoError(err) tt.Assert.Equal(numChanged, int64(1)) } @@ -721,12 +721,12 @@ func TestGetAssetStatsFiltersAndCursor(t *testing.T) { Cursor: testCase.cursor, Limit: 5, } - results, err := q.GetAssetStats(testCase.assetCode, testCase.assetIssuer, page) + results, err := q.GetAssetStats(tt.Ctx, testCase.assetCode, testCase.assetIssuer, page) tt.Assert.NoError(err) tt.Assert.Equal(testCase.expected, results) page.Limit = 1 - results, err = q.GetAssetStats(testCase.assetCode, testCase.assetIssuer, page) + results, err = q.GetAssetStats(tt.Ctx, testCase.assetCode, testCase.assetIssuer, page) tt.Assert.NoError(err) if len(testCase.expected) == 0 { tt.Assert.Equal(testCase.expected, results) @@ -738,7 +738,7 @@ func TestGetAssetStatsFiltersAndCursor(t *testing.T) { page = page.Invert() page.Limit = 5 - results, err = q.GetAssetStats(testCase.assetCode, testCase.assetIssuer, page) + results, err = q.GetAssetStats(tt.Ctx, testCase.assetCode, testCase.assetIssuer, page) tt.Assert.NoError(err) reverseAssetStats(results) tt.Assert.Equal(testCase.expected, results) diff --git a/services/horizon/internal/db2/history/asset_test.go b/services/horizon/internal/db2/history/asset_test.go index c345c43805..9289f44622 100644 --- a/services/horizon/internal/db2/history/asset_test.go +++ b/services/horizon/internal/db2/history/asset_test.go @@ -18,7 +18,7 @@ func TestCreateAssetsSortedOrder(t *testing.T) { usdAsset, nativeAsset, eurAsset, xdr.MustNewCreditAsset("CNY", issuer.Address()), } - assetMap, err := q.CreateAssets( + assetMap, err := q.CreateAssets(tt.Ctx, assets, 2, ) @@ -61,7 +61,7 @@ func TestCreateAssets(t *testing.T) { assets := []xdr.Asset{ nativeAsset, eurAsset, } - assetMap, err := q.CreateAssets(assets, 1) + assetMap, err := q.CreateAssets(tt.Ctx, assets, 1) tt.Assert.NoError(err) tt.Assert.Len(assetMap, len(assets)) @@ -81,7 +81,7 @@ func TestCreateAssets(t *testing.T) { } // CreateAssets handles duplicates - assetMap, err = q.CreateAssets( + assetMap, err = q.CreateAssets(tt.Ctx, []xdr.Asset{ nativeAsset, nativeAsset, eurAsset, eurAsset, nativeAsset, nativeAsset, eurAsset, eurAsset, @@ -106,7 +106,7 @@ func TestCreateAssets(t *testing.T) { // CreateAssets handles duplicates and new rows assets = append(assets, usdAsset) - assetMap, err = q.CreateAssets(assets, 2) + assetMap, err = q.CreateAssets(tt.Ctx, assets, 2) tt.Assert.NoError(err) tt.Assert.Len(assetMap, len(assets)) diff --git a/services/horizon/internal/db2/history/claimable_balances.go b/services/horizon/internal/db2/history/claimable_balances.go index 8b020a3140..75757b5393 100644 --- a/services/horizon/internal/db2/history/claimable_balances.go +++ b/services/horizon/internal/db2/history/claimable_balances.go @@ -1,6 +1,7 @@ package history import ( + "context" "database/sql/driver" "encoding/json" "strconv" @@ -116,17 +117,17 @@ type Claimant struct { } type ClaimableBalancesBatchInsertBuilder interface { - Add(entry *xdr.LedgerEntry) error - Exec() error + Add(ctx context.Context, entry *xdr.LedgerEntry) error + Exec(ctx context.Context) error } // QClaimableBalances defines account related queries. type QClaimableBalances interface { NewClaimableBalancesBatchInsertBuilder(maxBatchSize int) ClaimableBalancesBatchInsertBuilder - UpdateClaimableBalance(entry xdr.LedgerEntry) (int64, error) - RemoveClaimableBalance(cBalance xdr.ClaimableBalanceEntry) (int64, error) - GetClaimableBalancesByID(ids []xdr.ClaimableBalanceId) ([]ClaimableBalance, error) - CountClaimableBalances() (int, error) + UpdateClaimableBalance(ctx context.Context, entry xdr.LedgerEntry) (int64, error) + RemoveClaimableBalance(ctx context.Context, cBalance xdr.ClaimableBalanceEntry) (int64, error) + GetClaimableBalancesByID(ctx context.Context, ids []xdr.ClaimableBalanceId) ([]ClaimableBalance, error) + CountClaimableBalances(ctx context.Context) (int, error) } // NewClaimableBalancesBatchInsertBuilder constructs a new ClaimableBalancesBatchInsertBuilder instance @@ -140,11 +141,11 @@ func (q *Q) NewClaimableBalancesBatchInsertBuilder(maxBatchSize int) ClaimableBa } // CountClaimableBalances returns the total number of claimable balances in the DB -func (q *Q) CountClaimableBalances() (int, error) { +func (q *Q) CountClaimableBalances(ctx context.Context) (int, error) { sql := sq.Select("count(*)").From("claimable_balances") var count int - if err := q.Get(&count, sql); err != nil { + if err := q.Get(ctx, &count, sql); err != nil { return 0, errors.Wrap(err, "could not run select query") } @@ -152,17 +153,17 @@ func (q *Q) CountClaimableBalances() (int, error) { } // GetClaimableBalancesByID finds all claimable balances by ClaimableBalanceId -func (q *Q) GetClaimableBalancesByID(ids []xdr.ClaimableBalanceId) ([]ClaimableBalance, error) { +func (q *Q) GetClaimableBalancesByID(ctx context.Context, ids []xdr.ClaimableBalanceId) ([]ClaimableBalance, error) { var cBalances []ClaimableBalance sql := selectClaimableBalances.Where(map[string]interface{}{"cb.id": ids}) - err := q.Select(&cBalances, sql) + err := q.Select(ctx, &cBalances, sql) return cBalances, err } // UpdateClaimableBalance updates a row in the claimable_balances table. // The only updatable value on claimable_balances is sponsor // Returns number of rows affected and error. -func (q *Q) UpdateClaimableBalance(entry xdr.LedgerEntry) (int64, error) { +func (q *Q) UpdateClaimableBalance(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { cBalance := entry.Data.MustClaimableBalance() cBalanceMap := map[string]interface{}{ "last_modified_ledger": entry.LastModifiedLedgerSeq, @@ -170,7 +171,7 @@ func (q *Q) UpdateClaimableBalance(entry xdr.LedgerEntry) (int64, error) { } sql := sq.Update("claimable_balances").SetMap(cBalanceMap).Where("id = ?", cBalance.BalanceId) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -180,10 +181,10 @@ func (q *Q) UpdateClaimableBalance(entry xdr.LedgerEntry) (int64, error) { // RemoveClaimableBalance deletes a row in the claimable_balances table. // Returns number of rows affected and error. -func (q *Q) RemoveClaimableBalance(cBalance xdr.ClaimableBalanceEntry) (int64, error) { +func (q *Q) RemoveClaimableBalance(ctx context.Context, cBalance xdr.ClaimableBalanceEntry) (int64, error) { sql := sq.Delete("claimable_balances"). Where(sq.Eq{"id": cBalance.BalanceId}) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -192,15 +193,15 @@ func (q *Q) RemoveClaimableBalance(cBalance xdr.ClaimableBalanceEntry) (int64, e } // FindClaimableBalanceByID returns a claimable balance. -func (q *Q) FindClaimableBalanceByID(balanceID xdr.ClaimableBalanceId) (ClaimableBalance, error) { +func (q *Q) FindClaimableBalanceByID(ctx context.Context, balanceID xdr.ClaimableBalanceId) (ClaimableBalance, error) { var claimableBalance ClaimableBalance sql := selectClaimableBalances.Limit(1).Where("cb.id = ?", balanceID) - err := q.Get(&claimableBalance, sql) + err := q.Get(ctx, &claimableBalance, sql) return claimableBalance, err } // GetClaimableBalances finds all claimable balances where accountID is one of the claimants -func (q *Q) GetClaimableBalances(query ClaimableBalancesQuery) ([]ClaimableBalance, error) { +func (q *Q) GetClaimableBalances(ctx context.Context, query ClaimableBalancesQuery) ([]ClaimableBalance, error) { sql, err := query.ApplyCursor(selectClaimableBalances) if err != nil { return nil, errors.Wrap(err, "could not apply query to page") @@ -230,7 +231,7 @@ func (q *Q) GetClaimableBalances(query ClaimableBalancesQuery) ([]ClaimableBalan ) var results []ClaimableBalance - if err := q.Select(&results, sql); err != nil { + if err := q.Select(ctx, &results, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } @@ -254,7 +255,7 @@ func buildClaimants(claimants []xdr.Claimant) Claimants { return hClaimants } -func (i *claimableBalancesBatchInsertBuilder) Add(entry *xdr.LedgerEntry) error { +func (i *claimableBalancesBatchInsertBuilder) Add(ctx context.Context, entry *xdr.LedgerEntry) error { cBalance := entry.Data.MustClaimableBalance() row := ClaimableBalance{ BalanceID: cBalance.BalanceId, @@ -265,11 +266,11 @@ func (i *claimableBalancesBatchInsertBuilder) Add(entry *xdr.LedgerEntry) error LastModifiedLedger: uint32(entry.LastModifiedLedgerSeq), Flags: uint32(cBalance.Flags()), } - return i.builder.RowStruct(row) + return i.builder.RowStruct(ctx, row) } -func (i *claimableBalancesBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *claimableBalancesBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } var claimableBalancesSelectStatement = "cb.id, " + diff --git a/services/horizon/internal/db2/history/claimable_balances_batch_insert_builder_test.go b/services/horizon/internal/db2/history/claimable_balances_batch_insert_builder_test.go index 2ae97c9a38..c360fb1f61 100644 --- a/services/horizon/internal/db2/history/claimable_balances_batch_insert_builder_test.go +++ b/services/horizon/internal/db2/history/claimable_balances_batch_insert_builder_test.go @@ -59,14 +59,14 @@ func TestAddClaimableBalance(t *testing.T) { builder := q.NewClaimableBalancesBatchInsertBuilder(2) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) cbs := []ClaimableBalance{} - err = q.Select(&cbs, selectClaimableBalances) + err = q.Select(tt.Ctx, &cbs, selectClaimableBalances) if tt.Assert.NoError(err) { tt.Assert.Len(cbs, 1) diff --git a/services/horizon/internal/db2/history/claimable_balances_test.go b/services/horizon/internal/db2/history/claimable_balances_test.go index 19fa573332..c95320757a 100644 --- a/services/horizon/internal/db2/history/claimable_balances_test.go +++ b/services/horizon/internal/db2/history/claimable_balances_test.go @@ -47,22 +47,22 @@ func TestRemoveClaimableBalance(t *testing.T) { builder := q.NewClaimableBalancesBatchInsertBuilder(2) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) - r, err := q.FindClaimableBalanceByID(cBalance.BalanceId) + r, err := q.FindClaimableBalanceByID(tt.Ctx, cBalance.BalanceId) tt.Assert.NoError(err) tt.Assert.NotNil(r) - removed, err := q.RemoveClaimableBalance(cBalance) + removed, err := q.RemoveClaimableBalance(tt.Ctx, cBalance) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), removed) cbs := []ClaimableBalance{} - err = q.Select(&cbs, selectClaimableBalances) + err = q.Select(tt.Ctx, &cbs, selectClaimableBalances) if tt.Assert.NoError(err) { tt.Assert.Len(cbs, 0) @@ -110,7 +110,7 @@ func TestFindClaimableBalancesByDestination(t *testing.T) { builder := q.NewClaimableBalancesBatchInsertBuilder(2) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) balanceID = xdr.ClaimableBalanceId{ @@ -150,10 +150,10 @@ func TestFindClaimableBalancesByDestination(t *testing.T) { LastModifiedLedgerSeq: lastModifiedLedgerSeq, } - err = builder.Add(&entry) + err = builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) query := ClaimableBalancesQuery{ @@ -161,7 +161,7 @@ func TestFindClaimableBalancesByDestination(t *testing.T) { Claimant: xdr.MustAddressPtr(dest1), } - cbs, err := q.GetClaimableBalances(query) + cbs, err := q.GetClaimableBalances(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(cbs, 2) @@ -170,7 +170,7 @@ func TestFindClaimableBalancesByDestination(t *testing.T) { } query.Claimant = xdr.MustAddressPtr(dest2) - cbs, err = q.GetClaimableBalances(query) + cbs, err = q.GetClaimableBalances(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(cbs, 1) tt.Assert.Equal(dest2, cbs[0].Claimants[1].Destination) @@ -215,10 +215,10 @@ func TestUpdateClaimableBalance(t *testing.T) { builder := q.NewClaimableBalancesBatchInsertBuilder(1) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) entry = xdr.LedgerEntry{ @@ -235,12 +235,12 @@ func TestUpdateClaimableBalance(t *testing.T) { }, } - updated, err := q.UpdateClaimableBalance(entry) + updated, err := q.UpdateClaimableBalance(tt.Ctx, entry) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), updated) cbs := []ClaimableBalance{} - err = q.Select(&cbs, selectClaimableBalances) + err = q.Select(tt.Ctx, &cbs, selectClaimableBalances) tt.Assert.NoError(err) tt.Assert.Equal("GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", cbs[0].Sponsor.String) tt.Assert.Equal(uint32(lastModifiedLedgerSeq+1), cbs[0].LastModifiedLedger) @@ -285,13 +285,13 @@ func TestFindClaimableBalance(t *testing.T) { builder := q.NewClaimableBalancesBatchInsertBuilder(2) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) - cb, err := q.FindClaimableBalanceByID(cBalance.BalanceId) + cb, err := q.FindClaimableBalanceByID(tt.Ctx, cBalance.BalanceId) tt.Assert.NoError(err) tt.Assert.Equal(cBalance.BalanceId, cb.BalanceID) @@ -344,21 +344,21 @@ func TestGetClaimableBalancesByID(t *testing.T) { builder := q.NewClaimableBalancesBatchInsertBuilder(2) - err := builder.Add(&entry) + err := builder.Add(tt.Ctx, &entry) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) - r, err := q.GetClaimableBalancesByID([]xdr.ClaimableBalanceId{cBalance.BalanceId}) + r, err := q.GetClaimableBalancesByID(tt.Ctx, []xdr.ClaimableBalanceId{cBalance.BalanceId}) tt.Assert.NoError(err) tt.Assert.Len(r, 1) - removed, err := q.RemoveClaimableBalance(cBalance) + removed, err := q.RemoveClaimableBalance(tt.Ctx, cBalance) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), removed) - r, err = q.GetClaimableBalancesByID([]xdr.ClaimableBalanceId{cBalance.BalanceId}) + r, err = q.GetClaimableBalancesByID(tt.Ctx, []xdr.ClaimableBalanceId{cBalance.BalanceId}) tt.Assert.NoError(err) tt.Assert.Len(r, 0) } diff --git a/services/horizon/internal/db2/history/effect.go b/services/horizon/internal/db2/history/effect.go index 1a400a9250..efc24425da 100644 --- a/services/horizon/internal/db2/history/effect.go +++ b/services/horizon/internal/db2/history/effect.go @@ -1,6 +1,7 @@ package history import ( + "context" "encoding/json" "fmt" "math" @@ -48,9 +49,9 @@ func (q *Q) Effects() *EffectsQ { } // ForAccount filters the operations collection to a specific account -func (q *EffectsQ) ForAccount(aid string) *EffectsQ { +func (q *EffectsQ) ForAccount(ctx context.Context, aid string) *EffectsQ { var account Account - q.Err = q.parent.AccountByAddress(&account, aid) + q.Err = q.parent.AccountByAddress(ctx, &account, aid) if q.Err != nil { return q } @@ -62,9 +63,9 @@ func (q *EffectsQ) ForAccount(aid string) *EffectsQ { // ForLedger filters the query to only effects in a specific ledger, // specified by its sequence. -func (q *EffectsQ) ForLedger(seq int32) *EffectsQ { +func (q *EffectsQ) ForLedger(ctx context.Context, seq int32) *EffectsQ { var ledger Ledger - q.Err = q.parent.LedgerBySequence(&ledger, seq) + q.Err = q.parent.LedgerBySequence(ctx, &ledger, seq) if q.Err != nil { return q } @@ -97,9 +98,9 @@ func (q *EffectsQ) ForOperation(id int64) *EffectsQ { // ForTransaction filters the query to only effects in a specific // transaction, specified by the transactions's hex-encoded hash. -func (q *EffectsQ) ForTransaction(hash string) *EffectsQ { +func (q *EffectsQ) ForTransaction(ctx context.Context, hash string) *EffectsQ { var tx Transaction - q.Err = q.parent.TransactionByHash(&tx, hash) + q.Err = q.parent.TransactionByHash(ctx, &tx, hash) if q.Err != nil { return q } @@ -162,12 +163,12 @@ func (q *EffectsQ) Page(page db2.PageQuery) *EffectsQ { } // Select loads the results of the query specified by `q` into `dest`. -func (q *EffectsQ) Select(dest interface{}) error { +func (q *EffectsQ) Select(ctx context.Context, dest interface{}) error { if q.Err != nil { return q.Err } - q.Err = q.parent.Select(dest, q.sql) + q.Err = q.parent.Select(ctx, dest, q.sql) return q.Err } diff --git a/services/horizon/internal/db2/history/effect_batch_insert_builder.go b/services/horizon/internal/db2/history/effect_batch_insert_builder.go index 90c463a1e3..3a0bab6836 100644 --- a/services/horizon/internal/db2/history/effect_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/effect_batch_insert_builder.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stellar/go/support/db" ) @@ -8,13 +10,14 @@ import ( // history_effects table type EffectBatchInsertBuilder interface { Add( + ctx context.Context, accountID int64, operationID int64, order uint32, effectType EffectType, details []byte, ) error - Exec() error + Exec(ctx context.Context) error } // effectBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -34,13 +37,14 @@ func (q *Q) NewEffectBatchInsertBuilder(maxBatchSize int) EffectBatchInsertBuild // Add adds a effect to the batch func (i *effectBatchInsertBuilder) Add( + ctx context.Context, accountID int64, operationID int64, order uint32, effectType EffectType, details []byte, ) error { - return i.builder.Row(map[string]interface{}{ + return i.builder.Row(ctx, map[string]interface{}{ "history_account_id": accountID, "history_operation_id": operationID, "\"order\"": order, @@ -49,6 +53,6 @@ func (i *effectBatchInsertBuilder) Add( }) } -func (i *effectBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *effectBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/effect_batch_insert_builder_test.go b/services/horizon/internal/db2/history/effect_batch_insert_builder_test.go index 213dd2399f..3e4ac3f83c 100644 --- a/services/horizon/internal/db2/history/effect_batch_insert_builder_test.go +++ b/services/horizon/internal/db2/history/effect_batch_insert_builder_test.go @@ -15,7 +15,7 @@ func TestAddEffect(t *testing.T) { q := &Q{tt.HorizonSession()} address := "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON" - accounIDs, err := q.CreateAccounts([]string{address}, 1) + accounIDs, err := q.CreateAccounts(tt.Ctx, []string{address}, 1) tt.Assert.NoError(err) builder := q.NewEffectBatchInsertBuilder(2) @@ -25,7 +25,7 @@ func TestAddEffect(t *testing.T) { "asset_type": "native", }) - err = builder.Add( + err = builder.Add(tt.Ctx, accounIDs[address], toid.New(sequence, 1, 1).ToInt64(), 1, @@ -34,11 +34,11 @@ func TestAddEffect(t *testing.T) { ) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) effects := []Effect{} - tt.Assert.NoError(q.Effects().Select(&effects)) + tt.Assert.NoError(q.Effects().Select(tt.Ctx, &effects)) tt.Assert.Len(effects, 1) effect := effects[0] diff --git a/services/horizon/internal/db2/history/fee_bump_scenario.go b/services/horizon/internal/db2/history/fee_bump_scenario.go index fe2c843fff..e96acb7454 100644 --- a/services/horizon/internal/db2/history/fee_bump_scenario.go +++ b/services/horizon/internal/db2/history/fee_bump_scenario.go @@ -1,6 +1,7 @@ package history import ( + "context" "encoding/hex" "encoding/json" "testing" @@ -113,7 +114,7 @@ func FeeBumpScenario(tt *test.T, q *Q, successful bool) FeeBumpFixture { } *fixture.Ledger.SuccessfulTransactionCount = 1 *fixture.Ledger.FailedTransactionCount = 0 - _, err := q.Exec(sq.Insert("history_ledgers").SetMap(ledgerToMap(fixture.Ledger))) + _, err := q.Exec(context.Background(), sq.Insert("history_ledgers").SetMap(ledgerToMap(fixture.Ledger))) tt.Assert.NoError(err) fixture.Envelope = xdr.TransactionEnvelope{ @@ -242,12 +243,13 @@ func FeeBumpScenario(tt *test.T, q *Q, successful bool) FeeBumpFixture { metaXDR: "AAAAAQAAAAAAAAAA", hash: "edba3051b2f2d9b713e8a08709d631eccb72c59864ff3c564c68792271bb24a7", }) + ctx := context.Background() insertBuilder := q.NewTransactionBatchInsertBuilder(2) // include both fee bump and normal transaction in the same batch // to make sure both kinds of transactions can be inserted using a single exec statement - tt.Assert.NoError(insertBuilder.Add(feeBumpTransaction, sequence)) - tt.Assert.NoError(insertBuilder.Add(normalTransaction, sequence)) - tt.Assert.NoError(insertBuilder.Exec()) + tt.Assert.NoError(insertBuilder.Add(ctx, feeBumpTransaction, sequence)) + tt.Assert.NoError(insertBuilder.Add(ctx, normalTransaction, sequence)) + tt.Assert.NoError(insertBuilder.Exec(ctx)) account := fixture.Envelope.SourceAccount().ToAccountId() feeBumpAccount := fixture.Envelope.FeeBumpAccount().ToAccountId() @@ -259,6 +261,7 @@ func FeeBumpScenario(tt *test.T, q *Q, successful bool) FeeBumpFixture { tt.Assert.NoError(err) tt.Assert.NoError(opBuilder.Add( + ctx, toid.New(fixture.Ledger.Sequence, 1, 1).ToInt64(), toid.New(fixture.Ledger.Sequence, 1, 0).ToInt64(), 1, @@ -266,16 +269,17 @@ func FeeBumpScenario(tt *test.T, q *Q, successful bool) FeeBumpFixture { details, account.Address(), )) - tt.Assert.NoError(opBuilder.Exec()) + tt.Assert.NoError(opBuilder.Exec(ctx)) effectBuilder := q.NewEffectBatchInsertBuilder(2) details, err = json.Marshal(map[string]interface{}{"new_seq": 98}) tt.Assert.NoError(err) - accounIDs, err := q.CreateAccounts([]string{account.Address()}, 1) + accounIDs, err := q.CreateAccounts(ctx, []string{account.Address()}, 1) tt.Assert.NoError(err) err = effectBuilder.Add( + ctx, accounIDs[account.Address()], toid.New(fixture.Ledger.Sequence, 1, 1).ToInt64(), 1, @@ -283,7 +287,7 @@ func FeeBumpScenario(tt *test.T, q *Q, successful bool) FeeBumpFixture { details, ) tt.Assert.NoError(err) - tt.Assert.NoError(effectBuilder.Exec()) + tt.Assert.NoError(effectBuilder.Exec(ctx)) fixture.Transaction = Transaction{ TransactionWithoutLedger: TransactionWithoutLedger{ @@ -333,7 +337,7 @@ func FeeBumpScenario(tt *test.T, q *Q, successful bool) FeeBumpFixture { }, } - results, err := q.TransactionsByIDs(fixture.Transaction.ID, fixture.NormalTransaction.ID) + results, err := q.TransactionsByIDs(ctx, fixture.Transaction.ID, fixture.NormalTransaction.ID) tt.Assert.NoError(err) fixture.Transaction.CreatedAt = results[fixture.Transaction.ID].CreatedAt diff --git a/services/horizon/internal/db2/history/history_claimable_balances.go b/services/horizon/internal/db2/history/history_claimable_balances.go index c8d5527366..371323c5f9 100644 --- a/services/horizon/internal/db2/history/history_claimable_balances.go +++ b/services/horizon/internal/db2/history/history_claimable_balances.go @@ -2,6 +2,7 @@ package history import ( "bytes" + "context" "sort" sq "github.com/Masterminds/squirrel" @@ -13,14 +14,14 @@ import ( // QHistoryClaimableBalances defines account related queries. type QHistoryClaimableBalances interface { - CreateHistoryClaimableBalances(ids []xdr.ClaimableBalanceId, batchSize int) (map[string]int64, error) + CreateHistoryClaimableBalances(ctx context.Context, ids []xdr.ClaimableBalanceId, batchSize int) (map[string]int64, error) NewOperationClaimableBalanceBatchInsertBuilder(maxBatchSize int) OperationClaimableBalanceBatchInsertBuilder NewTransactionClaimableBalanceBatchInsertBuilder(maxBatchSize int) TransactionClaimableBalanceBatchInsertBuilder } // CreateHistoryClaimableBalances creates rows in the history_claimable_balances table for a given list of ids. // CreateHistoryClaimableBalances returns a mapping of id to its corresponding internal id in the history_claimable_balances table -func (q *Q) CreateHistoryClaimableBalances(ids []xdr.ClaimableBalanceId, batchSize int) (map[string]int64, error) { +func (q *Q) CreateHistoryClaimableBalances(ctx context.Context, ids []xdr.ClaimableBalanceId, batchSize int) (map[string]int64, error) { builder := &db.BatchInsertBuilder{ Table: q.GetTable("history_claimable_balances"), MaxBatchSize: batchSize, @@ -33,7 +34,7 @@ func (q *Q) CreateHistoryClaimableBalances(ids []xdr.ClaimableBalanceId, batchSi return bytes.Compare(ids[i].V0[:], ids[j].V0[:]) < 0 }) for _, id := range ids { - err := builder.Row(map[string]interface{}{ + err := builder.Row(ctx, map[string]interface{}{ "claimable_balance_id": id, }) if err != nil { @@ -41,7 +42,7 @@ func (q *Q) CreateHistoryClaimableBalances(ids []xdr.ClaimableBalanceId, batchSi } } - err := builder.Exec() + err := builder.Exec(ctx) if err != nil { return nil, errors.Wrap(err, "could not exec claimable balance insert builder") } @@ -57,7 +58,7 @@ func (q *Q) CreateHistoryClaimableBalances(ids []xdr.ClaimableBalanceId, batchSi } subset := ids[i:end] - cbs, err = q.ClaimableBalancesByIDs(subset) + cbs, err = q.ClaimableBalancesByIDs(ctx, subset) if err != nil { return nil, errors.Wrap(err, "could not select claimable balances") } @@ -83,24 +84,24 @@ type HistoryClaimableBalance struct { var selectHistoryClaimableBalance = sq.Select("hcb.*").From("history_claimable_balances hcb") // ClaimableBalancesByIDs loads rows from `history_claimable_balances`, by claimable_balance_id -func (q *Q) ClaimableBalancesByIDs(ids []xdr.ClaimableBalanceId) (dest []HistoryClaimableBalance, err error) { +func (q *Q) ClaimableBalancesByIDs(ctx context.Context, ids []xdr.ClaimableBalanceId) (dest []HistoryClaimableBalance, err error) { sql := selectHistoryClaimableBalance.Where(map[string]interface{}{ "hcb.claimable_balance_id": ids, // hcb.claimable_balance_id IN (...) }) - err = q.Select(&dest, sql) + err = q.Select(ctx, &dest, sql) return dest, err } // ClaimableBalanceByID loads a row from `history_claimable_balances`, by claimable_balance_id -func (q *Q) ClaimableBalanceByID(id xdr.ClaimableBalanceId) (dest HistoryClaimableBalance, err error) { +func (q *Q) ClaimableBalanceByID(ctx context.Context, id xdr.ClaimableBalanceId) (dest HistoryClaimableBalance, err error) { sql := selectHistoryClaimableBalance.Limit(1).Where("hcb.claimable_balance_id = ?", id) - err = q.Get(&dest, sql) + err = q.Get(ctx, &dest, sql) return dest, err } type OperationClaimableBalanceBatchInsertBuilder interface { - Add(operationID, internalID int64) error - Exec() error + Add(ctx context.Context, operationID, internalID int64) error + Exec(ctx context.Context) error } type operationClaimableBalanceBatchInsertBuilder struct { @@ -117,21 +118,21 @@ func (q *Q) NewOperationClaimableBalanceBatchInsertBuilder(maxBatchSize int) Ope } // Add adds a new operation claimable balance to the batch -func (i *operationClaimableBalanceBatchInsertBuilder) Add(operationID, internalID int64) error { - return i.builder.Row(map[string]interface{}{ +func (i *operationClaimableBalanceBatchInsertBuilder) Add(ctx context.Context, operationID, internalID int64) error { + return i.builder.Row(ctx, map[string]interface{}{ "history_operation_id": operationID, "history_claimable_balance_id": internalID, }) } // Exec flushes all pending operation claimable balances to the db -func (i *operationClaimableBalanceBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *operationClaimableBalanceBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } type TransactionClaimableBalanceBatchInsertBuilder interface { - Add(transactionID, internalID int64) error - Exec() error + Add(ctx context.Context, transactionID, internalID int64) error + Exec(ctx context.Context) error } type transactionClaimableBalanceBatchInsertBuilder struct { @@ -148,14 +149,14 @@ func (q *Q) NewTransactionClaimableBalanceBatchInsertBuilder(maxBatchSize int) T } // Add adds a new transaction claimable balance to the batch -func (i *transactionClaimableBalanceBatchInsertBuilder) Add(transactionID, internalID int64) error { - return i.builder.Row(map[string]interface{}{ +func (i *transactionClaimableBalanceBatchInsertBuilder) Add(ctx context.Context, transactionID, internalID int64) error { + return i.builder.Row(ctx, map[string]interface{}{ "history_transaction_id": transactionID, "history_claimable_balance_id": internalID, }) } // Exec flushes all pending transaction claimable balances to the db -func (i *transactionClaimableBalanceBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *transactionClaimableBalanceBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/ingestion.go b/services/horizon/internal/db2/history/ingestion.go index 686d7926b5..d88001e96f 100644 --- a/services/horizon/internal/db2/history/ingestion.go +++ b/services/horizon/internal/db2/history/ingestion.go @@ -1,12 +1,16 @@ package history +import ( + "context" +) + // TruncateIngestStateTables clears out ingestion state tables. // Ingestion state tables are horizon database tables populated by // the ingestion system using history archive snapshots. // Any horizon database tables which cannot be populated using // history archive snapshots will not be truncated. -func (q *Q) TruncateIngestStateTables() error { - return q.TruncateTables([]string{ +func (q *Q) TruncateIngestStateTables(ctx context.Context) error { + return q.TruncateTables(ctx, []string{ "accounts", "accounts_data", "accounts_signers", diff --git a/services/horizon/internal/db2/history/key_value.go b/services/horizon/internal/db2/history/key_value.go index 9214599b46..5a54ca73ea 100644 --- a/services/horizon/internal/db2/history/key_value.go +++ b/services/horizon/internal/db2/history/key_value.go @@ -1,6 +1,7 @@ package history import ( + "context" "database/sql" "strconv" @@ -22,8 +23,8 @@ const ( // it does not block the value and does not return error if the value // has not been previously set. // This is used in status reporting (ex. in root resource of Horizon). -func (q *Q) GetLastLedgerIngestNonBlocking() (uint32, error) { - lastIngestedLedger, err := q.getValueFromStore(lastLedgerKey, false) +func (q *Q) GetLastLedgerIngestNonBlocking(ctx context.Context) (uint32, error) { + lastIngestedLedger, err := q.getValueFromStore(ctx, lastLedgerKey, false) if err != nil { return 0, err } @@ -46,8 +47,8 @@ func (q *Q) GetLastLedgerIngestNonBlocking() (uint32, error) { // transactions.This behaviour is critical in distributed ingestion so do not change // it unless you know what you are doing. // The value can be set using UpdateLastLedgerIngest. -func (q *Q) GetLastLedgerIngest() (uint32, error) { - lastIngestedLedger, err := q.getValueFromStore(lastLedgerKey, true) +func (q *Q) GetLastLedgerIngest(ctx context.Context) (uint32, error) { + lastIngestedLedger, err := q.getValueFromStore(ctx, lastLedgerKey, true) if err != nil { return 0, err } @@ -68,8 +69,9 @@ func (q *Q) GetLastLedgerIngest() (uint32, error) { // UpdateLastLedgerIngest updates the last ledger ingested by ingest system. // Can be read using GetLastLedgerExpIngest. -func (q *Q) UpdateLastLedgerIngest(ledgerSequence uint32) error { +func (q *Q) UpdateLastLedgerIngest(ctx context.Context, ledgerSequence uint32) error { return q.updateValueInStore( + ctx, lastLedgerKey, strconv.FormatUint(uint64(ledgerSequence), 10), ) @@ -77,8 +79,8 @@ func (q *Q) UpdateLastLedgerIngest(ledgerSequence uint32) error { // GetIngestVersion returns the ingestion version. Returns zero // if there is no value. -func (q *Q) GetIngestVersion() (int, error) { - expVersion, err := q.getValueFromStore(ingestVersion, false) +func (q *Q) GetIngestVersion(ctx context.Context) (int, error) { + expVersion, err := q.getValueFromStore(ctx, ingestVersion, false) if err != nil { return 0, err } @@ -96,8 +98,9 @@ func (q *Q) GetIngestVersion() (int, error) { } // UpdateIngestVersion updates the ingestion version. -func (q *Q) UpdateIngestVersion(version int) error { +func (q *Q) UpdateIngestVersion(ctx context.Context, version int) error { return q.updateValueInStore( + ctx, ingestVersion, strconv.FormatUint(uint64(version), 10), ) @@ -105,8 +108,8 @@ func (q *Q) UpdateIngestVersion(version int) error { // GetExpStateInvalid returns true if the state was found to be invalid. // Returns false otherwise. -func (q *Q) GetExpStateInvalid() (bool, error) { - invalid, err := q.getValueFromStore(stateInvalid, false) +func (q *Q) GetExpStateInvalid(ctx context.Context) (bool, error) { + invalid, err := q.getValueFromStore(ctx, stateInvalid, false) if err != nil { return false, err } @@ -124,8 +127,9 @@ func (q *Q) GetExpStateInvalid() (bool, error) { } // UpdateExpStateInvalid updates the state invalid value. -func (q *Q) UpdateExpStateInvalid(val bool) error { +func (q *Q) UpdateExpStateInvalid(ctx context.Context, val bool) error { return q.updateValueInStore( + ctx, stateInvalid, strconv.FormatBool(val), ) @@ -133,8 +137,8 @@ func (q *Q) UpdateExpStateInvalid(val bool) error { // GetOfferCompactionSequence returns the sequence number corresponding to the // last time the offers table was compacted. -func (q *Q) GetOfferCompactionSequence() (uint32, error) { - sequence, err := q.getValueFromStore(offerCompactionSequence, false) +func (q *Q) GetOfferCompactionSequence(ctx context.Context) (uint32, error) { + sequence, err := q.getValueFromStore(ctx, offerCompactionSequence, false) if err != nil { return 0, err } @@ -152,8 +156,9 @@ func (q *Q) GetOfferCompactionSequence() (uint32, error) { // UpdateOfferCompactionSequence sets the sequence number corresponding to the // last time the offers table was compacted. -func (q *Q) UpdateOfferCompactionSequence(sequence uint32) error { +func (q *Q) UpdateOfferCompactionSequence(ctx context.Context, sequence uint32) error { return q.updateValueInStore( + ctx, offerCompactionSequence, strconv.FormatUint(uint64(sequence), 10), ) @@ -161,7 +166,7 @@ func (q *Q) UpdateOfferCompactionSequence(sequence uint32) error { // getValueFromStore returns a value for a given key from KV store. If value // is not present in the key value store "" will be returned. -func (q *Q) getValueFromStore(key string, forUpdate bool) (string, error) { +func (q *Q) getValueFromStore(ctx context.Context, key string, forUpdate bool) (string, error) { query := sq.Select("key_value_store.value"). From("key_value_store"). Where("key_value_store.key = ?", key) @@ -171,7 +176,7 @@ func (q *Q) getValueFromStore(key string, forUpdate bool) (string, error) { } var value string - if err := q.Get(&value, query); err != nil { + if err := q.Get(ctx, &value, query); err != nil { if errors.Cause(err) == sql.ErrNoRows { return "", nil } @@ -182,12 +187,12 @@ func (q *Q) getValueFromStore(key string, forUpdate bool) (string, error) { } // updateValueInStore updates a value for a given key in KV store -func (q *Q) updateValueInStore(key, value string) error { +func (q *Q) updateValueInStore(ctx context.Context, key, value string) error { query := sq.Insert("key_value_store"). Columns("key", "value"). Values(key, value). Suffix("ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value") - _, err := q.Exec(query) + _, err := q.Exec(ctx, query) return err } diff --git a/services/horizon/internal/db2/history/ledger.go b/services/horizon/internal/db2/history/ledger.go index ceb083e902..927295bd0d 100644 --- a/services/horizon/internal/db2/history/ledger.go +++ b/services/horizon/internal/db2/history/ledger.go @@ -1,6 +1,7 @@ package history import ( + "context" "encoding/hex" "fmt" "time" @@ -14,12 +15,12 @@ import ( ) // LedgerBySequence loads the single ledger at `seq` into `dest` -func (q *Q) LedgerBySequence(dest interface{}, seq int32) error { +func (q *Q) LedgerBySequence(ctx context.Context, dest interface{}, seq int32) error { sql := selectLedger. Limit(1). Where("sequence = ?", seq) - return q.Get(dest, sql) + return q.Get(ctx, dest, sql) } // Ledgers provides a helper to filter rows from the `history_ledgers` table @@ -33,7 +34,7 @@ func (q *Q) Ledgers() *LedgersQ { // LedgersBySequence loads the a set of ledgers identified by the sequences // `seqs` into `dest`. -func (q *Q) LedgersBySequence(dest interface{}, seqs ...int32) error { +func (q *Q) LedgersBySequence(ctx context.Context, dest interface{}, seqs ...int32) error { if len(seqs) == 0 { return errors.New("no sequence arguments provided") } @@ -46,15 +47,15 @@ func (q *Q) LedgersBySequence(dest interface{}, seqs ...int32) error { sql := selectLedger.Where(in, whereArgs...) - return q.Select(dest, sql) + return q.Select(ctx, dest, sql) } // LedgerCapacityUsageStats returns ledger capacity stats for the last 5 ledgers. // Currently, we hard code the query to return the last 5 ledgers. // TODO: make the number of ledgers configurable. -func (q *Q) LedgerCapacityUsageStats(currentSeq int32, dest *LedgerCapacityUsageStats) error { +func (q *Q) LedgerCapacityUsageStats(ctx context.Context, currentSeq int32, dest *LedgerCapacityUsageStats) error { const ledgers int32 = 5 - return q.GetRaw(dest, ` + return q.GetRaw(ctx, dest, ` SELECT ROUND(SUM(CAST(operation_count as decimal))/SUM(max_tx_set_size), 2) as ledger_capacity_usage FROM (SELECT hl.sequence, COALESCE(SUM(ht.operation_count), 0) as operation_count, hl.max_tx_set_size @@ -76,18 +77,19 @@ func (q *LedgersQ) Page(page db2.PageQuery) *LedgersQ { } // Select loads the results of the query specified by `q` into `dest`. -func (q *LedgersQ) Select(dest interface{}) error { +func (q *LedgersQ) Select(ctx context.Context, dest interface{}) error { if q.Err != nil { return q.Err } - q.Err = q.parent.Select(dest, q.sql) + q.Err = q.parent.Select(ctx, dest, q.sql) return q.Err } // QLedgers defines ingestion ledger related queries. type QLedgers interface { InsertLedger( + ctx context.Context, ledger xdr.LedgerHeaderHistoryEntry, successTxsCount int, failedTxsCount int, @@ -99,7 +101,7 @@ type QLedgers interface { // InsertLedger creates a row in the history_ledgers table. // Returns number of rows affected and error. -func (q *Q) InsertLedger( +func (q *Q) InsertLedger(ctx context.Context, ledger xdr.LedgerHeaderHistoryEntry, successTxsCount int, failedTxsCount int, @@ -120,7 +122,7 @@ func (q *Q) InsertLedger( } sql := sq.Insert("history_ledgers").SetMap(m) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } diff --git a/services/horizon/internal/db2/history/ledger_cache.go b/services/horizon/internal/db2/history/ledger_cache.go index f966ab706a..3318048ef7 100644 --- a/services/horizon/internal/db2/history/ledger_cache.go +++ b/services/horizon/internal/db2/history/ledger_cache.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stellar/go/support/errors" ) @@ -18,7 +20,7 @@ func (lc *LedgerCache) Queue(seq int32) { // Load loads a batch of ledgers identified by `sequences`, using `q`, // and populates the cache with the results -func (lc *LedgerCache) Load(q *Q) error { +func (lc *LedgerCache) Load(ctx context.Context, q *Q) error { lc.lock.Lock() defer lc.lock.Unlock() @@ -32,7 +34,7 @@ func (lc *LedgerCache) Load(q *Q) error { } var ledgers []Ledger - err := q.LedgersBySequence(&ledgers, sequences...) + err := q.LedgersBySequence(ctx, &ledgers, sequences...) if err != nil { return errors.Wrap(err, "failed to load ledger batch") } diff --git a/services/horizon/internal/db2/history/ledger_cache_test.go b/services/horizon/internal/db2/history/ledger_cache_test.go index ca758624ad..17720a72fe 100644 --- a/services/horizon/internal/db2/history/ledger_cache_test.go +++ b/services/horizon/internal/db2/history/ledger_cache_test.go @@ -16,7 +16,7 @@ func TestLedgerCache(t *testing.T) { lc.Queue(2) lc.Queue(3) - err := lc.Load(q) + err := lc.Load(tt.Ctx, q) if tt.Assert.NoError(err) { tt.Assert.Contains(lc.Records, int32(2)) diff --git a/services/horizon/internal/db2/history/ledger_test.go b/services/horizon/internal/db2/history/ledger_test.go index 8f639fd624..7d5b2af05e 100644 --- a/services/horizon/internal/db2/history/ledger_test.go +++ b/services/horizon/internal/db2/history/ledger_test.go @@ -21,22 +21,22 @@ func TestLedgerQueries(t *testing.T) { // Test LedgerBySequence var l Ledger - err := q.LedgerBySequence(&l, 3) + err := q.LedgerBySequence(tt.Ctx, &l, 3) tt.Assert.NoError(err) - err = q.LedgerBySequence(&l, 100000) + err = q.LedgerBySequence(tt.Ctx, &l, 100000) tt.Assert.Equal(err, sql.ErrNoRows) // Test Ledgers() ls := []Ledger{} - err = q.Ledgers().Select(&ls) + err = q.Ledgers().Select(tt.Ctx, &ls) if tt.Assert.NoError(err) { tt.Assert.Len(ls, 3) } // LedgersBySequence - err = q.LedgersBySequence(&ls, 1, 2, 3) + err = q.LedgersBySequence(tt.Ctx, &ls, 1, 2, 3) if tt.Assert.NoError(err) { tt.Assert.Len(ls, 3) @@ -116,7 +116,7 @@ func TestInsertLedger(t *testing.T) { tt.Assert.NoError(err) expectedLedger.LedgerHeaderXDR = null.NewString(ledgerHeaderBase64, true) - rowsAffected, err := q.InsertLedger( + rowsAffected, err := q.InsertLedger(tt.Ctx, ledgerEntry, 12, 3, @@ -128,7 +128,7 @@ func TestInsertLedger(t *testing.T) { tt.Assert.Equal(rowsAffected, int64(1)) var ledgerFromDB Ledger - err = q.LedgerBySequence(&ledgerFromDB, 69859) + err = q.LedgerBySequence(tt.Ctx, &ledgerFromDB, 69859) tt.Assert.NoError(err) expectedLedger.CreatedAt = ledgerFromDB.CreatedAt diff --git a/services/horizon/internal/db2/history/main.go b/services/horizon/internal/db2/history/main.go index 0c9f0fb3ed..e5ac0903e5 100644 --- a/services/horizon/internal/db2/history/main.go +++ b/services/horizon/internal/db2/history/main.go @@ -3,6 +3,7 @@ package history import ( + "context" "database/sql" "database/sql/driver" "encoding/json" @@ -215,8 +216,8 @@ type AccountEntry struct { } type AccountsBatchInsertBuilder interface { - Add(entry xdr.LedgerEntry) error - Exec() error + Add(ctx context.Context, entry xdr.LedgerEntry) error + Exec(ctx context.Context) error } type IngestionQ interface { @@ -237,32 +238,32 @@ type IngestionQ interface { QSigners //QTrades NewTradeBatchInsertBuilder(maxBatchSize int) TradeBatchInsertBuilder - CreateAssets(assets []xdr.Asset, batchSize int) (map[string]Asset, error) + CreateAssets(ctx context.Context, assets []xdr.Asset, batchSize int) (map[string]Asset, error) QTransactions QTrustLines - Begin() error - BeginTx(*sql.TxOptions) error - Commit() error + Begin(context.Context) error + BeginTx(context.Context, *sql.TxOptions) error + Commit(context.Context) error CloneIngestionQ() IngestionQ - Rollback() error + Rollback(context.Context) error GetTx() *sqlx.Tx - GetIngestVersion() (int, error) - UpdateExpStateInvalid(bool) error - UpdateIngestVersion(int) error - GetExpStateInvalid() (bool, error) - GetLatestHistoryLedger() (uint32, error) - GetOfferCompactionSequence() (uint32, error) - TruncateIngestStateTables() error - DeleteRangeAll(start, end int64) error + GetIngestVersion(context.Context) (int, error) + UpdateExpStateInvalid(context.Context, bool) error + UpdateIngestVersion(context.Context, int) error + GetExpStateInvalid(context.Context) (bool, error) + GetLatestHistoryLedger(context.Context) (uint32, error) + GetOfferCompactionSequence(context.Context) (uint32, error) + TruncateIngestStateTables(context.Context) error + DeleteRangeAll(ctx context.Context, start, end int64) error } // QAccounts defines account related queries. type QAccounts interface { NewAccountsBatchInsertBuilder(maxBatchSize int) AccountsBatchInsertBuilder - GetAccountsByIDs(ids []string) ([]AccountEntry, error) - UpsertAccounts(accounts []xdr.LedgerEntry) error - RemoveAccount(accountID string) (int64, error) + GetAccountsByIDs(ctx context.Context, ids []string) ([]AccountEntry, error) + UpsertAccounts(ctx context.Context, accounts []xdr.LedgerEntry) error + RemoveAccount(ctx context.Context, accountID string) (int64, error) } // AccountSigner is a row of data from the `accounts_signers` table @@ -274,8 +275,8 @@ type AccountSigner struct { } type AccountSignersBatchInsertBuilder interface { - Add(signer AccountSigner) error - Exec() error + Add(ctx context.Context, signer AccountSigner) error + Exec(ctx context.Context) error } // accountSignersBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -295,8 +296,8 @@ type Data struct { type AccountDataValue []byte type AccountDataBatchInsertBuilder interface { - Add(entry xdr.LedgerEntry) error - Exec() error + Add(ctx context.Context, entry xdr.LedgerEntry) error + Exec(ctx context.Context) error } // accountDataBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -307,11 +308,11 @@ type accountDataBatchInsertBuilder struct { // QData defines account data related queries. type QData interface { NewAccountDataBatchInsertBuilder(maxBatchSize int) AccountDataBatchInsertBuilder - CountAccountsData() (int, error) - GetAccountDataByKeys(keys []xdr.LedgerKeyData) ([]Data, error) - InsertAccountData(entry xdr.LedgerEntry) (int64, error) - UpdateAccountData(entry xdr.LedgerEntry) (int64, error) - RemoveAccountData(key xdr.LedgerKeyData) (int64, error) + CountAccountsData(ctx context.Context) (int, error) + GetAccountDataByKeys(ctx context.Context, keys []xdr.LedgerKeyData) ([]Data, error) + InsertAccountData(ctx context.Context, entry xdr.LedgerEntry) (int64, error) + UpdateAccountData(ctx context.Context, entry xdr.LedgerEntry) (int64, error) + RemoveAccountData(ctx context.Context, key xdr.LedgerKeyData) (int64, error) } // Asset is a row of data from the `history_assets` table @@ -400,17 +401,17 @@ func (e *ExpAssetStatBalances) Scan(src interface{}) error { // QAssetStats defines exp_asset_stats related queries. type QAssetStats interface { - InsertAssetStats(stats []ExpAssetStat, batchSize int) error - InsertAssetStat(stat ExpAssetStat) (int64, error) - UpdateAssetStat(stat ExpAssetStat) (int64, error) - GetAssetStat(assetType xdr.AssetType, assetCode, assetIssuer string) (ExpAssetStat, error) - RemoveAssetStat(assetType xdr.AssetType, assetCode, assetIssuer string) (int64, error) - GetAssetStats(assetCode, assetIssuer string, page db2.PageQuery) ([]ExpAssetStat, error) - CountTrustLines() (int, error) + InsertAssetStats(ctx context.Context, stats []ExpAssetStat, batchSize int) error + InsertAssetStat(ctx context.Context, stat ExpAssetStat) (int64, error) + UpdateAssetStat(ctx context.Context, stat ExpAssetStat) (int64, error) + GetAssetStat(ctx context.Context, assetType xdr.AssetType, assetCode, assetIssuer string) (ExpAssetStat, error) + RemoveAssetStat(ctx context.Context, assetType xdr.AssetType, assetCode, assetIssuer string) (int64, error) + GetAssetStats(ctx context.Context, assetCode, assetIssuer string, page db2.PageQuery) ([]ExpAssetStat, error) + CountTrustLines(ctx context.Context) (int, error) } type QCreateAccountsHistory interface { - CreateAccounts(addresses []string, maxBatchSize int) (map[string]int64, error) + CreateAccounts(ctx context.Context, addresses []string, maxBatchSize int) (map[string]int64, error) } // Effect is a row of data from the `history_effects` table @@ -580,8 +581,8 @@ type Offer struct { } type OffersBatchInsertBuilder interface { - Add(offer Offer) error - Exec() error + Add(ctx context.Context, offer Offer) error + Exec(ctx context.Context) error } // offersBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -608,15 +609,15 @@ type Q struct { // QSigners defines signer related queries. type QSigners interface { - GetLastLedgerIngestNonBlocking() (uint32, error) - GetLastLedgerIngest() (uint32, error) - UpdateLastLedgerIngest(ledgerSequence uint32) error - AccountsForSigner(signer string, page db2.PageQuery) ([]AccountSigner, error) + GetLastLedgerIngestNonBlocking(ctx context.Context) (uint32, error) + GetLastLedgerIngest(ctx context.Context) (uint32, error) + UpdateLastLedgerIngest(ctx context.Context, ledgerSequence uint32) error + AccountsForSigner(ctx context.Context, signer string, page db2.PageQuery) ([]AccountSigner, error) NewAccountSignersBatchInsertBuilder(maxBatchSize int) AccountSignersBatchInsertBuilder - CreateAccountSigner(account, signer string, weight int32, sponsor *string) (int64, error) - RemoveAccountSigner(account, signer string) (int64, error) - SignersForAccounts(accounts []string) ([]AccountSigner, error) - CountAccounts() (int, error) + CreateAccountSigner(ctx context.Context, account, signer string, weight int32, sponsor *string) (int64, error) + RemoveAccountSigner(ctx context.Context, account, signer string) (int64, error) + SignersForAccounts(ctx context.Context, accounts []string) ([]AccountSigner, error) + CountAccounts(ctx context.Context) (int, error) } // OffersQuery is a helper struct to configure queries to offers @@ -709,16 +710,16 @@ type TrustLine struct { // QTrustLines defines trust lines related queries. type QTrustLines interface { NewTrustLinesBatchInsertBuilder(maxBatchSize int) TrustLinesBatchInsertBuilder - GetTrustLinesByKeys(keys []xdr.LedgerKeyTrustLine) ([]TrustLine, error) - InsertTrustLine(entry xdr.LedgerEntry) (int64, error) - UpdateTrustLine(entry xdr.LedgerEntry) (int64, error) - UpsertTrustLines(entries []xdr.LedgerEntry) error - RemoveTrustLine(key xdr.LedgerKeyTrustLine) (int64, error) + GetTrustLinesByKeys(ctx context.Context, keys []xdr.LedgerKeyTrustLine) ([]TrustLine, error) + InsertTrustLine(ctx context.Context, entry xdr.LedgerEntry) (int64, error) + UpdateTrustLine(ctx context.Context, entry xdr.LedgerEntry) (int64, error) + UpsertTrustLines(ctx context.Context, entries []xdr.LedgerEntry) error + RemoveTrustLine(ctx context.Context, key xdr.LedgerKeyTrustLine) (int64, error) } type TrustLinesBatchInsertBuilder interface { - Add(entry xdr.LedgerEntry) error - Exec() error + Add(ctx context.Context, entry xdr.LedgerEntry) error + Exec(ctx context.Context) error } // trustLinesBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -772,31 +773,31 @@ func (q *Q) NewTrustLinesBatchInsertBuilder(maxBatchSize int) TrustLinesBatchIns } // ElderLedger loads the oldest ledger known to the history database -func (q *Q) ElderLedger(dest interface{}) error { - return q.GetRaw(dest, `SELECT COALESCE(MIN(sequence), 0) FROM history_ledgers`) +func (q *Q) ElderLedger(ctx context.Context, dest interface{}) error { + return q.GetRaw(ctx, dest, `SELECT COALESCE(MIN(sequence), 0) FROM history_ledgers`) } // GetLatestHistoryLedger loads the latest known ledger. Returns 0 if no ledgers in // `history_ledgers` table. -func (q *Q) GetLatestHistoryLedger() (uint32, error) { +func (q *Q) GetLatestHistoryLedger(ctx context.Context) (uint32, error) { var value uint32 - err := q.LatestLedger(&value) + err := q.LatestLedger(ctx, &value) return value, err } // LatestLedger loads the latest known ledger -func (q *Q) LatestLedger(dest interface{}) error { - return q.GetRaw(dest, `SELECT COALESCE(MAX(sequence), 0) FROM history_ledgers`) +func (q *Q) LatestLedger(ctx context.Context, dest interface{}) error { + return q.GetRaw(ctx, dest, `SELECT COALESCE(MAX(sequence), 0) FROM history_ledgers`) } // LatestLedgerSequenceClosedAt loads the latest known ledger sequence and close time, // returns empty values if no ledgers in a DB. -func (q *Q) LatestLedgerSequenceClosedAt() (int32, time.Time, error) { +func (q *Q) LatestLedgerSequenceClosedAt(ctx context.Context) (int32, time.Time, error) { ledger := struct { Sequence int32 `db:"sequence"` ClosedAt time.Time `db:"closed_at"` }{} - err := q.GetRaw(&ledger, `SELECT sequence, closed_at FROM history_ledgers ORDER BY sequence DESC LIMIT 1`) + err := q.GetRaw(ctx, &ledger, `SELECT sequence, closed_at FROM history_ledgers ORDER BY sequence DESC LIMIT 1`) if err == sql.ErrNoRows { // Will return empty values return ledger.Sequence, ledger.ClosedAt, nil @@ -806,8 +807,8 @@ func (q *Q) LatestLedgerSequenceClosedAt() (int32, time.Time, error) { // LatestLedgerBaseFeeAndSequence loads the latest known ledger's base fee and // sequence number. -func (q *Q) LatestLedgerBaseFeeAndSequence(dest interface{}) error { - return q.GetRaw(dest, ` +func (q *Q) LatestLedgerBaseFeeAndSequence(ctx context.Context, dest interface{}) error { + return q.GetRaw(ctx, dest, ` SELECT base_fee, sequence FROM history_ledgers WHERE sequence = (SELECT COALESCE(MAX(sequence), 0) FROM history_ledgers) @@ -821,32 +822,32 @@ func (q *Q) CloneIngestionQ() IngestionQ { // DeleteRangeAll deletes a range of rows from all history tables between // `start` and `end` (exclusive). -func (q *Q) DeleteRangeAll(start, end int64) error { - err := q.DeleteRange(start, end, "history_effects", "history_operation_id") +func (q *Q) DeleteRangeAll(ctx context.Context, start, end int64) error { + err := q.DeleteRange(ctx, start, end, "history_effects", "history_operation_id") if err != nil { return errors.Wrap(err, "Error clearing history_effects") } - err = q.DeleteRange(start, end, "history_operation_participants", "history_operation_id") + err = q.DeleteRange(ctx, start, end, "history_operation_participants", "history_operation_id") if err != nil { return errors.Wrap(err, "Error clearing history_operation_participants") } - err = q.DeleteRange(start, end, "history_operations", "id") + err = q.DeleteRange(ctx, start, end, "history_operations", "id") if err != nil { return errors.Wrap(err, "Error clearing history_operations") } - err = q.DeleteRange(start, end, "history_transaction_participants", "history_transaction_id") + err = q.DeleteRange(ctx, start, end, "history_transaction_participants", "history_transaction_id") if err != nil { return errors.Wrap(err, "Error clearing history_transaction_participants") } - err = q.DeleteRange(start, end, "history_transactions", "id") + err = q.DeleteRange(ctx, start, end, "history_transactions", "id") if err != nil { return errors.Wrap(err, "Error clearing history_transactions") } - err = q.DeleteRange(start, end, "history_ledgers", "id") + err = q.DeleteRange(ctx, start, end, "history_ledgers", "id") if err != nil { return errors.Wrap(err, "Error clearing history_ledgers") } - err = q.DeleteRange(start, end, "history_trades", "history_operation_id") + err = q.DeleteRange(ctx, start, end, "history_trades", "history_operation_id") if err != nil { return errors.Wrap(err, "Error clearing history_trades") } diff --git a/services/horizon/internal/db2/history/main_test.go b/services/horizon/internal/db2/history/main_test.go index d2b966f7c9..c94154b463 100644 --- a/services/horizon/internal/db2/history/main_test.go +++ b/services/horizon/internal/db2/history/main_test.go @@ -14,7 +14,7 @@ func TestLatestLedger(t *testing.T) { q := &Q{tt.HorizonSession()} var seq int - err := q.LatestLedger(&seq) + err := q.LatestLedger(tt.Ctx, &seq) if tt.Assert.NoError(err) { tt.Assert.Equal(3, seq) @@ -27,7 +27,7 @@ func TestLatestLedgerSequenceClosedAt(t *testing.T) { defer tt.Finish() q := &Q{tt.HorizonSession()} - sequence, closedAt, err := q.LatestLedgerSequenceClosedAt() + sequence, closedAt, err := q.LatestLedgerSequenceClosedAt(tt.Ctx) if tt.Assert.NoError(err) { tt.Assert.Equal(int32(3), sequence) tt.Assert.Equal("2019-10-31T13:19:46Z", closedAt.Format(time.RFC3339)) @@ -35,7 +35,7 @@ func TestLatestLedgerSequenceClosedAt(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) - sequence, closedAt, err = q.LatestLedgerSequenceClosedAt() + sequence, closedAt, err = q.LatestLedgerSequenceClosedAt(tt.Ctx) if tt.Assert.NoError(err) { tt.Assert.Equal(int32(0), sequence) tt.Assert.Equal("0001-01-01T00:00:00Z", closedAt.Format(time.RFC3339)) @@ -48,7 +48,7 @@ func TestGetLatestHistoryLedgerEmptyDB(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - value, err := q.GetLatestHistoryLedger() + value, err := q.GetLatestHistoryLedger(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(uint32(0), value) } @@ -60,7 +60,7 @@ func TestElderLedger(t *testing.T) { q := &Q{tt.HorizonSession()} var seq int - err := q.ElderLedger(&seq) + err := q.ElderLedger(tt.Ctx, &seq) if tt.Assert.NoError(err) { tt.Assert.Equal(1, seq) diff --git a/services/horizon/internal/db2/history/mock_account_data_batch_insert_builder.go b/services/horizon/internal/db2/history/mock_account_data_batch_insert_builder.go index 27dc38b3af..7f2d2173c9 100644 --- a/services/horizon/internal/db2/history/mock_account_data_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/mock_account_data_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stellar/go/xdr" "github.com/stretchr/testify/mock" ) @@ -9,12 +10,12 @@ type MockAccountDataBatchInsertBuilder struct { mock.Mock } -func (m *MockAccountDataBatchInsertBuilder) Add(entry xdr.LedgerEntry) error { - a := m.Called(entry) +func (m *MockAccountDataBatchInsertBuilder) Add(ctx context.Context, entry xdr.LedgerEntry) error { + a := m.Called(ctx, entry) return a.Error(0) } -func (m *MockAccountDataBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockAccountDataBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_account_signers_batch_insert_builder.go b/services/horizon/internal/db2/history/mock_account_signers_batch_insert_builder.go index d40a737a9a..3f786f65ac 100644 --- a/services/horizon/internal/db2/history/mock_account_signers_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/mock_account_signers_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" ) @@ -8,12 +9,12 @@ type MockAccountSignersBatchInsertBuilder struct { mock.Mock } -func (m *MockAccountSignersBatchInsertBuilder) Add(signer AccountSigner) error { - a := m.Called(signer) +func (m *MockAccountSignersBatchInsertBuilder) Add(ctx context.Context, signer AccountSigner) error { + a := m.Called(ctx, signer) return a.Error(0) } -func (m *MockAccountSignersBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockAccountSignersBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_effect_batch_insert_builder.go b/services/horizon/internal/db2/history/mock_effect_batch_insert_builder.go index b5ceecde50..87777a70ff 100644 --- a/services/horizon/internal/db2/history/mock_effect_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/mock_effect_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" ) @@ -10,14 +11,14 @@ type MockEffectBatchInsertBuilder struct { } // Add mock -func (m *MockEffectBatchInsertBuilder) Add( +func (m *MockEffectBatchInsertBuilder) Add(ctx context.Context, accountID int64, operationID int64, order uint32, effectType EffectType, details []byte, ) error { - a := m.Called( + a := m.Called(ctx, accountID, operationID, order, @@ -28,7 +29,7 @@ func (m *MockEffectBatchInsertBuilder) Add( } // Exec mock -func (m *MockEffectBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockEffectBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_offers_batch_insert_builder.go b/services/horizon/internal/db2/history/mock_offers_batch_insert_builder.go index bc6a358291..75e88f3263 100644 --- a/services/horizon/internal/db2/history/mock_offers_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/mock_offers_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" ) @@ -8,12 +9,12 @@ type MockOffersBatchInsertBuilder struct { mock.Mock } -func (m *MockOffersBatchInsertBuilder) Add(row Offer) error { - a := m.Called(row) +func (m *MockOffersBatchInsertBuilder) Add(ctx context.Context, row Offer) error { + a := m.Called(ctx, row) return a.Error(0) } -func (m *MockOffersBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockOffersBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_operation_participant_batch_insert_builder.go b/services/horizon/internal/db2/history/mock_operation_participant_batch_insert_builder.go index b6cbcb91f1..014763f989 100644 --- a/services/horizon/internal/db2/history/mock_operation_participant_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/mock_operation_participant_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" ) @@ -10,13 +11,13 @@ type MockOperationParticipantBatchInsertBuilder struct { } // Add mock -func (m *MockOperationParticipantBatchInsertBuilder) Add(operationID int64, accountID int64) error { - a := m.Called(operationID, accountID) +func (m *MockOperationParticipantBatchInsertBuilder) Add(ctx context.Context, operationID int64, accountID int64) error { + a := m.Called(ctx, operationID, accountID) return a.Error(0) } // Exec mock -func (m *MockOperationParticipantBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockOperationParticipantBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_operations_batch_insert_builder.go b/services/horizon/internal/db2/history/mock_operations_batch_insert_builder.go index 6b9f2e068c..a2f00f1fb7 100644 --- a/services/horizon/internal/db2/history/mock_operations_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/mock_operations_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stellar/go/xdr" "github.com/stretchr/testify/mock" ) @@ -11,7 +12,7 @@ type MockOperationsBatchInsertBuilder struct { } // Add mock -func (m *MockOperationsBatchInsertBuilder) Add( +func (m *MockOperationsBatchInsertBuilder) Add(ctx context.Context, id int64, transactionID int64, applicationOrder uint32, @@ -19,7 +20,7 @@ func (m *MockOperationsBatchInsertBuilder) Add( details []byte, sourceAccount string, ) error { - a := m.Called( + a := m.Called(ctx, id, transactionID, applicationOrder, @@ -31,7 +32,7 @@ func (m *MockOperationsBatchInsertBuilder) Add( } // Exec mock -func (m *MockOperationsBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockOperationsBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_q_accounts.go b/services/horizon/internal/db2/history/mock_q_accounts.go index 0e17d4db26..3db8f7c91d 100644 --- a/services/horizon/internal/db2/history/mock_q_accounts.go +++ b/services/horizon/internal/db2/history/mock_q_accounts.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" "github.com/stellar/go/xdr" @@ -11,8 +12,8 @@ type MockQAccounts struct { mock.Mock } -func (m *MockQAccounts) GetAccountsByIDs(ids []string) ([]AccountEntry, error) { - a := m.Called(ids) +func (m *MockQAccounts) GetAccountsByIDs(ctx context.Context, ids []string) ([]AccountEntry, error) { + a := m.Called(ctx, ids) return a.Get(0).([]AccountEntry), a.Error(1) } @@ -21,12 +22,12 @@ func (m *MockQAccounts) NewAccountsBatchInsertBuilder(maxBatchSize int) Accounts return a.Get(0).(AccountsBatchInsertBuilder) } -func (m *MockQAccounts) UpsertAccounts(accounts []xdr.LedgerEntry) error { - a := m.Called(accounts) +func (m *MockQAccounts) UpsertAccounts(ctx context.Context, accounts []xdr.LedgerEntry) error { + a := m.Called(ctx, accounts) return a.Error(0) } -func (m *MockQAccounts) RemoveAccount(accountID string) (int64, error) { - a := m.Called(accountID) +func (m *MockQAccounts) RemoveAccount(ctx context.Context, accountID string) (int64, error) { + a := m.Called(ctx, accountID) return a.Get(0).(int64), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_q_asset_stats.go b/services/horizon/internal/db2/history/mock_q_asset_stats.go index f172792b1b..17334039e8 100644 --- a/services/horizon/internal/db2/history/mock_q_asset_stats.go +++ b/services/horizon/internal/db2/history/mock_q_asset_stats.go @@ -1,9 +1,12 @@ package history import ( + "context" + + "github.com/stretchr/testify/mock" + "github.com/stellar/go/services/horizon/internal/db2" "github.com/stellar/go/xdr" - "github.com/stretchr/testify/mock" ) // MockQAssetStats is a mock implementation of the QAssetStats interface @@ -11,37 +14,37 @@ type MockQAssetStats struct { mock.Mock } -func (m *MockQAssetStats) InsertAssetStats(assetStats []ExpAssetStat, batchSize int) error { - a := m.Called(assetStats, batchSize) +func (m *MockQAssetStats) InsertAssetStats(ctx context.Context, assetStats []ExpAssetStat, batchSize int) error { + a := m.Called(ctx, assetStats, batchSize) return a.Error(0) } -func (m *MockQAssetStats) InsertAssetStat(assetStat ExpAssetStat) (int64, error) { - a := m.Called(assetStat) +func (m *MockQAssetStats) InsertAssetStat(ctx context.Context, assetStat ExpAssetStat) (int64, error) { + a := m.Called(ctx, assetStat) return a.Get(0).(int64), a.Error(1) } -func (m *MockQAssetStats) UpdateAssetStat(assetStat ExpAssetStat) (int64, error) { - a := m.Called(assetStat) +func (m *MockQAssetStats) UpdateAssetStat(ctx context.Context, assetStat ExpAssetStat) (int64, error) { + a := m.Called(ctx, assetStat) return a.Get(0).(int64), a.Error(1) } -func (m *MockQAssetStats) GetAssetStat(assetType xdr.AssetType, assetCode, assetIssuer string) (ExpAssetStat, error) { - a := m.Called(assetType, assetCode, assetIssuer) +func (m *MockQAssetStats) GetAssetStat(ctx context.Context, assetType xdr.AssetType, assetCode, assetIssuer string) (ExpAssetStat, error) { + a := m.Called(ctx, assetType, assetCode, assetIssuer) return a.Get(0).(ExpAssetStat), a.Error(1) } -func (m *MockQAssetStats) RemoveAssetStat(assetType xdr.AssetType, assetCode, assetIssuer string) (int64, error) { - a := m.Called(assetType, assetCode, assetIssuer) +func (m *MockQAssetStats) RemoveAssetStat(ctx context.Context, assetType xdr.AssetType, assetCode, assetIssuer string) (int64, error) { + a := m.Called(ctx, assetType, assetCode, assetIssuer) return a.Get(0).(int64), a.Error(1) } -func (m *MockQAssetStats) GetAssetStats(assetCode, assetIssuer string, page db2.PageQuery) ([]ExpAssetStat, error) { - a := m.Called(assetCode, assetIssuer, page) +func (m *MockQAssetStats) GetAssetStats(ctx context.Context, assetCode, assetIssuer string, page db2.PageQuery) ([]ExpAssetStat, error) { + a := m.Called(ctx, assetCode, assetIssuer, page) return a.Get(0).([]ExpAssetStat), a.Error(1) } -func (m *MockQAssetStats) CountTrustLines() (int, error) { - a := m.Called() +func (m *MockQAssetStats) CountTrustLines(ctx context.Context) (int, error) { + a := m.Called(ctx) return a.Get(0).(int), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_q_claimable_balances.go b/services/horizon/internal/db2/history/mock_q_claimable_balances.go index 0354afa944..c50e81603e 100644 --- a/services/horizon/internal/db2/history/mock_q_claimable_balances.go +++ b/services/horizon/internal/db2/history/mock_q_claimable_balances.go @@ -1,8 +1,11 @@ package history import ( - "github.com/stellar/go/xdr" + "context" + "github.com/stretchr/testify/mock" + + "github.com/stellar/go/xdr" ) // MockQClaimableBalances is a mock implementation of the QAccounts interface @@ -15,23 +18,23 @@ func (m *MockQClaimableBalances) NewClaimableBalancesBatchInsertBuilder(maxBatch return a.Get(0).(ClaimableBalancesBatchInsertBuilder) } -func (m *MockQClaimableBalances) CountClaimableBalances() (int, error) { - a := m.Called() +func (m *MockQClaimableBalances) CountClaimableBalances(ctx context.Context) (int, error) { + a := m.Called(ctx) return a.Get(0).(int), a.Error(1) } -func (m *MockQClaimableBalances) GetClaimableBalancesByID(ids []xdr.ClaimableBalanceId) ([]ClaimableBalance, error) { - a := m.Called(ids) +func (m *MockQClaimableBalances) GetClaimableBalancesByID(ctx context.Context, ids []xdr.ClaimableBalanceId) ([]ClaimableBalance, error) { + a := m.Called(ctx, ids) return a.Get(0).([]ClaimableBalance), a.Error(1) } -func (m *MockQClaimableBalances) UpdateClaimableBalance(entry xdr.LedgerEntry) (int64, error) { - a := m.Called(entry) +func (m *MockQClaimableBalances) UpdateClaimableBalance(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { + a := m.Called(ctx, entry) return a.Get(0).(int64), a.Error(1) } -func (m *MockQClaimableBalances) RemoveClaimableBalance(cBalance xdr.ClaimableBalanceEntry) (int64, error) { - a := m.Called(cBalance) +func (m *MockQClaimableBalances) RemoveClaimableBalance(ctx context.Context, cBalance xdr.ClaimableBalanceEntry) (int64, error) { + a := m.Called(ctx, cBalance) return a.Get(0).(int64), a.Error(1) } @@ -39,12 +42,12 @@ type MockClaimableBalancesBatchInsertBuilder struct { mock.Mock } -func (m *MockClaimableBalancesBatchInsertBuilder) Add(entry *xdr.LedgerEntry) error { - a := m.Called(entry) +func (m *MockClaimableBalancesBatchInsertBuilder) Add(ctx context.Context, entry *xdr.LedgerEntry) error { + a := m.Called(ctx, entry) return a.Error(0) } -func (m *MockClaimableBalancesBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockClaimableBalancesBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_q_data.go b/services/horizon/internal/db2/history/mock_q_data.go index 93986fc717..653ca56f6f 100644 --- a/services/horizon/internal/db2/history/mock_q_data.go +++ b/services/horizon/internal/db2/history/mock_q_data.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stretchr/testify/mock" "github.com/stellar/go/xdr" @@ -11,13 +13,13 @@ type MockQData struct { mock.Mock } -func (m *MockQData) GetAccountDataByKeys(keys []xdr.LedgerKeyData) ([]Data, error) { - a := m.Called() +func (m *MockQData) GetAccountDataByKeys(ctx context.Context, keys []xdr.LedgerKeyData) ([]Data, error) { + a := m.Called(ctx) return a.Get(0).([]Data), a.Error(1) } -func (m *MockQData) CountAccountsData() (int, error) { - a := m.Called() +func (m *MockQData) CountAccountsData(ctx context.Context) (int, error) { + a := m.Called(ctx) return a.Get(0).(int), a.Error(1) } @@ -26,17 +28,17 @@ func (m *MockQData) NewAccountDataBatchInsertBuilder(maxBatchSize int) AccountDa return a.Get(0).(AccountDataBatchInsertBuilder) } -func (m *MockQData) InsertAccountData(entry xdr.LedgerEntry) (int64, error) { - a := m.Called(entry) +func (m *MockQData) InsertAccountData(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { + a := m.Called(ctx, entry) return a.Get(0).(int64), a.Error(1) } -func (m *MockQData) UpdateAccountData(entry xdr.LedgerEntry) (int64, error) { - a := m.Called(entry) +func (m *MockQData) UpdateAccountData(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { + a := m.Called(ctx, entry) return a.Get(0).(int64), a.Error(1) } -func (m *MockQData) RemoveAccountData(key xdr.LedgerKeyData) (int64, error) { - a := m.Called(key) +func (m *MockQData) RemoveAccountData(ctx context.Context, key xdr.LedgerKeyData) (int64, error) { + a := m.Called(ctx, key) return a.Get(0).(int64), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_q_effects.go b/services/horizon/internal/db2/history/mock_q_effects.go index a9b1452f6d..d8bdd97765 100644 --- a/services/horizon/internal/db2/history/mock_q_effects.go +++ b/services/horizon/internal/db2/history/mock_q_effects.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" ) @@ -14,7 +15,7 @@ func (m *MockQEffects) NewEffectBatchInsertBuilder(maxBatchSize int) EffectBatch return a.Get(0).(EffectBatchInsertBuilder) } -func (m *MockQEffects) CreateAccounts(addresses []string, maxBatchSize int) (map[string]int64, error) { - a := m.Called(addresses, maxBatchSize) +func (m *MockQEffects) CreateAccounts(ctx context.Context, addresses []string, maxBatchSize int) (map[string]int64, error) { + a := m.Called(ctx, addresses, maxBatchSize) return a.Get(0).(map[string]int64), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_q_history_claimable_balances.go b/services/horizon/internal/db2/history/mock_q_history_claimable_balances.go index 5f09371cbd..ee5bbb38c3 100644 --- a/services/horizon/internal/db2/history/mock_q_history_claimable_balances.go +++ b/services/horizon/internal/db2/history/mock_q_history_claimable_balances.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stellar/go/xdr" "github.com/stretchr/testify/mock" @@ -11,8 +12,8 @@ type MockQHistoryClaimableBalances struct { mock.Mock } -func (m *MockQHistoryClaimableBalances) CreateHistoryClaimableBalances(ids []xdr.ClaimableBalanceId, maxBatchSize int) (map[string]int64, error) { - a := m.Called(ids, maxBatchSize) +func (m *MockQHistoryClaimableBalances) CreateHistoryClaimableBalances(ctx context.Context, ids []xdr.ClaimableBalanceId, maxBatchSize int) (map[string]int64, error) { + a := m.Called(ctx, ids, maxBatchSize) return a.Get(0).(map[string]int64), a.Error(1) } @@ -27,13 +28,13 @@ type MockTransactionClaimableBalanceBatchInsertBuilder struct { mock.Mock } -func (m *MockTransactionClaimableBalanceBatchInsertBuilder) Add(transactionID, accountID int64) error { - a := m.Called(transactionID, accountID) +func (m *MockTransactionClaimableBalanceBatchInsertBuilder) Add(ctx context.Context, transactionID, accountID int64) error { + a := m.Called(ctx, transactionID, accountID) return a.Error(0) } -func (m *MockTransactionClaimableBalanceBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockTransactionClaimableBalanceBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } @@ -49,12 +50,12 @@ type MockOperationClaimableBalanceBatchInsertBuilder struct { mock.Mock } -func (m *MockOperationClaimableBalanceBatchInsertBuilder) Add(transactionID, accountID int64) error { - a := m.Called(transactionID, accountID) +func (m *MockOperationClaimableBalanceBatchInsertBuilder) Add(ctx context.Context, transactionID, accountID int64) error { + a := m.Called(ctx, transactionID, accountID) return a.Error(0) } -func (m *MockOperationClaimableBalanceBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockOperationClaimableBalanceBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_q_ledgers.go b/services/horizon/internal/db2/history/mock_q_ledgers.go index b024c907bc..16d3ef5524 100644 --- a/services/horizon/internal/db2/history/mock_q_ledgers.go +++ b/services/horizon/internal/db2/history/mock_q_ledgers.go @@ -1,15 +1,18 @@ package history import ( - "github.com/stellar/go/xdr" + "context" + "github.com/stretchr/testify/mock" + + "github.com/stellar/go/xdr" ) type MockQLedgers struct { mock.Mock } -func (m *MockQLedgers) InsertLedger( +func (m *MockQLedgers) InsertLedger(ctx context.Context, ledger xdr.LedgerHeaderHistoryEntry, successTxsCount int, failedTxsCount int, @@ -17,6 +20,6 @@ func (m *MockQLedgers) InsertLedger( txSetOpCount int, ingestVersion int, ) (int64, error) { - a := m.Called(ledger, successTxsCount, failedTxsCount, opCount, txSetOpCount, ingestVersion) + a := m.Called(ctx, ledger, successTxsCount, failedTxsCount, opCount, txSetOpCount, ingestVersion) return a.Get(0).(int64), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_q_offers.go b/services/horizon/internal/db2/history/mock_q_offers.go index 84150e49e9..0b23720b7f 100644 --- a/services/horizon/internal/db2/history/mock_q_offers.go +++ b/services/horizon/internal/db2/history/mock_q_offers.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" ) @@ -9,23 +10,23 @@ type MockQOffers struct { mock.Mock } -func (m *MockQOffers) GetAllOffers() ([]Offer, error) { - a := m.Called() +func (m *MockQOffers) GetAllOffers(ctx context.Context) ([]Offer, error) { + a := m.Called(ctx) return a.Get(0).([]Offer), a.Error(1) } -func (m *MockQOffers) GetOffersByIDs(ids []int64) ([]Offer, error) { - a := m.Called(ids) +func (m *MockQOffers) GetOffersByIDs(ctx context.Context, ids []int64) ([]Offer, error) { + a := m.Called(ctx, ids) return a.Get(0).([]Offer), a.Error(1) } -func (m *MockQOffers) GetUpdatedOffers(newerThanSequence uint32) ([]Offer, error) { - a := m.Called(newerThanSequence) +func (m *MockQOffers) GetUpdatedOffers(ctx context.Context, newerThanSequence uint32) ([]Offer, error) { + a := m.Called(ctx, newerThanSequence) return a.Get(0).([]Offer), a.Error(1) } -func (m *MockQOffers) CountOffers() (int, error) { - a := m.Called() +func (m *MockQOffers) CountOffers(ctx context.Context) (int, error) { + a := m.Called(ctx) return a.Get(0).(int), a.Error(1) } @@ -34,17 +35,17 @@ func (m *MockQOffers) NewOffersBatchInsertBuilder(maxBatchSize int) OffersBatchI return a.Get(0).(OffersBatchInsertBuilder) } -func (m *MockQOffers) UpdateOffer(row Offer) (int64, error) { - a := m.Called(row) +func (m *MockQOffers) UpdateOffer(ctx context.Context, row Offer) (int64, error) { + a := m.Called(ctx, row) return a.Get(0).(int64), a.Error(1) } -func (m *MockQOffers) RemoveOffers(offerIDs []int64, lastModifiedLedger uint32) (int64, error) { - a := m.Called(offerIDs, lastModifiedLedger) +func (m *MockQOffers) RemoveOffers(ctx context.Context, offerIDs []int64, lastModifiedLedger uint32) (int64, error) { + a := m.Called(ctx, offerIDs, lastModifiedLedger) return a.Get(0).(int64), a.Error(1) } -func (m *MockQOffers) CompactOffers(cutOffSequence uint32) (int64, error) { - a := m.Called(cutOffSequence) +func (m *MockQOffers) CompactOffers(ctx context.Context, cutOffSequence uint32) (int64, error) { + a := m.Called(ctx, cutOffSequence) return a.Get(0).(int64), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_q_participants.go b/services/horizon/internal/db2/history/mock_q_participants.go index 04758e43de..9365e06db3 100644 --- a/services/horizon/internal/db2/history/mock_q_participants.go +++ b/services/horizon/internal/db2/history/mock_q_participants.go @@ -1,6 +1,7 @@ package history import ( + "context" "github.com/stretchr/testify/mock" ) @@ -9,8 +10,8 @@ type MockQParticipants struct { mock.Mock } -func (m *MockQParticipants) CreateAccounts(addresses []string, maxBatchSize int) (map[string]int64, error) { - a := m.Called(addresses, maxBatchSize) +func (m *MockQParticipants) CreateAccounts(ctx context.Context, addresses []string, maxBatchSize int) (map[string]int64, error) { + a := m.Called(ctx, addresses, maxBatchSize) return a.Get(0).(map[string]int64), a.Error(1) } @@ -25,13 +26,13 @@ type MockTransactionParticipantsBatchInsertBuilder struct { mock.Mock } -func (m *MockTransactionParticipantsBatchInsertBuilder) Add(transactionID, accountID int64) error { - a := m.Called(transactionID, accountID) +func (m *MockTransactionParticipantsBatchInsertBuilder) Add(ctx context.Context, transactionID, accountID int64) error { + a := m.Called(ctx, transactionID, accountID) return a.Error(0) } -func (m *MockTransactionParticipantsBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockTransactionParticipantsBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_q_signers.go b/services/horizon/internal/db2/history/mock_q_signers.go index da5e8a6c48..81f56d9fd1 100644 --- a/services/horizon/internal/db2/history/mock_q_signers.go +++ b/services/horizon/internal/db2/history/mock_q_signers.go @@ -1,31 +1,34 @@ package history import ( - "github.com/stellar/go/services/horizon/internal/db2" + "context" + "github.com/stretchr/testify/mock" + + "github.com/stellar/go/services/horizon/internal/db2" ) type MockQSigners struct { mock.Mock } -func (m *MockQSigners) GetLastLedgerIngestNonBlocking() (uint32, error) { - a := m.Called() +func (m *MockQSigners) GetLastLedgerIngestNonBlocking(ctx context.Context) (uint32, error) { + a := m.Called(ctx) return a.Get(0).(uint32), a.Error(1) } -func (m *MockQSigners) GetLastLedgerIngest() (uint32, error) { - a := m.Called() +func (m *MockQSigners) GetLastLedgerIngest(ctx context.Context) (uint32, error) { + a := m.Called(ctx) return a.Get(0).(uint32), a.Error(1) } -func (m *MockQSigners) UpdateLastLedgerIngest(ledgerSequence uint32) error { - a := m.Called(ledgerSequence) +func (m *MockQSigners) UpdateLastLedgerIngest(ctx context.Context, ledgerSequence uint32) error { + a := m.Called(ctx, ledgerSequence) return a.Error(0) } -func (m *MockQSigners) AccountsForSigner(signer string, page db2.PageQuery) ([]AccountSigner, error) { - a := m.Called(signer, page) +func (m *MockQSigners) AccountsForSigner(ctx context.Context, signer string, page db2.PageQuery) ([]AccountSigner, error) { + a := m.Called(ctx, signer, page) return a.Get(0).([]AccountSigner), a.Error(1) } @@ -34,22 +37,22 @@ func (m *MockQSigners) NewAccountSignersBatchInsertBuilder(maxBatchSize int) Acc return a.Get(0).(AccountSignersBatchInsertBuilder) } -func (m *MockQSigners) CreateAccountSigner(account, signer string, weight int32, sponsor *string) (int64, error) { - a := m.Called(account, signer, weight, sponsor) +func (m *MockQSigners) CreateAccountSigner(ctx context.Context, account, signer string, weight int32, sponsor *string) (int64, error) { + a := m.Called(ctx, account, signer, weight, sponsor) return a.Get(0).(int64), a.Error(1) } -func (m *MockQSigners) RemoveAccountSigner(account, signer string) (int64, error) { - a := m.Called(account, signer) +func (m *MockQSigners) RemoveAccountSigner(ctx context.Context, account, signer string) (int64, error) { + a := m.Called(ctx, account, signer) return a.Get(0).(int64), a.Error(1) } -func (m *MockQSigners) SignersForAccounts(accounts []string) ([]AccountSigner, error) { - a := m.Called(accounts) +func (m *MockQSigners) SignersForAccounts(ctx context.Context, accounts []string) ([]AccountSigner, error) { + a := m.Called(ctx, accounts) return a.Get(0).([]AccountSigner), a.Error(1) } -func (m *MockQSigners) CountAccounts() (int, error) { - a := m.Called() +func (m *MockQSigners) CountAccounts(ctx context.Context) (int, error) { + a := m.Called(ctx) return a.Get(0).(int), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_q_trades.go b/services/horizon/internal/db2/history/mock_q_trades.go index e64afcb24c..e204c5d443 100644 --- a/services/horizon/internal/db2/history/mock_q_trades.go +++ b/services/horizon/internal/db2/history/mock_q_trades.go @@ -1,7 +1,10 @@ package history import ( + "context" + "github.com/stellar/go/xdr" + "github.com/stretchr/testify/mock" ) @@ -9,13 +12,13 @@ type MockQTrades struct { mock.Mock } -func (m *MockQTrades) CreateAccounts(addresses []string, maxBatchSize int) (map[string]int64, error) { - a := m.Called(addresses, maxBatchSize) +func (m *MockQTrades) CreateAccounts(ctx context.Context, addresses []string, maxBatchSize int) (map[string]int64, error) { + a := m.Called(ctx, addresses, maxBatchSize) return a.Get(0).(map[string]int64), a.Error(1) } -func (m *MockQTrades) CreateAssets(assets []xdr.Asset, maxBatchSize int) (map[string]Asset, error) { - a := m.Called(assets, maxBatchSize) +func (m *MockQTrades) CreateAssets(ctx context.Context, assets []xdr.Asset, maxBatchSize int) (map[string]Asset, error) { + a := m.Called(ctx, assets, maxBatchSize) return a.Get(0).(map[string]Asset), a.Error(1) } @@ -28,12 +31,12 @@ type MockTradeBatchInsertBuilder struct { mock.Mock } -func (m *MockTradeBatchInsertBuilder) Add(entries ...InsertTrade) error { - a := m.Called(entries) +func (m *MockTradeBatchInsertBuilder) Add(ctx context.Context, entries ...InsertTrade) error { + a := m.Called(ctx, entries) return a.Error(0) } -func (m *MockTradeBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockTradeBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/mock_q_trust_lines.go b/services/horizon/internal/db2/history/mock_q_trust_lines.go index fd9eeb33c9..ab9a903913 100644 --- a/services/horizon/internal/db2/history/mock_q_trust_lines.go +++ b/services/horizon/internal/db2/history/mock_q_trust_lines.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stretchr/testify/mock" "github.com/stellar/go/xdr" @@ -16,27 +18,27 @@ func (m *MockQTrustLines) NewTrustLinesBatchInsertBuilder(maxBatchSize int) Trus return a.Get(0).(TrustLinesBatchInsertBuilder) } -func (m *MockQTrustLines) GetTrustLinesByKeys(keys []xdr.LedgerKeyTrustLine) ([]TrustLine, error) { - a := m.Called(keys) +func (m *MockQTrustLines) GetTrustLinesByKeys(ctx context.Context, keys []xdr.LedgerKeyTrustLine) ([]TrustLine, error) { + a := m.Called(ctx, keys) return a.Get(0).([]TrustLine), a.Error(1) } -func (m *MockQTrustLines) InsertTrustLine(entry xdr.LedgerEntry) (int64, error) { - a := m.Called(entry) +func (m *MockQTrustLines) InsertTrustLine(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { + a := m.Called(ctx, entry) return a.Get(0).(int64), a.Error(1) } -func (m *MockQTrustLines) UpdateTrustLine(entry xdr.LedgerEntry) (int64, error) { - a := m.Called(entry) +func (m *MockQTrustLines) UpdateTrustLine(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { + a := m.Called(ctx, entry) return a.Get(0).(int64), a.Error(1) } -func (m *MockQTrustLines) UpsertTrustLines(trustLines []xdr.LedgerEntry) error { - a := m.Called(trustLines) +func (m *MockQTrustLines) UpsertTrustLines(ctx context.Context, trustLines []xdr.LedgerEntry) error { + a := m.Called(ctx, trustLines) return a.Error(0) } -func (m *MockQTrustLines) RemoveTrustLine(key xdr.LedgerKeyTrustLine) (int64, error) { - a := m.Called(key) +func (m *MockQTrustLines) RemoveTrustLine(ctx context.Context, key xdr.LedgerKeyTrustLine) (int64, error) { + a := m.Called(ctx, key) return a.Get(0).(int64), a.Error(1) } diff --git a/services/horizon/internal/db2/history/mock_transactions_batch_insert_builder.go b/services/horizon/internal/db2/history/mock_transactions_batch_insert_builder.go index c9997ed088..8e2608d553 100644 --- a/services/horizon/internal/db2/history/mock_transactions_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/mock_transactions_batch_insert_builder.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stretchr/testify/mock" "github.com/stellar/go/ingest" @@ -10,12 +12,12 @@ type MockTransactionsBatchInsertBuilder struct { mock.Mock } -func (m *MockTransactionsBatchInsertBuilder) Add(transaction ingest.LedgerTransaction, sequence uint32) error { - a := m.Called(transaction, sequence) +func (m *MockTransactionsBatchInsertBuilder) Add(ctx context.Context, transaction ingest.LedgerTransaction, sequence uint32) error { + a := m.Called(ctx, transaction, sequence) return a.Error(0) } -func (m *MockTransactionsBatchInsertBuilder) Exec() error { - a := m.Called() +func (m *MockTransactionsBatchInsertBuilder) Exec(ctx context.Context) error { + a := m.Called(ctx) return a.Error(0) } diff --git a/services/horizon/internal/db2/history/offers.go b/services/horizon/internal/db2/history/offers.go index 515cf3928b..fe37ba91c9 100644 --- a/services/horizon/internal/db2/history/offers.go +++ b/services/horizon/internal/db2/history/offers.go @@ -1,27 +1,30 @@ package history import ( + "context" + sq "github.com/Masterminds/squirrel" + "github.com/stellar/go/support/errors" ) // QOffers defines offer related queries. type QOffers interface { - GetAllOffers() ([]Offer, error) - GetOffersByIDs(ids []int64) ([]Offer, error) - CountOffers() (int, error) - GetUpdatedOffers(newerThanSequence uint32) ([]Offer, error) + GetAllOffers(ctx context.Context) ([]Offer, error) + GetOffersByIDs(ctx context.Context, ids []int64) ([]Offer, error) + CountOffers(ctx context.Context) (int, error) + GetUpdatedOffers(ctx context.Context, newerThanSequence uint32) ([]Offer, error) NewOffersBatchInsertBuilder(maxBatchSize int) OffersBatchInsertBuilder - UpdateOffer(offer Offer) (int64, error) - RemoveOffers(offerIDs []int64, lastModifiedLedger uint32) (int64, error) - CompactOffers(cutOffSequence uint32) (int64, error) + UpdateOffer(ctx context.Context, offer Offer) (int64, error) + RemoveOffers(ctx context.Context, offerIDs []int64, lastModifiedLedger uint32) (int64, error) + CompactOffers(ctx context.Context, cutOffSequence uint32) (int64, error) } -func (q *Q) CountOffers() (int, error) { +func (q *Q) CountOffers(ctx context.Context) (int, error) { sql := sq.Select("count(*)").Where("deleted = ?", false).From("offers") var count int - if err := q.Get(&count, sql); err != nil { + if err := q.Get(ctx, &count, sql); err != nil { return 0, errors.Wrap(err, "could not run select query") } @@ -29,25 +32,25 @@ func (q *Q) CountOffers() (int, error) { } // GetOfferByID loads a row from the `offers` table, selected by offerid. -func (q *Q) GetOfferByID(id int64) (Offer, error) { +func (q *Q) GetOfferByID(ctx context.Context, id int64) (Offer, error) { var offer Offer sql := selectOffers.Where("deleted = ?", false). Where("offers.offer_id = ?", id) - err := q.Get(&offer, sql) + err := q.Get(ctx, &offer, sql) return offer, err } // GetOffersByIDs loads a row from the `offers` table, selected by multiple offerid. -func (q *Q) GetOffersByIDs(ids []int64) ([]Offer, error) { +func (q *Q) GetOffersByIDs(ctx context.Context, ids []int64) ([]Offer, error) { var offers []Offer sql := selectOffers.Where("deleted = ?", false). Where(map[string]interface{}{"offers.offer_id": ids}) - err := q.Select(&offers, sql) + err := q.Select(ctx, &offers, sql) return offers, err } // GetOffers loads rows from `offers` by paging query. -func (q *Q) GetOffers(query OffersQuery) ([]Offer, error) { +func (q *Q) GetOffers(ctx context.Context, query OffersQuery) ([]Offer, error) { sql := selectOffers.Where("deleted = ?", false) sql, err := query.PageQuery.ApplyTo(sql, "offers.offer_id") @@ -72,7 +75,7 @@ func (q *Q) GetOffers(query OffersQuery) ([]Offer, error) { } var offers []Offer - if err := q.Select(&offers, sql); err != nil { + if err := q.Select(ctx, &offers, sql); err != nil { return nil, errors.Wrap(err, "could not run select query") } @@ -80,24 +83,24 @@ func (q *Q) GetOffers(query OffersQuery) ([]Offer, error) { } // GetAllOffers loads all non deleted offers -func (q *Q) GetAllOffers() ([]Offer, error) { +func (q *Q) GetAllOffers(ctx context.Context) ([]Offer, error) { var offers []Offer - err := q.Select(&offers, selectOffers.Where("deleted = ?", false)) + err := q.Select(ctx, &offers, selectOffers.Where("deleted = ?", false)) return offers, err } // GetUpdatedOffers returns all offers created, updated, or deleted after the given ledger sequence. -func (q *Q) GetUpdatedOffers(newerThanSequence uint32) ([]Offer, error) { +func (q *Q) GetUpdatedOffers(ctx context.Context, newerThanSequence uint32) ([]Offer, error) { var offers []Offer - err := q.Select(&offers, selectOffers.Where("offers.last_modified_ledger > ?", newerThanSequence)) + err := q.Select(ctx, &offers, selectOffers.Where("offers.last_modified_ledger > ?", newerThanSequence)) return offers, err } // UpdateOffer updates a row in the offers table. // Returns number of rows affected and error. -func (q *Q) UpdateOffer(offer Offer) (int64, error) { +func (q *Q) UpdateOffer(ctx context.Context, offer Offer) (int64, error) { updateBuilder := q.GetTable("offers").Update() - result, err := updateBuilder.SetStruct(offer, []string{}).Where("offer_id = ?", offer.OfferID).Exec() + result, err := updateBuilder.SetStruct(offer, []string{}).Where("offer_id = ?", offer.OfferID).Exec(ctx) if err != nil { return 0, err } @@ -106,13 +109,13 @@ func (q *Q) UpdateOffer(offer Offer) (int64, error) { // RemoveOffers marks rows in the offers table as deleted. // Returns number of rows affected and error. -func (q *Q) RemoveOffers(offerIDs []int64, lastModifiedLedger uint32) (int64, error) { +func (q *Q) RemoveOffers(ctx context.Context, offerIDs []int64, lastModifiedLedger uint32) (int64, error) { sql := sq.Update("offers"). Set("deleted", true). Set("last_modified_ledger", lastModifiedLedger). Where(map[string]interface{}{"offer_id": offerIDs}) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -121,17 +124,17 @@ func (q *Q) RemoveOffers(offerIDs []int64, lastModifiedLedger uint32) (int64, er } // CompactOffers removes rows from the offers table which are marked for deletion. -func (q *Q) CompactOffers(cutOffSequence uint32) (int64, error) { +func (q *Q) CompactOffers(ctx context.Context, cutOffSequence uint32) (int64, error) { sql := sq.Delete("offers"). Where("deleted = ?", true). Where("last_modified_ledger <= ?", cutOffSequence) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, errors.Wrap(err, "cannot delete offer rows") } - if err = q.UpdateOfferCompactionSequence(cutOffSequence); err != nil { + if err = q.UpdateOfferCompactionSequence(ctx, cutOffSequence); err != nil { return 0, errors.Wrap(err, "cannot update offer compaction sequence") } diff --git a/services/horizon/internal/db2/history/offers_batch_insert_builder.go b/services/horizon/internal/db2/history/offers_batch_insert_builder.go index 4278223bde..c1d3b628a9 100644 --- a/services/horizon/internal/db2/history/offers_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/offers_batch_insert_builder.go @@ -1,10 +1,14 @@ package history +import ( + "context" +) + // Add adds a new offer entry to the batch. -func (i *offersBatchInsertBuilder) Add(offer Offer) error { - return i.builder.RowStruct(offer) +func (i *offersBatchInsertBuilder) Add(ctx context.Context, offer Offer) error { + return i.builder.RowStruct(ctx, offer) } -func (i *offersBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *offersBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/offers_test.go b/services/horizon/internal/db2/history/offers_test.go index 79ee19c0eb..2218ffc71a 100644 --- a/services/horizon/internal/db2/history/offers_test.go +++ b/services/horizon/internal/db2/history/offers_test.go @@ -63,13 +63,13 @@ var ( } ) -func insertOffer(q *Q, offer Offer) error { +func insertOffer(tt *test.T, q *Q, offer Offer) error { batch := q.NewOffersBatchInsertBuilder(0) - err := batch.Add(offer) + err := batch.Add(tt.Ctx, offer) if err != nil { return err } - return batch.Exec() + return batch.Exec(tt.Ctx) } func TestGetOfferByID(t *testing.T) { @@ -78,9 +78,9 @@ func TestGetOfferByID(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - err := insertOffer(q, eurOffer) + err := insertOffer(tt, q, eurOffer) tt.Assert.NoError(err) - offer, err := q.GetOfferByID(eurOffer.OfferID) + offer, err := q.GetOfferByID(tt.Ctx, eurOffer.OfferID) tt.Assert.NoError(err) tt.Assert.Equal(offer, eurOffer) } @@ -91,7 +91,7 @@ func TestGetNonExistentOfferByID(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, err := q.GetOfferByID(12345) + _, err := q.GetOfferByID(tt.Ctx, 12345) tt.Assert.True(q.NoRows(err)) } @@ -101,22 +101,22 @@ func TestQueryEmptyOffers(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - offers, err := q.GetAllOffers() + offers, err := q.GetAllOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(offers, 0) - updated, err := q.GetUpdatedOffers(0) + updated, err := q.GetUpdatedOffers(tt.Ctx, 0) tt.Assert.NoError(err) tt.Assert.Len(updated, 0) - count, err := q.CountOffers() + count, err := q.CountOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(0, count) - numRemoved, err := q.CompactOffers(100) + numRemoved, err := q.CompactOffers(tt.Ctx, 100) tt.Assert.NoError(err) tt.Assert.Equal(int64(0), numRemoved) - seq, err := q.GetOfferCompactionSequence() + seq, err := q.GetOfferCompactionSequence(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(uint32(100), seq) } @@ -127,12 +127,12 @@ func TestInsertOffers(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - err := insertOffer(q, eurOffer) + err := insertOffer(tt, q, eurOffer) tt.Assert.NoError(err) - err = insertOffer(q, twoEurOffer) + err = insertOffer(tt, q, twoEurOffer) tt.Assert.NoError(err) - offers, err := q.GetAllOffers() + offers, err := q.GetAllOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(offers, 2) @@ -144,22 +144,22 @@ func TestInsertOffers(t *testing.T) { tt.Assert.Equal(offersByID[eurOffer.OfferID], eurOffer) tt.Assert.Equal(offersByID[twoEurOffer.OfferID], twoEurOffer) - count, err := q.CountOffers() + count, err := q.CountOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(2, count) - numRemoved, err := q.CompactOffers(12350) + numRemoved, err := q.CompactOffers(tt.Ctx, 12350) tt.Assert.NoError(err) tt.Assert.Equal(int64(0), numRemoved) - seq, err := q.GetOfferCompactionSequence() + seq, err := q.GetOfferCompactionSequence(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(uint32(12350), seq) - afterCompactionCount, err := q.CountOffers() + afterCompactionCount, err := q.CountOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(2, afterCompactionCount) - afterCompactionOffers, err := q.GetAllOffers() + afterCompactionOffers, err := q.GetAllOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(afterCompactionOffers, 2) } @@ -170,22 +170,22 @@ func TestUpdateOffer(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - err := insertOffer(q, eurOffer) + err := insertOffer(tt, q, eurOffer) tt.Assert.NoError(err) - offers, err := q.GetAllOffers() + offers, err := q.GetAllOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) - updatedOffers, err := q.GetUpdatedOffers(1233) + updatedOffers, err := q.GetUpdatedOffers(tt.Ctx, 1233) tt.Assert.NoError(err) tt.Assert.Equal(offers, updatedOffers) - updatedOffers, err = q.GetUpdatedOffers(100) + updatedOffers, err = q.GetUpdatedOffers(tt.Ctx, 100) tt.Assert.NoError(err) tt.Assert.Equal(offers, updatedOffers) - updatedOffers, err = q.GetUpdatedOffers(1234) + updatedOffers, err = q.GetUpdatedOffers(tt.Ctx, 1234) tt.Assert.NoError(err) tt.Assert.Len(updatedOffers, 0) @@ -194,19 +194,19 @@ func TestUpdateOffer(t *testing.T) { modifiedEurOffer := eurOffer modifiedEurOffer.Amount -= 10 - rowsAffected, err := q.UpdateOffer(modifiedEurOffer) + rowsAffected, err := q.UpdateOffer(tt.Ctx, modifiedEurOffer) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), rowsAffected) - offers, err = q.GetAllOffers() + offers, err = q.GetAllOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) - updatedOffers, err = q.GetUpdatedOffers(1233) + updatedOffers, err = q.GetUpdatedOffers(tt.Ctx, 1233) tt.Assert.NoError(err) tt.Assert.Equal(offers, updatedOffers) - updatedOffers, err = q.GetUpdatedOffers(1235) + updatedOffers, err = q.GetUpdatedOffers(tt.Ctx, 1235) tt.Assert.NoError(err) tt.Assert.Len(updatedOffers, 0) @@ -219,7 +219,7 @@ func TestRemoveNonExistantOffer(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - numAffected, err := q.RemoveOffers([]int64{12345}, 1236) + numAffected, err := q.RemoveOffers(tt.Ctx, []int64{12345}, 1236) tt.Assert.NoError(err) tt.Assert.Equal(int64(0), numAffected) } @@ -230,51 +230,51 @@ func TestRemoveOffer(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - err := insertOffer(q, eurOffer) + err := insertOffer(tt, q, eurOffer) tt.Assert.NoError(err) - offers, err := q.GetAllOffers() + offers, err := q.GetAllOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) tt.Assert.Equal(offers[0], eurOffer) expectedUpdates := offers - rowsAffected, err := q.RemoveOffers([]int64{eurOffer.OfferID}, 1236) + rowsAffected, err := q.RemoveOffers(tt.Ctx, []int64{eurOffer.OfferID}, 1236) tt.Assert.Equal(int64(1), rowsAffected) tt.Assert.NoError(err) expectedUpdates[0].LastModifiedLedger = 1236 expectedUpdates[0].Deleted = true - offers, err = q.GetAllOffers() + offers, err = q.GetAllOffers(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(offers, 0) - offers, err = q.GetOffersByIDs([]int64{int64(expectedUpdates[0].OfferID)}) + offers, err = q.GetOffersByIDs(tt.Ctx, []int64{int64(expectedUpdates[0].OfferID)}) tt.Assert.NoError(err) tt.Assert.Len(offers, 0) - _, err = q.GetOfferByID(int64(expectedUpdates[0].OfferID)) + _, err = q.GetOfferByID(tt.Ctx, int64(expectedUpdates[0].OfferID)) tt.Assert.True(q.NoRows(err)) - updated, err := q.GetUpdatedOffers(1234) + updated, err := q.GetUpdatedOffers(tt.Ctx, 1234) tt.Assert.NoError(err) tt.Assert.Equal(expectedUpdates, updated) - count, err := q.CompactOffers(1235) + count, err := q.CompactOffers(tt.Ctx, 1235) tt.Assert.NoError(err) tt.Assert.Equal(int64(0), count) - updated, err = q.GetUpdatedOffers(1234) + updated, err = q.GetUpdatedOffers(tt.Ctx, 1234) tt.Assert.NoError(err) tt.Assert.Equal(expectedUpdates, updated) - count, err = q.CompactOffers(1236) + count, err = q.CompactOffers(tt.Ctx, 1236) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), count) - seq, err := q.GetOfferCompactionSequence() + seq, err := q.GetOfferCompactionSequence(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(uint32(1236), seq) - updated, err = q.GetUpdatedOffers(1234) + updated, err = q.GetUpdatedOffers(tt.Ctx, 1234) tt.Assert.NoError(err) tt.Assert.Len(updated, 0) } @@ -285,15 +285,15 @@ func TestGetOffers(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - err := insertOffer(q, eurOffer) + err := insertOffer(tt, q, eurOffer) tt.Assert.NoError(err) - err = insertOffer(q, twoEurOffer) + err = insertOffer(tt, q, twoEurOffer) tt.Assert.NoError(err) // check removed offers aren't included in GetOffer queries - err = insertOffer(q, threeEurOffer) + err = insertOffer(tt, q, threeEurOffer) tt.Assert.NoError(err) - count, err := q.RemoveOffers([]int64{threeEurOffer.OfferID}, 1235) + count, err := q.RemoveOffers(tt.Ctx, []int64{threeEurOffer.OfferID}, 1235) tt.Assert.NoError(err) tt.Assert.Equal(int64(1), count) @@ -306,7 +306,7 @@ func TestGetOffers(t *testing.T) { Selling: &usdAsset, } - offers, err := q.GetOffers(query) + offers, err := q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 0) @@ -315,7 +315,7 @@ func TestGetOffers(t *testing.T) { Selling: &nativeAsset, } - offers, err = q.GetOffers(query) + offers, err = q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 2) @@ -330,7 +330,7 @@ func TestGetOffers(t *testing.T) { Buying: &eurAsset, } - offers, err := q.GetOffers(query) + offers, err := q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 2) @@ -343,7 +343,7 @@ func TestGetOffers(t *testing.T) { Buying: &usdAsset, } - offers, err = q.GetOffers(query) + offers, err = q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 0) }) @@ -355,7 +355,7 @@ func TestGetOffers(t *testing.T) { SellerID: sellerID, } - offers, err := q.GetOffers(query) + offers, err := q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) @@ -368,7 +368,7 @@ func TestGetOffers(t *testing.T) { Sponsor: sponsor.Address(), } - offers, err := q.GetOffers(query) + offers, err := q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) @@ -383,7 +383,7 @@ func TestGetOffers(t *testing.T) { PageQuery: pageQuery, } - offers, err := q.GetOffers(query) + offers, err := q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 2) @@ -401,7 +401,7 @@ func TestGetOffers(t *testing.T) { PageQuery: pageQuery, } - offers, err = q.GetOffers(query) + offers, err = q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) @@ -413,7 +413,7 @@ func TestGetOffers(t *testing.T) { PageQuery: pageQuery, } - offers, err = q.GetOffers(query) + offers, err = q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) @@ -430,7 +430,7 @@ func TestGetOffers(t *testing.T) { PageQuery: pageQuery, } - offers, err = q.GetOffers(query) + offers, err = q.GetOffers(tt.Ctx, query) tt.Assert.NoError(err) tt.Assert.Len(offers, 1) diff --git a/services/horizon/internal/db2/history/operation.go b/services/horizon/internal/db2/history/operation.go index 6a5a1551dd..949f861d23 100644 --- a/services/horizon/internal/db2/history/operation.go +++ b/services/horizon/internal/db2/history/operation.go @@ -2,6 +2,7 @@ package history import ( "bytes" + "context" "encoding/json" "text/template" @@ -54,7 +55,7 @@ WHERE ledger_sequence > $1 AND ledger_sequence <= $2`)) // FeeStats returns operation fee stats for the last 5 ledgers. // Currently, we hard code the query to return the last 5 ledgers worth of transactions. // TODO: make the number of ledgers configurable. -func (q *Q) FeeStats(currentSeq int32, dest *FeeStats) error { +func (q *Q) FeeStats(ctx context.Context, currentSeq int32, dest *FeeStats) error { percentiles := []int{10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 99} var buf bytes.Buffer @@ -63,7 +64,7 @@ func (q *Q) FeeStats(currentSeq int32, dest *FeeStats) error { return errors.Wrap(err, "error executing the query template") } - return q.GetRaw(dest, buf.String(), currentSeq-5, currentSeq) + return q.GetRaw(ctx, dest, buf.String(), currentSeq-5, currentSeq) } // Operations provides a helper to filter the operations table with pre-defined @@ -81,20 +82,20 @@ func (q *Q) Operations() *OperationsQ { } // OperationByID returns an Operation and optionally a Transaction given an operation id -func (q *Q) OperationByID(includeTransactions bool, id int64) (Operation, *Transaction, error) { +func (q *Q) OperationByID(ctx context.Context, includeTransactions bool, id int64) (Operation, *Transaction, error) { sql := selectOperation. Limit(1). Where("hop.id = ?", id) var operation Operation - err := q.Get(&operation, sql) + err := q.Get(ctx, &operation, sql) if err != nil { return operation, nil, err } if includeTransactions { var transaction Transaction - if err = q.TransactionByHash(&transaction, operation.TransactionHash); err != nil { + if err = q.TransactionByHash(ctx, &transaction, operation.TransactionHash); err != nil { return operation, nil, err } @@ -109,9 +110,9 @@ func (q *Q) OperationByID(includeTransactions bool, id int64) (Operation, *Trans } // ForAccount filters the operations collection to a specific account -func (q *OperationsQ) ForAccount(aid string) *OperationsQ { +func (q *OperationsQ) ForAccount(ctx context.Context, aid string) *OperationsQ { var account Account - q.Err = q.parent.AccountByAddress(&account, aid) + q.Err = q.parent.AccountByAddress(ctx, &account, aid) if q.Err != nil { return q } @@ -129,9 +130,9 @@ func (q *OperationsQ) ForAccount(aid string) *OperationsQ { // ForClaimableBalance filters the query to only operations pertaining to a // claimable balance, specified by the claimable balance's hex-encoded id. -func (q *OperationsQ) ForClaimableBalance(cbID xdr.ClaimableBalanceId) *OperationsQ { +func (q *OperationsQ) ForClaimableBalance(ctx context.Context, cbID xdr.ClaimableBalanceId) *OperationsQ { var hCB HistoryClaimableBalance - hCB, q.Err = q.parent.ClaimableBalanceByID(cbID) + hCB, q.Err = q.parent.ClaimableBalanceByID(ctx, cbID) if q.Err != nil { return q } @@ -149,9 +150,9 @@ func (q *OperationsQ) ForClaimableBalance(cbID xdr.ClaimableBalanceId) *Operatio // ForLedger filters the query to a only operations in a specific ledger, // specified by its sequence. -func (q *OperationsQ) ForLedger(seq int32) *OperationsQ { +func (q *OperationsQ) ForLedger(ctx context.Context, seq int32) *OperationsQ { var ledger Ledger - q.Err = q.parent.LedgerBySequence(&ledger, seq) + q.Err = q.parent.LedgerBySequence(ctx, &ledger, seq) if q.Err != nil { return q } @@ -169,9 +170,9 @@ func (q *OperationsQ) ForLedger(seq int32) *OperationsQ { // ForTransaction filters the query to only operations in a specific // transaction, specified by the transactions's hex-encoded hash. -func (q *OperationsQ) ForTransaction(hash string) *OperationsQ { +func (q *OperationsQ) ForTransaction(ctx context.Context, hash string) *OperationsQ { var tx Transaction - q.Err = q.parent.TransactionByHash(&tx, hash) + q.Err = q.parent.TransactionByHash(ctx, &tx, hash) if q.Err != nil { return q } @@ -225,7 +226,7 @@ func (q *OperationsQ) Page(page db2.PageQuery) *OperationsQ { } // Fetch returns results specified by a filtered operations query -func (q *OperationsQ) Fetch() ([]Operation, []Transaction, error) { +func (q *OperationsQ) Fetch(ctx context.Context) ([]Operation, []Transaction, error) { if q.Err != nil { return nil, nil, q.Err } @@ -237,7 +238,7 @@ func (q *OperationsQ) Fetch() ([]Operation, []Transaction, error) { var operations []Operation var transactions []Transaction - q.Err = q.parent.Select(&operations, q.sql) + q.Err = q.parent.Select(ctx, &operations, q.sql) if q.Err != nil { return nil, nil, q.Err } @@ -277,7 +278,7 @@ func (q *OperationsQ) Fetch() ([]Operation, []Transaction, error) { } if q.includeTransactions && len(transactionIDs) > 0 { - transactionsByID, err := q.parent.TransactionsByIDs(transactionIDs...) + transactionsByID, err := q.parent.TransactionsByIDs(ctx, transactionIDs...) if err != nil { return nil, nil, err } diff --git a/services/horizon/internal/db2/history/operation_batch_insert_builder.go b/services/horizon/internal/db2/history/operation_batch_insert_builder.go index 78b0116b39..73525b97cb 100644 --- a/services/horizon/internal/db2/history/operation_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/operation_batch_insert_builder.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stellar/go/support/db" "github.com/stellar/go/xdr" ) @@ -9,6 +11,7 @@ import ( // history_operations table type OperationBatchInsertBuilder interface { Add( + ctx context.Context, id int64, transactionID int64, applicationOrder uint32, @@ -16,7 +19,7 @@ type OperationBatchInsertBuilder interface { details []byte, sourceAccount string, ) error - Exec() error + Exec(ctx context.Context) error } // operationBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -36,6 +39,7 @@ func (q *Q) NewOperationBatchInsertBuilder(maxBatchSize int) OperationBatchInser // Add adds a transaction's operations to the batch func (i *operationBatchInsertBuilder) Add( + ctx context.Context, id int64, transactionID int64, applicationOrder uint32, @@ -43,7 +47,7 @@ func (i *operationBatchInsertBuilder) Add( details []byte, sourceAccount string, ) error { - return i.builder.Row(map[string]interface{}{ + return i.builder.Row(ctx, map[string]interface{}{ "id": id, "transaction_id": transactionID, "application_order": applicationOrder, @@ -54,6 +58,6 @@ func (i *operationBatchInsertBuilder) Add( } -func (i *operationBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *operationBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/operation_batch_insert_builder_test.go b/services/horizon/internal/db2/history/operation_batch_insert_builder_test.go index 72e012f118..fd7d44271c 100644 --- a/services/horizon/internal/db2/history/operation_batch_insert_builder_test.go +++ b/services/horizon/internal/db2/history/operation_batch_insert_builder_test.go @@ -34,8 +34,8 @@ func TestAddOperation(t *testing.T) { ) sequence := int32(56) - tt.Assert.NoError(txBatch.Add(transaction, uint32(sequence))) - tt.Assert.NoError(txBatch.Exec()) + tt.Assert.NoError(txBatch.Add(tt.Ctx, transaction, uint32(sequence))) + tt.Assert.NoError(txBatch.Exec(tt.Ctx)) details, err := json.Marshal(map[string]string{ "to": "GANFZDRBCNTUXIODCJEYMACPMCSZEVE4WZGZ3CZDZ3P2SXK4KH75IK6Y", @@ -45,7 +45,7 @@ func TestAddOperation(t *testing.T) { }) tt.Assert.NoError(err) - err = builder.Add( + err = builder.Add(tt.Ctx, toid.New(sequence, 1, 1).ToInt64(), toid.New(sequence, 1, 0).ToInt64(), 1, @@ -55,11 +55,11 @@ func TestAddOperation(t *testing.T) { ) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) ops := []Operation{} - err = q.Select(&ops, selectOperation) + err = q.Select(tt.Ctx, &ops, selectOperation) if tt.Assert.NoError(err) { tt.Assert.Len(ops, 1) diff --git a/services/horizon/internal/db2/history/operation_participant_batch_insert_builder.go b/services/horizon/internal/db2/history/operation_participant_batch_insert_builder.go index c0aa2da3c2..6b2b3afb56 100644 --- a/services/horizon/internal/db2/history/operation_participant_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/operation_participant_batch_insert_builder.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stellar/go/support/db" ) @@ -8,10 +10,11 @@ import ( // history_operations table type OperationParticipantBatchInsertBuilder interface { Add( + ctx context.Context, operationID int64, accountID int64, ) error - Exec() error + Exec(ctx context.Context) error } // operationParticipantBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -31,15 +34,16 @@ func (q *Q) NewOperationParticipantBatchInsertBuilder(maxBatchSize int) Operatio // Add adds an operation participant to the batch func (i *operationParticipantBatchInsertBuilder) Add( + ctx context.Context, operationID int64, accountID int64, ) error { - return i.builder.Row(map[string]interface{}{ + return i.builder.Row(ctx, map[string]interface{}{ "history_operation_id": operationID, "history_account_id": accountID, }) } -func (i *operationParticipantBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *operationParticipantBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/operation_participant_batch_insert_builder_test.go b/services/horizon/internal/db2/history/operation_participant_batch_insert_builder_test.go index 612acba3bd..51a0c4800d 100644 --- a/services/horizon/internal/db2/history/operation_participant_batch_insert_builder_test.go +++ b/services/horizon/internal/db2/history/operation_participant_batch_insert_builder_test.go @@ -14,10 +14,10 @@ func TestAddOperationParticipants(t *testing.T) { q := &Q{tt.HorizonSession()} builder := q.NewOperationParticipantBatchInsertBuilder(1) - err := builder.Add(240518172673, 1) + err := builder.Add(tt.Ctx, 240518172673, 1) tt.Assert.NoError(err) - err = builder.Exec() + err = builder.Exec(tt.Ctx) tt.Assert.NoError(err) type hop struct { @@ -26,7 +26,7 @@ func TestAddOperationParticipants(t *testing.T) { } ops := []hop{} - err = q.Select(&ops, sq.Select( + err = q.Select(tt.Ctx, &ops, sq.Select( "hopp.history_operation_id, "+ "hopp.history_account_id"). From("history_operation_participants hopp"), diff --git a/services/horizon/internal/db2/history/operation_test.go b/services/horizon/internal/db2/history/operation_test.go index 8d1287d62f..a26d43beca 100644 --- a/services/horizon/internal/db2/history/operation_test.go +++ b/services/horizon/internal/db2/history/operation_test.go @@ -15,7 +15,7 @@ func TestOperationQueries(t *testing.T) { q := &Q{tt.HorizonSession()} // Test OperationByID - op, transaction, err := q.OperationByID(false, 8589938689) + op, transaction, err := q.OperationByID(tt.Ctx, false, 8589938689) if tt.Assert.NoError(err) { tt.Assert.Equal(int64(8589938689), op.ID) } @@ -23,15 +23,15 @@ func TestOperationQueries(t *testing.T) { // Test Operations() ops, transactions, err := q.Operations(). - ForAccount("GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). - Fetch() + ForAccount(tt.Ctx, "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). + Fetch(tt.Ctx) if tt.Assert.NoError(err) { tt.Assert.Len(ops, 2) } tt.Assert.Len(transactions, 0) // ledger filter works - ops, transactions, err = q.Operations().ForLedger(2).Fetch() + ops, transactions, err = q.Operations().ForLedger(tt.Ctx, 2).Fetch(tt.Ctx) if tt.Assert.NoError(err) { tt.Assert.Len(ops, 3) } @@ -39,7 +39,7 @@ func TestOperationQueries(t *testing.T) { // tx filter works hash := "2374e99349b9ef7dba9a5db3339b78fda8f34777b1af33ba468ad5c0df946d4d" - ops, transactions, err = q.Operations().ForTransaction(hash).Fetch() + ops, transactions, err = q.Operations().ForTransaction(tt.Ctx, hash).Fetch(tt.Ctx) if tt.Assert.NoError(err) { tt.Assert.Len(ops, 1) } @@ -47,7 +47,7 @@ func TestOperationQueries(t *testing.T) { // payment filter works tt.Scenario("pathed_payment") - ops, transactions, err = q.Operations().OnlyPayments().Fetch() + ops, transactions, err = q.Operations().OnlyPayments().Fetch(tt.Ctx) if tt.Assert.NoError(err) { tt.Assert.Len(ops, 10) } @@ -55,7 +55,7 @@ func TestOperationQueries(t *testing.T) { // payment filter includes account merges tt.Scenario("account_merge") - ops, transactions, err = q.Operations().OnlyPayments().Fetch() + ops, transactions, err = q.Operations().OnlyPayments().Fetch(tt.Ctx) if tt.Assert.NoError(err) { tt.Assert.Len(ops, 3) } @@ -68,7 +68,7 @@ func TestOperationQueryBuilder(t *testing.T) { defer tt.Finish() q := &Q{tt.HorizonSession()} - opsQ := q.Operations().ForAccount("GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON").Page(db2.PageQuery{Cursor: "8589938689", Order: "asc", Limit: 10}) + opsQ := q.Operations().ForAccount(tt.Ctx, "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON").Page(db2.PageQuery{Cursor: "8589938689", Order: "asc", Limit: 10}) tt.Assert.NoError(opsQ.Err) got, _, err := opsQ.sql.ToSql() tt.Assert.NoError(err) @@ -77,7 +77,7 @@ func TestOperationQueryBuilder(t *testing.T) { want := "SELECT hop.id, hop.transaction_id, hop.application_order, hop.type, hop.details, hop.source_account, ht.transaction_hash, ht.tx_result, COALESCE(ht.successful, true) as transaction_successful FROM history_operations hop LEFT JOIN history_transactions ht ON ht.id = hop.transaction_id JOIN history_operation_participants hopp ON hopp.history_operation_id = hop.id WHERE hopp.history_account_id = ? AND hopp.history_operation_id > ? ORDER BY hopp.history_operation_id asc LIMIT 10" tt.Assert.EqualValues(want, got) - opsQ = q.Operations().ForLedger(2).Page(db2.PageQuery{Cursor: "8589938689", Order: "asc", Limit: 10}) + opsQ = q.Operations().ForLedger(tt.Ctx, 2).Page(db2.PageQuery{Cursor: "8589938689", Order: "asc", Limit: 10}) tt.Assert.NoError(opsQ.Err) got, _, err = opsQ.sql.ToSql() tt.Assert.NoError(err) @@ -98,9 +98,9 @@ func TestOperationSuccessfulOnly(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Operations(). - ForAccount("GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2") + ForAccount(tt.Ctx, "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2") - operations, transactions, err := query.Fetch() + operations, transactions, err := query.Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(transactions, 0) @@ -124,10 +124,10 @@ func TestOperationIncludeFailed(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Operations(). - ForAccount("GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). + ForAccount(tt.Ctx, "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). IncludeFailed() - operations, transactions, err := query.Fetch() + operations, transactions, err := query.Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(transactions, 0) @@ -160,9 +160,9 @@ func TestPaymentsSuccessfulOnly(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Operations(). OnlyPayments(). - ForAccount("GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON") + ForAccount(tt.Ctx, "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON") - operations, transactions, err := query.Fetch() + operations, transactions, err := query.Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(transactions, 0) @@ -187,10 +187,10 @@ func TestPaymentsIncludeFailed(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Operations(). OnlyPayments(). - ForAccount("GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). + ForAccount(tt.Ctx, "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). IncludeFailed() - operations, transactions, err := query.Fetch() + operations, transactions, err := query.Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(transactions, 0) @@ -224,10 +224,10 @@ func TestExtraChecksOperationsTransactionSuccessfulTrueResultFalse(t *testing.T) q := &Q{tt.HorizonSession()} query := q.Operations(). - ForAccount("GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). + ForAccount(tt.Ctx, "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). IncludeFailed() - _, _, err = query.Fetch() + _, _, err = query.Fetch(tt.Ctx) tt.Assert.Error(err) tt.Assert.Contains(err.Error(), "Corrupted data! `successful=true` but returned transaction is not success") } @@ -245,10 +245,10 @@ func TestExtraChecksOperationsTransactionSuccessfulFalseResultTrue(t *testing.T) q := &Q{tt.HorizonSession()} query := q.Operations(). - ForAccount("GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). + ForAccount(tt.Ctx, "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). IncludeFailed() - _, _, err = query.Fetch() + _, _, err = query.Fetch(tt.Ctx) tt.Assert.Error(err) tt.Assert.Contains(err.Error(), "Corrupted data! `successful=false` but returned transaction is success") } @@ -271,9 +271,9 @@ func TestOperationIncludeTransactions(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Operations(). IncludeTransactions(). - ForAccount(accountID) + ForAccount(tt.Ctx, accountID) - operations, transactions, err := query.Fetch() + operations, transactions, err := query.Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(transactions, 3) tt.Assert.Len(transactions, len(operations)) @@ -285,27 +285,27 @@ func TestOperationIncludeTransactions(t *testing.T) { } withoutTransactionsQuery := (&Q{tt.HorizonSession()}).Operations(). - ForAccount(accountID) + ForAccount(tt.Ctx, accountID) var expectedTransactions []Transaction - err = (&Q{tt.HorizonSession()}).Transactions().ForAccount(accountID).Select(&expectedTransactions) + err = (&Q{tt.HorizonSession()}).Transactions().ForAccount(tt.Ctx, accountID).Select(tt.Ctx, &expectedTransactions) tt.Assert.NoError(err) - expectedOperations, _, err := withoutTransactionsQuery.Fetch() + expectedOperations, _, err := withoutTransactionsQuery.Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Equal(operations, expectedOperations) tt.Assert.Equal(transactions, expectedTransactions) - op, transaction, err := q.OperationByID(true, expectedOperations[0].ID) + op, transaction, err := q.OperationByID(tt.Ctx, true, expectedOperations[0].ID) tt.Assert.NoError(err) tt.Assert.Equal(op, expectedOperations[0]) tt.Assert.Equal(*transaction, expectedTransactions[0]) assertOperationMatchesTransaction(tt, op, *transaction) - _, err = q.Exec(sq.Delete("history_transactions")) + _, err = q.Exec(tt.Ctx, sq.Delete("history_transactions")) tt.Assert.NoError(err) - _, _, err = q.OperationByID(true, 17179877377) + _, _, err = q.OperationByID(tt.Ctx, true, 17179877377) tt.Assert.Error(err) } @@ -329,13 +329,13 @@ func TestValidateTransactionForOperation(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Operations(). IncludeTransactions(). - ForAccount(accountID) + ForAccount(tt.Ctx, accountID) - _, _, err := query.Fetch() + _, _, err := query.Fetch(tt.Ctx) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction with id 17179877376 could not be found") - _, _, err = q.OperationByID(true, 17179877377) + _, _, err = q.OperationByID(tt.Ctx, true, 17179877377) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction id 0 does not match transaction id in operation 17179877376") @@ -346,13 +346,13 @@ func TestValidateTransactionForOperation(t *testing.T) { From("history_transactions ht") query = q.Operations(). IncludeTransactions(). - ForAccount(accountID) + ForAccount(tt.Ctx, accountID) - _, _, err = query.Fetch() + _, _, err = query.Fetch(tt.Ctx) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction result does not match transaction result in operation AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=") - _, _, err = q.OperationByID(true, 17179877377) + _, _, err = q.OperationByID(tt.Ctx, true, 17179877377) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction result does not match transaction result in operation AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAA=") @@ -363,13 +363,13 @@ func TestValidateTransactionForOperation(t *testing.T) { From("history_transactions ht") query = q.Operations(). IncludeTransactions(). - ForAccount(accountID) + ForAccount(tt.Ctx, accountID) - _, _, err = query.Fetch() + _, _, err = query.Fetch(tt.Ctx) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction hash does not match transaction hash in operation 1c454630267aa8767ec8c8e30450cea6ba660145e9c924abb75d7a6669b6c28a") - _, _, err = q.OperationByID(true, 17179877377) + _, _, err = q.OperationByID(tt.Ctx, true, 17179877377) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction hash does not match transaction hash in operation 1c454630267aa8767ec8c8e30450cea6ba660145e9c924abb75d7a6669b6c28a") @@ -380,13 +380,13 @@ func TestValidateTransactionForOperation(t *testing.T) { From("history_transactions ht") query = q.Operations(). IncludeTransactions(). - ForAccount(accountID) + ForAccount(tt.Ctx, accountID) - _, _, err = query.Fetch() + _, _, err = query.Fetch(tt.Ctx) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction successful flag false does not match transaction successful flag in operation true") - _, _, err = q.OperationByID(true, 17179877377) + _, _, err = q.OperationByID(tt.Ctx, true, 17179877377) tt.Assert.Error(err) tt.Assert.EqualError(err, "transaction successful flag false does not match transaction successful flag in operation true") } diff --git a/services/horizon/internal/db2/history/orderbook.go b/services/horizon/internal/db2/history/orderbook.go index cfa96c418e..4ea068f022 100644 --- a/services/horizon/internal/db2/history/orderbook.go +++ b/services/horizon/internal/db2/history/orderbook.go @@ -1,10 +1,11 @@ package history import ( + "context" "database/sql" - "github.com/stellar/go/amount" "math/big" + "github.com/stellar/go/amount" "github.com/stellar/go/support/errors" "github.com/stellar/go/xdr" ) @@ -40,7 +41,7 @@ type OrderBookSummary struct { // GetOrderBookSummary returns an OrderBookSummary for a given trading pair. // GetOrderBookSummary should only be called in a repeatable read transaction. -func (q *Q) GetOrderBookSummary(sellingAsset, buyingAsset xdr.Asset, maxPriceLevels int) (OrderBookSummary, error) { +func (q *Q) GetOrderBookSummary(ctx context.Context, sellingAsset, buyingAsset xdr.Asset, maxPriceLevels int) (OrderBookSummary, error) { var result OrderBookSummary if tx := q.GetTx(); tx == nil { @@ -100,12 +101,12 @@ func (q *Q) GetOrderBookSummary(sellingAsset, buyingAsset xdr.Asset, maxPriceLev LIMIT $3 ) ` - err = q.SelectRaw(&levels, selectPriceLevels, selling, buying, maxPriceLevels) + err = q.SelectRaw(ctx, &levels, selectPriceLevels, selling, buying, maxPriceLevels) if err != nil { return result, errors.Wrap(err, "cannot select price levels") } - err = q.SelectRaw(&offers, selectOfferSummaries, selling, buying, maxPriceLevels) + err = q.SelectRaw(ctx, &offers, selectOfferSummaries, selling, buying, maxPriceLevels) if err != nil { return result, errors.Wrap(err, "cannot select offer summaries") } diff --git a/services/horizon/internal/db2/history/orderbook_test.go b/services/horizon/internal/db2/history/orderbook_test.go index 004e4d6a27..4d4d35e6da 100644 --- a/services/horizon/internal/db2/history/orderbook_test.go +++ b/services/horizon/internal/db2/history/orderbook_test.go @@ -15,13 +15,13 @@ func TestGetOrderBookSummaryRequiresTransaction(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, err := q.GetOrderBookSummary(nativeAsset, eurAsset, 10) + _, err := q.GetOrderBookSummary(tt.Ctx, nativeAsset, eurAsset, 10) assert.EqualError(t, err, "cannot be called outside of a transaction") - assert.NoError(t, q.Begin()) - defer q.Rollback() + assert.NoError(t, q.Begin(tt.Ctx)) + defer q.Rollback(tt.Ctx) - _, err = q.GetOrderBookSummary(nativeAsset, eurAsset, 10) + _, err = q.GetOrderBookSummary(tt.Ctx, nativeAsset, eurAsset, 10) assert.EqualError(t, err, "should only be called in a repeatable read transaction") } @@ -212,21 +212,21 @@ func TestGetOrderBookSummary(t *testing.T) { }, } { t.Run(testCase.name, func(t *testing.T) { - assert.NoError(t, q.TruncateTables([]string{"offers"})) + assert.NoError(t, q.TruncateTables(tt.Ctx, []string{"offers"})) batch := q.NewOffersBatchInsertBuilder(0) for _, offer := range testCase.offers { - assert.NoError(t, batch.Add(offer)) + assert.NoError(t, batch.Add(tt.Ctx, offer)) } - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - assert.NoError(t, q.BeginTx(&sql.TxOptions{ + assert.NoError(t, q.BeginTx(tt.Ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, })) - defer q.Rollback() + defer q.Rollback(tt.Ctx) - result, err := q.GetOrderBookSummary(nativeAsset, eurAsset, testCase.limit) + result, err := q.GetOrderBookSummary(tt.Ctx, nativeAsset, eurAsset, testCase.limit) assert.NoError(t, err) assert.Equal(t, testCase.expected, result) }) @@ -262,54 +262,54 @@ func TestGetOrderBookSummaryExcludesRemovedOffers(t *testing.T) { batch := q.NewOffersBatchInsertBuilder(0) for _, offer := range offers { - assert.NoError(t, batch.Add(offer)) + assert.NoError(t, batch.Add(tt.Ctx, offer)) } - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - assert.NoError(t, q.BeginTx(&sql.TxOptions{ + assert.NoError(t, q.BeginTx(tt.Ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, })) - result, err := q.GetOrderBookSummary(nativeAsset, eurAsset, 100) + result, err := q.GetOrderBookSummary(tt.Ctx, nativeAsset, eurAsset, 100) assert.NoError(t, err) assert.Len(t, result.Asks, 2) assert.Len(t, result.Bids, 1) - assert.NoError(t, q.Rollback()) + assert.NoError(t, q.Rollback(tt.Ctx)) for i, offer := range offers { var count int64 - count, err = q.RemoveOffers([]int64{offer.OfferID}, uint32(i+2)) + count, err = q.RemoveOffers(tt.Ctx, []int64{offer.OfferID}, uint32(i+2)) assert.NoError(t, err) assert.Equal(t, int64(1), count) } - assert.NoError(t, q.BeginTx(&sql.TxOptions{ + assert.NoError(t, q.BeginTx(tt.Ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, })) - result, err = q.GetOrderBookSummary(nativeAsset, eurAsset, 100) + result, err = q.GetOrderBookSummary(tt.Ctx, nativeAsset, eurAsset, 100) assert.NoError(t, err) assert.Len(t, result.Asks, 0) assert.Len(t, result.Bids, 0) - assert.NoError(t, q.Rollback()) + assert.NoError(t, q.Rollback(tt.Ctx)) - count, err := q.CompactOffers(1000) + count, err := q.CompactOffers(tt.Ctx, 1000) assert.NoError(t, err) assert.Equal(t, int64(len(offers)), count) - assert.NoError(t, q.BeginTx(&sql.TxOptions{ + assert.NoError(t, q.BeginTx(tt.Ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, })) - result, err = q.GetOrderBookSummary(nativeAsset, eurAsset, 100) + result, err = q.GetOrderBookSummary(tt.Ctx, nativeAsset, eurAsset, 100) assert.NoError(t, err) assert.Len(t, result.Asks, 0) assert.Len(t, result.Bids, 0) - assert.NoError(t, q.Rollback()) + assert.NoError(t, q.Rollback(tt.Ctx)) } diff --git a/services/horizon/internal/db2/history/participants.go b/services/horizon/internal/db2/history/participants.go index 462ffda2da..658e877f78 100644 --- a/services/horizon/internal/db2/history/participants.go +++ b/services/horizon/internal/db2/history/participants.go @@ -1,6 +1,8 @@ package history import ( + "context" + "github.com/stellar/go/support/db" ) @@ -14,8 +16,8 @@ type QParticipants interface { // TransactionParticipantsBatchInsertBuilder is used to insert transaction participants into the // history_transaction_participants table type TransactionParticipantsBatchInsertBuilder interface { - Add(transactionID, accountID int64) error - Exec() error + Add(ctx context.Context, transactionID, accountID int64) error + Exec(ctx context.Context) error } type transactionParticipantsBatchInsertBuilder struct { @@ -33,14 +35,14 @@ func (q *Q) NewTransactionParticipantsBatchInsertBuilder(maxBatchSize int) Trans } // Add adds a new transaction participant to the batch -func (i *transactionParticipantsBatchInsertBuilder) Add(transactionID, accountID int64) error { - return i.builder.Row(map[string]interface{}{ +func (i *transactionParticipantsBatchInsertBuilder) Add(ctx context.Context, transactionID, accountID int64) error { + return i.builder.Row(ctx, map[string]interface{}{ "history_transaction_id": transactionID, "history_account_id": accountID, }) } // Exec flushes all pending transaction participants to the db -func (i *transactionParticipantsBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *transactionParticipantsBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/participants_test.go b/services/horizon/internal/db2/history/participants_test.go index 1c656ef883..ee37f2b833 100644 --- a/services/horizon/internal/db2/history/participants_test.go +++ b/services/horizon/internal/db2/history/participants_test.go @@ -18,7 +18,7 @@ func getTransactionParticipants(tt *test.T, q *Q) []transactionParticipant { From("history_transaction_participants"). OrderBy("(history_transaction_id, history_account_id) asc") - err := q.Select(&participants, sql) + err := q.Select(tt.Ctx, &participants, sql) if err != nil { tt.T.Fatal(err) } @@ -39,11 +39,11 @@ func TestTransactionParticipantsBatch(t *testing.T) { accountID := int64(100) for i := int64(0); i < 3; i++ { - tt.Assert.NoError(batch.Add(transactionID, accountID+i)) + tt.Assert.NoError(batch.Add(tt.Ctx, transactionID, accountID+i)) } - tt.Assert.NoError(batch.Add(otherTransactionID, accountID)) - tt.Assert.NoError(batch.Exec()) + tt.Assert.NoError(batch.Add(tt.Ctx, otherTransactionID, accountID)) + tt.Assert.NoError(batch.Exec(tt.Ctx)) participants := getTransactionParticipants(tt, q) tt.Assert.Equal( diff --git a/services/horizon/internal/db2/history/sequence_provider.go b/services/horizon/internal/db2/history/sequence_provider.go index ac26053480..97f53e9253 100644 --- a/services/horizon/internal/db2/history/sequence_provider.go +++ b/services/horizon/internal/db2/history/sequence_provider.go @@ -1,16 +1,18 @@ package history import ( + "context" + sq "github.com/Masterminds/squirrel" "github.com/stellar/go/support/errors" ) -func (q *Q) GetSequenceNumbers(addresses []string) (map[string]uint64, error) { +func (q *Q) GetSequenceNumbers(ctx context.Context, addresses []string) (map[string]uint64, error) { var accounts []AccountEntry sql := sq.Select("account_id, sequence_number").From("accounts"). Where(map[string]interface{}{"accounts.account_id": addresses}) - if err := q.Select(&accounts, sql); err != nil { + if err := q.Select(ctx, &accounts, sql); err != nil { return nil, errors.Wrap(err, "could not query accounts") } diff --git a/services/horizon/internal/db2/history/sequence_provider_test.go b/services/horizon/internal/db2/history/sequence_provider_test.go index f56054cae1..5ed67d7731 100644 --- a/services/horizon/internal/db2/history/sequence_provider_test.go +++ b/services/horizon/internal/db2/history/sequence_provider_test.go @@ -17,7 +17,7 @@ func TestSequenceProviderEmptyDB(t *testing.T) { "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB", "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H", } - results, err := q.GetSequenceNumbers(addresses) + results, err := q.GetSequenceNumbers(tt.Ctx, addresses) assert.NoError(t, err) assert.Len(t, results, 0) } @@ -29,13 +29,13 @@ func TestSequenceProviderGet(t *testing.T) { q := &Q{tt.HorizonSession()} batch := q.NewAccountsBatchInsertBuilder(0) - err := batch.Add(account1) + err := batch.Add(tt.Ctx, account1) assert.NoError(t, err) - err = batch.Add(account2) + err = batch.Add(tt.Ctx, account2) assert.NoError(t, err) - assert.NoError(t, batch.Exec()) + assert.NoError(t, batch.Exec(tt.Ctx)) - results, err := q.GetSequenceNumbers([]string{ + results, err := q.GetSequenceNumbers(tt.Ctx, []string{ "GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB", "GCT2NQM5KJJEF55NPMY444C6M6CA7T33HRNCMA6ZFBIIXKNCRO6J25K7", "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H", diff --git a/services/horizon/internal/db2/history/trade.go b/services/horizon/internal/db2/history/trade.go index d034072087..a291d0357e 100644 --- a/services/horizon/internal/db2/history/trade.go +++ b/services/horizon/internal/db2/history/trade.go @@ -1,6 +1,7 @@ package history import ( + "context" "fmt" "math" @@ -77,9 +78,9 @@ func (q *TradesQ) forAssetPair(baseAssetId int64, counterAssetId int64) *TradesQ } // ForAccount filter Trades by account id -func (q *TradesQ) ForAccount(aid string) *TradesQ { +func (q *TradesQ) ForAccount(ctx context.Context, aid string) *TradesQ { var account Account - q.Err = q.parent.AccountByAddress(&account, aid) + q.Err = q.parent.AccountByAddress(ctx, &account, aid) if q.Err != nil { return q } @@ -89,7 +90,7 @@ func (q *TradesQ) ForAccount(aid string) *TradesQ { } // Page specifies the paging constraints for the query being built by `q`. -func (q *TradesQ) Page(page db2.PageQuery) *TradesQ { +func (q *TradesQ) Page(ctx context.Context, page db2.PageQuery) *TradesQ { if q.Err != nil { return q } @@ -119,8 +120,8 @@ func (q *TradesQ) Page(page db2.PageQuery) *TradesQ { secondSelect = q.sql.Where("htrd.counter_offer_id = ?", q.forOfferID) } - firstSelect = q.appendOrdering(firstSelect, op, idx, page.Order) - secondSelect = q.appendOrdering(secondSelect, op, idx, page.Order) + firstSelect = q.appendOrdering(ctx, firstSelect, op, idx, page.Order) + secondSelect = q.appendOrdering(ctx, secondSelect, op, idx, page.Order) firstSQL, firstArgs, err := firstSelect.ToSql() if err != nil { @@ -149,13 +150,13 @@ func (q *TradesQ) Page(page db2.PageQuery) *TradesQ { // Reset sql so it's not used accidentally q.sql = sq.SelectBuilder{} } else { - q.sql = q.appendOrdering(q.sql, op, idx, page.Order) + q.sql = q.appendOrdering(ctx, q.sql, op, idx, page.Order) q.sql = q.sql.Limit(page.Limit) } return q } -func (q *TradesQ) appendOrdering(sel sq.SelectBuilder, op, idx int64, order string) sq.SelectBuilder { +func (q *TradesQ) appendOrdering(ctx context.Context, sel sq.SelectBuilder, op, idx int64, order string) sq.SelectBuilder { // NOTE: Remember to test the queries below with EXPLAIN / EXPLAIN ANALYZE // before changing them. // This condition is using multicolumn index and it's easy to write it in a way that @@ -185,7 +186,7 @@ func (q *TradesQ) appendOrdering(sel sq.SelectBuilder, op, idx int64, order stri } // Select loads the results of the query specified by `q` into `dest`. -func (q *TradesQ) Select(dest interface{}) error { +func (q *TradesQ) Select(ctx context.Context, dest interface{}) error { if q.Err != nil { return q.Err } @@ -195,9 +196,9 @@ func (q *TradesQ) Select(dest interface{}) error { } if q.rawSQL != "" { - q.Err = q.parent.SelectRaw(dest, q.rawSQL, q.rawArgs...) + q.Err = q.parent.SelectRaw(ctx, dest, q.rawSQL, q.rawArgs...) } else { - q.Err = q.parent.Select(dest, q.sql) + q.Err = q.parent.Select(ctx, dest, q.sql) } return q.Err } @@ -269,5 +270,5 @@ func getCanonicalAssetOrder(assetId1 int64, assetId2 int64) (orderPreserved bool type QTrades interface { QCreateAccountsHistory NewTradeBatchInsertBuilder(maxBatchSize int) TradeBatchInsertBuilder - CreateAssets(assets []xdr.Asset, maxBatchSize int) (map[string]Asset, error) + CreateAssets(ctx context.Context, assets []xdr.Asset, maxBatchSize int) (map[string]Asset, error) } diff --git a/services/horizon/internal/db2/history/trade_batch_insert_builder.go b/services/horizon/internal/db2/history/trade_batch_insert_builder.go index f017ab7874..5c47082e8d 100644 --- a/services/horizon/internal/db2/history/trade_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/trade_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "time" "github.com/stellar/go/support/db" @@ -27,8 +28,8 @@ type InsertTrade struct { // TradeBatchInsertBuilder is used to insert trades into the // history_trades table type TradeBatchInsertBuilder interface { - Add(entries ...InsertTrade) error - Exec() error + Add(ctx context.Context, entries ...InsertTrade) error + Exec(ctx context.Context) error } // tradeBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -47,12 +48,12 @@ func (q *Q) NewTradeBatchInsertBuilder(maxBatchSize int) TradeBatchInsertBuilder } // Exec flushes all outstanding trades to the database -func (i *tradeBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *tradeBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } // Add adds a new trade to the batch -func (i *tradeBatchInsertBuilder) Add(entries ...InsertTrade) error { +func (i *tradeBatchInsertBuilder) Add(ctx context.Context, entries ...InsertTrade) error { for _, entry := range entries { sellOfferID := EncodeOfferId(uint64(entry.Trade.OfferId), CoreOfferIDType) @@ -90,7 +91,7 @@ func (i *tradeBatchInsertBuilder) Add(entries ...InsertTrade) error { entry.SellPrice.Invert() } - err := i.builder.Row(map[string]interface{}{ + err := i.builder.Row(ctx, map[string]interface{}{ "history_operation_id": entry.HistoryOperationID, "\"order\"": entry.Order, "ledger_closed_at": entry.LedgerCloseTime, diff --git a/services/horizon/internal/db2/history/trade_test.go b/services/horizon/internal/db2/history/trade_test.go index 591fbe2e3f..8d1cefb354 100644 --- a/services/horizon/internal/db2/history/trade_test.go +++ b/services/horizon/internal/db2/history/trade_test.go @@ -20,7 +20,7 @@ func TestTradeQueries(t *testing.T) { var trades []Trade // All trades - err := q.Trades().Page(db2.MustPageQuery("", false, "asc", 100)).Select(&trades) + err := q.Trades().Page(tt.Ctx, db2.MustPageQuery("", false, "asc", 100)).Select(tt.Ctx, &trades) if tt.Assert.NoError(err) { tt.Assert.Len(trades, 4) } @@ -29,7 +29,7 @@ func TestTradeQueries(t *testing.T) { pq := db2.MustPageQuery(trades[0].PagingToken(), false, "asc", 1) var pt []Trade - err = q.Trades().Page(pq).Select(&pt) + err = q.Trades().Page(tt.Ctx, pq).Select(tt.Ctx, &pt) if tt.Assert.NoError(err) { if tt.Assert.Len(pt, 1) { tt.Assert.Equal(trades[1], pt[0]) @@ -38,25 +38,25 @@ func TestTradeQueries(t *testing.T) { // Cursor bounds checking pq = db2.MustPageQuery("", false, "desc", 1) - err = q.Trades().Page(pq).Select(&pt) + err = q.Trades().Page(tt.Ctx, pq).Select(tt.Ctx, &pt) tt.Require.NoError(err) // test for asset pairs - lumen, err := q.GetAssetID(xdr.MustNewNativeAsset()) + lumen, err := q.GetAssetID(tt.Ctx, xdr.MustNewNativeAsset()) tt.Require.NoError(err) - assetUSD, err := q.GetAssetID(xdr.MustNewCreditAsset("USD", "GB2QIYT2IAUFMRXKLSLLPRECC6OCOGJMADSPTRK7TGNT2SFR2YGWDARD")) + assetUSD, err := q.GetAssetID(tt.Ctx, xdr.MustNewCreditAsset("USD", "GB2QIYT2IAUFMRXKLSLLPRECC6OCOGJMADSPTRK7TGNT2SFR2YGWDARD")) tt.Require.NoError(err) - assetEUR, err := q.GetAssetID(xdr.MustNewCreditAsset("EUR", "GAXMF43TGZHW3QN3REOUA2U5PW5BTARXGGYJ3JIFHW3YT6QRKRL3CPPU")) + assetEUR, err := q.GetAssetID(tt.Ctx, xdr.MustNewCreditAsset("EUR", "GAXMF43TGZHW3QN3REOUA2U5PW5BTARXGGYJ3JIFHW3YT6QRKRL3CPPU")) tt.Require.NoError(err) - err = q.TradesForAssetPair(assetUSD, assetEUR).Page(db2.MustPageQuery("", false, "asc", 100)).Select(&trades) + err = q.TradesForAssetPair(assetUSD, assetEUR).Page(tt.Ctx, db2.MustPageQuery("", false, "asc", 100)).Select(tt.Ctx, &trades) tt.Require.NoError(err) tt.Assert.Len(trades, 0) - assetUSD, err = q.GetAssetID(xdr.MustNewCreditAsset("USD", "GAXMF43TGZHW3QN3REOUA2U5PW5BTARXGGYJ3JIFHW3YT6QRKRL3CPPU")) + assetUSD, err = q.GetAssetID(tt.Ctx, xdr.MustNewCreditAsset("USD", "GAXMF43TGZHW3QN3REOUA2U5PW5BTARXGGYJ3JIFHW3YT6QRKRL3CPPU")) tt.Require.NoError(err) - err = q.TradesForAssetPair(lumen, assetUSD).Page(db2.MustPageQuery("", false, "asc", 100)).Select(&trades) + err = q.TradesForAssetPair(lumen, assetUSD).Page(tt.Ctx, db2.MustPageQuery("", false, "asc", 100)).Select(tt.Ctx, &trades) tt.Require.NoError(err) tt.Assert.Len(trades, 1) @@ -65,7 +65,7 @@ func TestTradeQueries(t *testing.T) { tt.Assert.Equal(true, trades[0].BaseIsSeller) // reverse assets - err = q.TradesForAssetPair(assetUSD, lumen).Page(db2.MustPageQuery("", false, "asc", 100)).Select(&trades) + err = q.TradesForAssetPair(assetUSD, lumen).Page(tt.Ctx, db2.MustPageQuery("", false, "asc", 100)).Select(tt.Ctx, &trades) tt.Require.NoError(err) tt.Assert.Len(trades, 1) @@ -130,7 +130,7 @@ func createInsertTrades( func createAccountsAndAssets( tt *test.T, q *Q, accounts []string, assets []xdr.Asset, ) ([]int64, []int64) { - addressToAccounts, err := q.CreateAccounts(accounts, 2) + addressToAccounts, err := q.CreateAccounts(tt.Ctx, accounts, 2) tt.Assert.NoError(err) accountIDs := []int64{} @@ -138,7 +138,7 @@ func createAccountsAndAssets( accountIDs = append(accountIDs, addressToAccounts[account]) } - assetMap, err := q.CreateAssets(assets, 2) + assetMap, err := q.CreateAssets(tt.Ctx, assets, 2) tt.Assert.NoError(err) assetIDs := []int64{} @@ -195,12 +195,12 @@ func TestBatchInsertTrade(t *testing.T) { builder := q.NewTradeBatchInsertBuilder(1) tt.Assert.NoError( - builder.Add(first, second, third), + builder.Add(tt.Ctx, first, second, third), ) - tt.Assert.NoError(builder.Exec()) + tt.Assert.NoError(builder.Exec(tt.Ctx)) var rows []Trade - tt.Assert.NoError(q.Trades().Page(db2.MustPageQuery("", false, "asc", 100)).Select(&rows)) + tt.Assert.NoError(q.Trades().Page(tt.Ctx, db2.MustPageQuery("", false, "asc", 100)).Select(tt.Ctx, &rows)) idToAccount := buildIDtoAccountMapping(addresses, accountIDs) idToAsset := buildIDtoAssetMapping(assets, assetIDs) @@ -324,11 +324,11 @@ func TestTradesQueryForAccount(t *testing.T) { var trades []Trade account := "GAXMF43TGZHW3QN3REOUA2U5PW5BTARXGGYJ3JIFHW3YT6QRKRL3CPPU" - tradesQ.ForAccount(account) + tradesQ.ForAccount(tt.Ctx, account) tt.Assert.Equal(int64(15), tradesQ.forAccountID) tt.Assert.Equal(int64(0), tradesQ.forOfferID) - tradesQ.Page(db2.MustPageQuery("", false, "desc", 100)) + tradesQ.Page(tt.Ctx, db2.MustPageQuery("", false, "desc", 100)) _, _, err := tradesQ.sql.ToSql() // q.sql was reset in Page so should return error tt.Assert.EqualError(err, "select statements must have at least one result column") @@ -346,7 +346,7 @@ func TestTradesQueryForAccount(t *testing.T) { )) ORDER BY htrd.history_operation_id desc, htrd.order desc) ORDER BY history_operation_id desc, "order" desc LIMIT 100` tt.Assert.Equal(expectedRawSQL, tradesQ.rawSQL) - err = tradesQ.Select(&trades) + err = tradesQ.Select(tt.Ctx, &trades) tt.Assert.NoError(err) tt.Assert.Len(trades, 3) @@ -376,7 +376,7 @@ func TestTradesQueryForOffer(t *testing.T) { tt.Assert.Equal(int64(0), tradesQ.forAccountID) tt.Assert.Equal(int64(2), tradesQ.forOfferID) - tradesQ.Page(db2.MustPageQuery("", false, "asc", 100)) + tradesQ.Page(tt.Ctx, db2.MustPageQuery("", false, "asc", 100)) _, _, err := tradesQ.sql.ToSql() // q.sql was reset in Page so should return error tt.Assert.EqualError(err, "select statements must have at least one result column") @@ -394,7 +394,7 @@ func TestTradesQueryForOffer(t *testing.T) { )) ORDER BY htrd.history_operation_id asc, htrd.order asc) ORDER BY history_operation_id asc, "order" asc LIMIT 100` tt.Assert.Equal(expectedRawSQL, tradesQ.rawSQL) - err = tradesQ.Select(&trades) + err = tradesQ.Select(tt.Ctx, &trades) tt.Assert.NoError(err) tt.Assert.Len(trades, 2) diff --git a/services/horizon/internal/db2/history/transaction.go b/services/horizon/internal/db2/history/transaction.go index 63075488c7..622bf60287 100644 --- a/services/horizon/internal/db2/history/transaction.go +++ b/services/horizon/internal/db2/history/transaction.go @@ -1,7 +1,10 @@ package history import ( + "context" + sq "github.com/Masterminds/squirrel" + "github.com/stellar/go/services/horizon/internal/db2" "github.com/stellar/go/services/horizon/internal/toid" "github.com/stellar/go/support/errors" @@ -10,7 +13,7 @@ import ( // TransactionByHash is a query that loads a single row from the // `history_transactions` table based upon the provided hash. -func (q *Q) TransactionByHash(dest interface{}, hash string) error { +func (q *Q) TransactionByHash(ctx context.Context, dest interface{}, hash string) error { byHash := selectTransaction. Where("ht.transaction_hash = ?", hash) byInnerHash := selectTransaction. @@ -22,12 +25,12 @@ func (q *Q) TransactionByHash(dest interface{}, hash string) error { } union := byHash.Suffix("UNION ALL "+byInnerHashString, args...) - return q.Get(dest, union) + return q.Get(ctx, dest, union) } // TransactionsByIDs fetches transactions from the `history_transactions` table // which match the given ids -func (q *Q) TransactionsByIDs(ids ...int64) (map[int64]Transaction, error) { +func (q *Q) TransactionsByIDs(ctx context.Context, ids ...int64) (map[int64]Transaction, error) { if len(ids) == 0 { return nil, errors.New("no id arguments provided") } @@ -37,7 +40,7 @@ func (q *Q) TransactionsByIDs(ids ...int64) (map[int64]Transaction, error) { }) var transactions []Transaction - if err := q.Select(&transactions, sql); err != nil { + if err := q.Select(ctx, &transactions, sql); err != nil { return nil, err } @@ -61,9 +64,9 @@ func (q *Q) Transactions() *TransactionsQ { } // ForAccount filters the transactions collection to a specific account -func (q *TransactionsQ) ForAccount(aid string) *TransactionsQ { +func (q *TransactionsQ) ForAccount(ctx context.Context, aid string) *TransactionsQ { var account Account - q.Err = q.parent.AccountByAddress(&account, aid) + q.Err = q.parent.AccountByAddress(ctx, &account, aid) if q.Err != nil { return q } @@ -76,10 +79,10 @@ func (q *TransactionsQ) ForAccount(aid string) *TransactionsQ { } // ForClaimableBalance filters the transactions collection to a specific claimable balance -func (q *TransactionsQ) ForClaimableBalance(cbID xdr.ClaimableBalanceId) *TransactionsQ { +func (q *TransactionsQ) ForClaimableBalance(ctx context.Context, cbID xdr.ClaimableBalanceId) *TransactionsQ { var hCB HistoryClaimableBalance - hCB, q.Err = q.parent.ClaimableBalanceByID(cbID) + hCB, q.Err = q.parent.ClaimableBalanceByID(ctx, cbID) if q.Err != nil { return q } @@ -93,9 +96,9 @@ func (q *TransactionsQ) ForClaimableBalance(cbID xdr.ClaimableBalanceId) *Transa // ForLedger filters the query to a only transactions in a specific ledger, // specified by its sequence. -func (q *TransactionsQ) ForLedger(seq int32) *TransactionsQ { +func (q *TransactionsQ) ForLedger(ctx context.Context, seq int32) *TransactionsQ { var ledger Ledger - q.Err = q.parent.LedgerBySequence(&ledger, seq) + q.Err = q.parent.LedgerBySequence(ctx, &ledger, seq) if q.Err != nil { return q } @@ -128,7 +131,7 @@ func (q *TransactionsQ) Page(page db2.PageQuery) *TransactionsQ { } // Select loads the results of the query specified by `q` into `dest`. -func (q *TransactionsQ) Select(dest interface{}) error { +func (q *TransactionsQ) Select(ctx context.Context, dest interface{}) error { if q.Err != nil { return q.Err } @@ -138,7 +141,7 @@ func (q *TransactionsQ) Select(dest interface{}) error { Where("(ht.successful = true OR ht.successful IS NULL)") } - q.Err = q.parent.Select(dest, q.sql) + q.Err = q.parent.Select(ctx, dest, q.sql) if q.Err != nil { return q.Err } diff --git a/services/horizon/internal/db2/history/transaction_batch_insert_builder.go b/services/horizon/internal/db2/history/transaction_batch_insert_builder.go index 256f4a59fa..eb8e24c644 100644 --- a/services/horizon/internal/db2/history/transaction_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/transaction_batch_insert_builder.go @@ -1,6 +1,7 @@ package history import ( + "context" "database/sql/driver" "encoding/base64" "encoding/hex" @@ -24,8 +25,8 @@ import ( // TransactionBatchInsertBuilder is used to insert transactions into the // history_transactions table type TransactionBatchInsertBuilder interface { - Add(transaction ingest.LedgerTransaction, sequence uint32) error - Exec() error + Add(ctx context.Context, transaction ingest.LedgerTransaction, sequence uint32) error + Exec(ctx context.Context) error } // transactionBatchInsertBuilder is a simple wrapper around db.BatchInsertBuilder @@ -44,17 +45,17 @@ func (q *Q) NewTransactionBatchInsertBuilder(maxBatchSize int) TransactionBatchI } // Add adds a new transaction to the batch -func (i *transactionBatchInsertBuilder) Add(transaction ingest.LedgerTransaction, sequence uint32) error { +func (i *transactionBatchInsertBuilder) Add(ctx context.Context, transaction ingest.LedgerTransaction, sequence uint32) error { row, err := transactionToRow(transaction, sequence) if err != nil { return err } - return i.builder.RowStruct(row) + return i.builder.RowStruct(ctx, row) } -func (i *transactionBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *transactionBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } // TimeBounds represents the time bounds of a Stellar transaction diff --git a/services/horizon/internal/db2/history/transaction_test.go b/services/horizon/internal/db2/history/transaction_test.go index 1ff437ad41..e07d24e9c3 100644 --- a/services/horizon/internal/db2/history/transaction_test.go +++ b/services/horizon/internal/db2/history/transaction_test.go @@ -22,11 +22,11 @@ func TestTransactionQueries(t *testing.T) { // Test TransactionByHash var tx Transaction real := "2374e99349b9ef7dba9a5db3339b78fda8f34777b1af33ba468ad5c0df946d4d" - err := q.TransactionByHash(&tx, real) + err := q.TransactionByHash(tt.Ctx, &tx, real) tt.Assert.NoError(err) fake := "not_real" - err = q.TransactionByHash(&tx, fake) + err = q.TransactionByHash(tt.Ctx, &tx, fake) tt.Assert.Equal(err, sql.ErrNoRows) } @@ -43,9 +43,9 @@ func TestTransactionSuccessfulOnly(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Transactions(). - ForAccount("GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2") + ForAccount(tt.Ctx, "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2") - err := query.Select(&transactions) + err := query.Select(tt.Ctx, &transactions) tt.Assert.NoError(err) tt.Assert.Equal(3, len(transactions)) @@ -70,10 +70,10 @@ func TestTransactionIncludeFailed(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Transactions(). - ForAccount("GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). + ForAccount(tt.Ctx, "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). IncludeFailed() - err := query.Select(&transactions) + err := query.Select(tt.Ctx, &transactions) tt.Assert.NoError(err) var failed, successful int @@ -108,10 +108,10 @@ func TestExtraChecksTransactionSuccessfulTrueResultFalse(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Transactions(). - ForAccount("GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). + ForAccount(tt.Ctx, "GA5WBPYA5Y4WAEHXWR2UKO2UO4BUGHUQ74EUPKON2QHV4WRHOIRNKKH2"). IncludeFailed() - err = query.Select(&transactions) + err = query.Select(tt.Ctx, &transactions) tt.Assert.Error(err) tt.Assert.Contains(err.Error(), "Corrupted data! `successful=true` but returned transaction is not success") } @@ -131,10 +131,10 @@ func TestExtraChecksTransactionSuccessfulFalseResultTrue(t *testing.T) { q := &Q{tt.HorizonSession()} query := q.Transactions(). - ForAccount("GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). + ForAccount(tt.Ctx, "GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON"). IncludeFailed() - err = query.Select(&transactions) + err = query.Select(tt.Ctx, &transactions) tt.Assert.Error(err) tt.Assert.Contains(err.Error(), "Corrupted data! `successful=false` but returned transaction is success") } @@ -165,12 +165,12 @@ func TestInsertTransactionDoesNotAllowDuplicateIndex(t *testing.T) { hash: "7e2def20d5a21a56be2a457b648f702ee1af889d3df65790e92a05081e9fabf1", }) - tt.Assert.NoError(insertBuilder.Add(firstTransaction, sequence)) - tt.Assert.NoError(insertBuilder.Exec()) + tt.Assert.NoError(insertBuilder.Add(tt.Ctx, firstTransaction, sequence)) + tt.Assert.NoError(insertBuilder.Exec(tt.Ctx)) - tt.Assert.NoError(insertBuilder.Add(secondTransaction, sequence)) + tt.Assert.NoError(insertBuilder.Add(tt.Ctx, secondTransaction, sequence)) tt.Assert.EqualError( - insertBuilder.Exec(), + insertBuilder.Exec(tt.Ctx), "error adding values while inserting to history_transactions: "+ "exec failed: pq: duplicate key value violates unique constraint "+ "\"hs_transaction_by_id\"", @@ -197,11 +197,11 @@ func TestInsertTransactionDoesNotAllowDuplicateIndex(t *testing.T) { } *ledger.SuccessfulTransactionCount = 12 *ledger.FailedTransactionCount = 3 - _, err := q.Exec(sq.Insert("history_ledgers").SetMap(ledgerToMap(ledger))) + _, err := q.Exec(tt.Ctx, sq.Insert("history_ledgers").SetMap(ledgerToMap(ledger))) tt.Assert.NoError(err) var transactions []Transaction - tt.Assert.NoError(q.Transactions().Select(&transactions)) + tt.Assert.NoError(q.Transactions().Select(tt.Ctx, &transactions)) tt.Assert.Len(transactions, 1) tt.Assert.Equal( "19aaa18db88605aedec04659fb45e06f240b022eb2d429e05133e4d53cd945ba", @@ -237,7 +237,7 @@ func TestInsertTransaction(t *testing.T) { } *ledger.SuccessfulTransactionCount = 12 *ledger.FailedTransactionCount = 3 - _, err := q.Exec(sq.Insert("history_ledgers").SetMap(ledgerToMap(ledger))) + _, err := q.Exec(tt.Ctx, sq.Insert("history_ledgers").SetMap(ledgerToMap(ledger))) tt.Assert.NoError(err) insertBuilder := q.NewTransactionBatchInsertBuilder(0) @@ -692,11 +692,11 @@ func TestInsertTransaction(t *testing.T) { }, } { t.Run(testCase.name, func(t *testing.T) { - tt.Assert.NoError(insertBuilder.Add(testCase.toInsert, sequence)) - tt.Assert.NoError(insertBuilder.Exec()) + tt.Assert.NoError(insertBuilder.Add(tt.Ctx, testCase.toInsert, sequence)) + tt.Assert.NoError(insertBuilder.Exec(tt.Ctx)) var transactions []Transaction - tt.Assert.NoError(q.Transactions().IncludeFailed().Select(&transactions)) + tt.Assert.NoError(q.Transactions().IncludeFailed().Select(tt.Ctx, &transactions)) tt.Assert.Len(transactions, 1) transaction := transactions[0] @@ -712,7 +712,7 @@ func TestInsertTransaction(t *testing.T) { tt.Assert.True(closedAt.Equal(testCase.expected.LedgerCloseTime)) tt.Assert.Equal(transaction, testCase.expected) - _, err = q.Exec(sq.Delete("history_transactions")) + _, err = q.Exec(tt.Ctx, sq.Delete("history_transactions")) tt.Assert.NoError(err) }) } @@ -727,20 +727,20 @@ func TestFetchFeeBumpTransaction(t *testing.T) { fixture := FeeBumpScenario(tt, q, true) var byOuterhash, byInnerHash Transaction - tt.Assert.NoError(q.TransactionByHash(&byOuterhash, fixture.OuterHash)) - tt.Assert.NoError(q.TransactionByHash(&byInnerHash, fixture.InnerHash)) + tt.Assert.NoError(q.TransactionByHash(tt.Ctx, &byOuterhash, fixture.OuterHash)) + tt.Assert.NoError(q.TransactionByHash(tt.Ctx, &byInnerHash, fixture.InnerHash)) tt.Assert.Equal(byOuterhash, byInnerHash) tt.Assert.Equal(byOuterhash, fixture.Transaction) outerOps, outerTransactions, err := q.Operations().IncludeTransactions(). - ForTransaction(fixture.OuterHash).Fetch() + ForTransaction(tt.Ctx, fixture.OuterHash).Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(outerTransactions, 1) tt.Assert.Len(outerOps, 1) innerOps, innerTransactions, err := q.Operations().IncludeTransactions(). - ForTransaction(fixture.InnerHash).Fetch() + ForTransaction(tt.Ctx, fixture.InnerHash).Fetch(tt.Ctx) tt.Assert.NoError(err) tt.Assert.Len(innerTransactions, 1) tt.Assert.Equal(innerOps, outerOps) @@ -754,11 +754,11 @@ func TestFetchFeeBumpTransaction(t *testing.T) { } var outerEffects, innerEffects []Effect - err = q.Effects().ForTransaction(fixture.OuterHash).Select(&outerEffects) + err = q.Effects().ForTransaction(tt.Ctx, fixture.OuterHash).Select(tt.Ctx, &outerEffects) tt.Assert.NoError(err) tt.Assert.Len(outerEffects, 1) - err = q.Effects().ForTransaction(fixture.InnerHash).Select(&innerEffects) + err = q.Effects().ForTransaction(tt.Ctx, fixture.InnerHash).Select(tt.Ctx, &innerEffects) tt.Assert.NoError(err) tt.Assert.Equal(outerEffects, innerEffects) } diff --git a/services/horizon/internal/db2/history/trust_lines.go b/services/horizon/internal/db2/history/trust_lines.go index 27c3705643..1d351c9cd3 100644 --- a/services/horizon/internal/db2/history/trust_lines.go +++ b/services/horizon/internal/db2/history/trust_lines.go @@ -1,6 +1,7 @@ package history import ( + "context" "database/sql" "encoding/base64" @@ -31,7 +32,7 @@ func (trustLine TrustLine) IsClawbackEnabled() bool { // AssetsForAddress returns a list of assets and balances for those assets held by // a given address. -func (q *Q) AssetsForAddress(addy string) ([]xdr.Asset, []xdr.Int64, error) { +func (q *Q) AssetsForAddress(ctx context.Context, addy string) ([]xdr.Asset, []xdr.Int64, error) { if tx := q.GetTx(); tx == nil { return nil, nil, errors.New("cannot be called outside of a transaction") } @@ -39,7 +40,7 @@ func (q *Q) AssetsForAddress(addy string) ([]xdr.Asset, []xdr.Int64, error) { return nil, nil, errors.New("should only be called in a repeatable read transaction") } - account, err := q.GetAccountByID(addy) + account, err := q.GetAccountByID(ctx, addy) if q.NoRows(err) { // if there is no account for the given address then @@ -50,7 +51,7 @@ func (q *Q) AssetsForAddress(addy string) ([]xdr.Asset, []xdr.Int64, error) { } var tls []TrustLine - err = q.Select(&tls, selectTrustLines.Where(sq.Eq{"account_id": addy})) + err = q.Select(ctx, &tls, selectTrustLines.Where(sq.Eq{"account_id": addy})) if err != nil { return nil, nil, err } @@ -68,23 +69,23 @@ func (q *Q) AssetsForAddress(addy string) ([]xdr.Asset, []xdr.Int64, error) { return assets, balances, err } -func (q *Q) CountTrustLines() (int, error) { +func (q *Q) CountTrustLines(ctx context.Context) (int, error) { sql := sq.Select("count(*)").From("trust_lines") var count int - if err := q.Get(&count, sql); err != nil { + if err := q.Get(ctx, &count, sql); err != nil { return 0, errors.Wrap(err, "could not run select query") } return count, nil } -func (q *Q) GetSortedTrustLinesByAccountID(id string) ([]TrustLine, error) { - return q.GetSortedTrustLinesByAccountIDs([]string{id}) +func (q *Q) GetSortedTrustLinesByAccountID(ctx context.Context, id string) ([]TrustLine, error) { + return q.GetSortedTrustLinesByAccountIDs(ctx, []string{id}) } // GetTrustLinesByKeys loads a row from the `trust_lines` table, selected by multiple keys. -func (q *Q) GetTrustLinesByKeys(keys []xdr.LedgerKeyTrustLine) ([]TrustLine, error) { +func (q *Q) GetTrustLinesByKeys(ctx context.Context, keys []xdr.LedgerKeyTrustLine) ([]TrustLine, error) { var trustLines []TrustLine lkeys := make([]string, 0, len(keys)) for _, key := range keys { @@ -95,13 +96,13 @@ func (q *Q) GetTrustLinesByKeys(keys []xdr.LedgerKeyTrustLine) ([]TrustLine, err lkeys = append(lkeys, lkey) } sql := selectTrustLines.Where(map[string]interface{}{"trust_lines.ledger_key": lkeys}) - err := q.Select(&trustLines, sql) + err := q.Select(ctx, &trustLines, sql) return trustLines, err } // InsertTrustLine creates a row in the trust lines table. // Returns number of rows affected and error. -func (q *Q) InsertTrustLine(entry xdr.LedgerEntry) (int64, error) { +func (q *Q) InsertTrustLine(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { m := trustLineToMap(entry) // Add lkey only when inserting rows @@ -112,7 +113,7 @@ func (q *Q) InsertTrustLine(entry xdr.LedgerEntry) (int64, error) { m["ledger_key"] = key sql := sq.Insert("trust_lines").SetMap(m) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -122,7 +123,7 @@ func (q *Q) InsertTrustLine(entry xdr.LedgerEntry) (int64, error) { // UpdateTrustLine updates a row in the trust lines table. // Returns number of rows affected and error. -func (q *Q) UpdateTrustLine(entry xdr.LedgerEntry) (int64, error) { +func (q *Q) UpdateTrustLine(ctx context.Context, entry xdr.LedgerEntry) (int64, error) { key, err := trustLineEntryToLedgerKeyString(entry) if err != nil { return 0, errors.Wrap(err, "Error running trustLineEntryToLedgerKeyString") @@ -131,7 +132,7 @@ func (q *Q) UpdateTrustLine(entry xdr.LedgerEntry) (int64, error) { sql := sq.Update("trust_lines"). SetMap(trustLineToMap(entry)). Where(map[string]interface{}{"ledger_key": key}) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -143,7 +144,7 @@ func (q *Q) UpdateTrustLine(entry xdr.LedgerEntry) (int64, error) { // There's currently no limit of the number of trust lines this method can // accept other than 2GB limit of the query string length what should be enough // for each ledger with the current limits. -func (q *Q) UpsertTrustLines(trustLines []xdr.LedgerEntry) error { +func (q *Q) UpsertTrustLines(ctx context.Context, trustLines []xdr.LedgerEntry) error { var ledgerKey, accountID, assetIssuer, assetCode []string var balance, limit, buyingLiabilities, sellingLiabilities []xdr.Int64 var flags, lastModifiedLedger []xdr.Uint32 @@ -220,7 +221,7 @@ func (q *Q) UpsertTrustLines(trustLines []xdr.LedgerEntry) error { last_modified_ledger = excluded.last_modified_ledger, sponsor = excluded.sponsor` - _, err := q.ExecRaw(sql, + _, err := q.ExecRaw(ctx, sql, pq.Array(ledgerKey), pq.Array(accountID), pq.Array(assetType), @@ -238,7 +239,7 @@ func (q *Q) UpsertTrustLines(trustLines []xdr.LedgerEntry) error { // RemoveTrustLine deletes a row in the trust lines table. // Returns number of rows affected and error. -func (q *Q) RemoveTrustLine(ledgerKey xdr.LedgerKeyTrustLine) (int64, error) { +func (q *Q) RemoveTrustLine(ctx context.Context, ledgerKey xdr.LedgerKeyTrustLine) (int64, error) { key, err := ledgerKeyTrustLineToString(ledgerKey) if err != nil { return 0, errors.Wrap(err, "Error ledgerKeyTrustLineToString MarshalBinaryCompress") @@ -246,7 +247,7 @@ func (q *Q) RemoveTrustLine(ledgerKey xdr.LedgerKeyTrustLine) (int64, error) { sql := sq.Delete("trust_lines"). Where(map[string]interface{}{"ledger_key": key}) - result, err := q.Exec(sql) + result, err := q.Exec(ctx, sql) if err != nil { return 0, err } @@ -255,10 +256,10 @@ func (q *Q) RemoveTrustLine(ledgerKey xdr.LedgerKeyTrustLine) (int64, error) { } // GetSortedTrustLinesByAccountIDs loads trust lines for a list of accounts ID, ordered by asset and issuer -func (q *Q) GetSortedTrustLinesByAccountIDs(id []string) ([]TrustLine, error) { +func (q *Q) GetSortedTrustLinesByAccountIDs(ctx context.Context, id []string) ([]TrustLine, error) { var data []TrustLine sql := selectTrustLines.Where(sq.Eq{"account_id": id}).OrderBy("asset_code", "asset_issuer") - err := q.Select(&data, sql) + err := q.Select(ctx, &data, sql) return data, err } diff --git a/services/horizon/internal/db2/history/trust_lines_batch_insert_builder.go b/services/horizon/internal/db2/history/trust_lines_batch_insert_builder.go index aa6b32dc5b..cb710b5c4b 100644 --- a/services/horizon/internal/db2/history/trust_lines_batch_insert_builder.go +++ b/services/horizon/internal/db2/history/trust_lines_batch_insert_builder.go @@ -1,13 +1,15 @@ package history import ( + "context" + "github.com/stellar/go/support/errors" "github.com/stellar/go/xdr" ) // Add adds a new trust line entry to the batch. `lastModifiedLedger` is another // parameter because `xdr.TrustLineEntry` does not have a field to hold this value. -func (i *trustLinesBatchInsertBuilder) Add(entry xdr.LedgerEntry) error { +func (i *trustLinesBatchInsertBuilder) Add(ctx context.Context, entry xdr.LedgerEntry) error { m := trustLineToMap(entry) // Add lkey only when inserting rows @@ -17,9 +19,9 @@ func (i *trustLinesBatchInsertBuilder) Add(entry xdr.LedgerEntry) error { } m["ledger_key"] = key - return i.builder.Row(m) + return i.builder.Row(ctx, m) } -func (i *trustLinesBatchInsertBuilder) Exec() error { - return i.builder.Exec() +func (i *trustLinesBatchInsertBuilder) Exec(ctx context.Context) error { + return i.builder.Exec(ctx) } diff --git a/services/horizon/internal/db2/history/trust_lines_test.go b/services/horizon/internal/db2/history/trust_lines_test.go index 49aca2fa53..204567d241 100644 --- a/services/horizon/internal/db2/history/trust_lines_test.go +++ b/services/horizon/internal/db2/history/trust_lines_test.go @@ -108,11 +108,11 @@ func TestInsertTrustLine(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - rows, err := q.InsertTrustLine(eurTrustLine) + rows, err := q.InsertTrustLine(tt.Ctx, eurTrustLine) assert.NoError(t, err) assert.Equal(t, int64(1), rows) - rows, err = q.InsertTrustLine(usdTrustLine) + rows, err = q.InsertTrustLine(tt.Ctx, usdTrustLine) assert.NoError(t, err) assert.Equal(t, int64(1), rows) @@ -121,7 +121,7 @@ func TestInsertTrustLine(t *testing.T) { {Asset: usdTrustLine.Data.TrustLine.Asset, AccountId: usdTrustLine.Data.TrustLine.AccountId}, } - lines, err := q.GetTrustLinesByKeys(keys) + lines, err := q.GetTrustLinesByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, lines, 2) @@ -134,7 +134,7 @@ func TestUpdateTrustLine(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - rows, err := q.InsertTrustLine(eurTrustLine) + rows, err := q.InsertTrustLine(tt.Ctx, eurTrustLine) assert.NoError(t, err) assert.Equal(t, int64(1), rows) @@ -145,14 +145,14 @@ func TestUpdateTrustLine(t *testing.T) { modifiedTrustLine.Ext.V1 = &v1Copy modifiedTrustLine.Data.TrustLine.Balance = 30000 - rows, err = q.UpdateTrustLine(modifiedTrustLine) + rows, err = q.UpdateTrustLine(tt.Ctx, modifiedTrustLine) assert.NoError(t, err) assert.Equal(t, int64(1), rows) keys := []xdr.LedgerKeyTrustLine{ {Asset: eurTrustLine.Data.TrustLine.Asset, AccountId: eurTrustLine.Data.TrustLine.AccountId}, } - lines, err := q.GetTrustLinesByKeys(keys) + lines, err := q.GetTrustLinesByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, lines, 1) @@ -189,25 +189,25 @@ func TestUpsertTrustLines(t *testing.T) { q := &Q{tt.HorizonSession()} // Upserting nothing is no op - err := q.UpsertTrustLines([]xdr.LedgerEntry{}) + err := q.UpsertTrustLines(tt.Ctx, []xdr.LedgerEntry{}) assert.NoError(t, err) ledgerEntries := []xdr.LedgerEntry{eurTrustLine, usdTrustLine} - err = q.UpsertTrustLines(ledgerEntries) + err = q.UpsertTrustLines(tt.Ctx, ledgerEntries) assert.NoError(t, err) keys := []xdr.LedgerKeyTrustLine{ {Asset: eurTrustLine.Data.TrustLine.Asset, AccountId: eurTrustLine.Data.TrustLine.AccountId}, } - lines, err := q.GetTrustLinesByKeys(keys) + lines, err := q.GetTrustLinesByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, lines, 1) keys = []xdr.LedgerKeyTrustLine{ {Asset: usdTrustLine.Data.TrustLine.Asset, AccountId: usdTrustLine.Data.TrustLine.AccountId}, } - lines, err = q.GetTrustLinesByKeys(keys) + lines, err = q.GetTrustLinesByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, lines, 1) @@ -216,13 +216,13 @@ func TestUpsertTrustLines(t *testing.T) { ledgerEntries = []xdr.LedgerEntry{modifiedTrustLine} - err = q.UpsertTrustLines(ledgerEntries) + err = q.UpsertTrustLines(tt.Ctx, ledgerEntries) assert.NoError(t, err) keys = []xdr.LedgerKeyTrustLine{ {Asset: eurTrustLine.Data.TrustLine.Asset, AccountId: eurTrustLine.Data.TrustLine.AccountId}, } - lines, err = q.GetTrustLinesByKeys(keys) + lines, err = q.GetTrustLinesByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, lines, 1) @@ -267,7 +267,7 @@ func TestUpsertTrustLines(t *testing.T) { keys = []xdr.LedgerKeyTrustLine{ {Asset: usdTrustLine.Data.TrustLine.Asset, AccountId: usdTrustLine.Data.TrustLine.AccountId}, } - lines, err = q.GetTrustLinesByKeys(keys) + lines, err = q.GetTrustLinesByKeys(tt.Ctx, keys) assert.NoError(t, err) assert.Len(t, lines, 1) @@ -309,21 +309,21 @@ func TestRemoveTrustLine(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - rows, err := q.InsertTrustLine(eurTrustLine) + rows, err := q.InsertTrustLine(tt.Ctx, eurTrustLine) assert.NoError(t, err) assert.Equal(t, int64(1), rows) key := xdr.LedgerKeyTrustLine{Asset: eurTrustLine.Data.TrustLine.Asset, AccountId: eurTrustLine.Data.TrustLine.AccountId} - rows, err = q.RemoveTrustLine(key) + rows, err = q.RemoveTrustLine(tt.Ctx, key) assert.NoError(t, err) assert.Equal(t, int64(1), rows) - lines, err := q.GetTrustLinesByKeys([]xdr.LedgerKeyTrustLine{key}) + lines, err := q.GetTrustLinesByKeys(tt.Ctx, []xdr.LedgerKeyTrustLine{key}) assert.NoError(t, err) assert.Len(t, lines, 0) // Doesn't exist anymore - rows, err = q.RemoveTrustLine(key) + rows, err = q.RemoveTrustLine(tt.Ctx, key) assert.NoError(t, err) assert.Equal(t, int64(0), rows) } @@ -333,11 +333,11 @@ func TestGetSortedTrustLinesByAccountsID(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, err := q.InsertTrustLine(eurTrustLine) + _, err := q.InsertTrustLine(tt.Ctx, eurTrustLine) tt.Assert.NoError(err) - _, err = q.InsertTrustLine(usdTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, usdTrustLine) tt.Assert.NoError(err) - _, err = q.InsertTrustLine(usdTrustLine2) + _, err = q.InsertTrustLine(tt.Ctx, usdTrustLine2) tt.Assert.NoError(err) ids := []string{ @@ -345,7 +345,7 @@ func TestGetSortedTrustLinesByAccountsID(t *testing.T) { usdTrustLine.Data.TrustLine.AccountId.Address(), } - records, err := q.GetSortedTrustLinesByAccountIDs(ids) + records, err := q.GetSortedTrustLinesByAccountIDs(tt.Ctx, ids) tt.Assert.NoError(err) tt.Assert.Len(records, 2) @@ -378,10 +378,10 @@ func TestGetTrustLinesByAccountID(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, err := q.InsertTrustLine(eurTrustLine) + _, err := q.InsertTrustLine(tt.Ctx, eurTrustLine) tt.Assert.NoError(err) - record, err := q.GetSortedTrustLinesByAccountID(eurTrustLine.Data.TrustLine.AccountId.Address()) + record, err := q.GetSortedTrustLinesByAccountID(tt.Ctx, eurTrustLine.Data.TrustLine.AccountId.Address()) tt.Assert.NoError(err) asset := xdr.MustNewCreditAsset(record[0].AssetCode, record[0].AssetIssuer) @@ -401,13 +401,13 @@ func TestAssetsForAddressRequiresTransaction(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - _, _, err := q.AssetsForAddress(eurTrustLine.Data.TrustLine.AccountId.Address()) + _, _, err := q.AssetsForAddress(tt.Ctx, eurTrustLine.Data.TrustLine.AccountId.Address()) assert.EqualError(t, err, "cannot be called outside of a transaction") - assert.NoError(t, q.Begin()) - defer q.Rollback() + assert.NoError(t, q.Begin(tt.Ctx)) + defer q.Rollback(tt.Ctx) - _, _, err = q.AssetsForAddress(eurTrustLine.Data.TrustLine.AccountId.Address()) + _, _, err = q.AssetsForAddress(tt.Ctx, eurTrustLine.Data.TrustLine.AccountId.Address()) assert.EqualError(t, err, "should only be called in a repeatable read transaction") } @@ -419,10 +419,10 @@ func TestAssetsForAddress(t *testing.T) { ledgerEntries := []xdr.LedgerEntry{account1} - err := q.UpsertAccounts(ledgerEntries) + err := q.UpsertAccounts(tt.Ctx, ledgerEntries) assert.NoError(t, err) - _, err = q.InsertTrustLine(eurTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, eurTrustLine) tt.Assert.NoError(err) brlTrustLine := xdr.LedgerEntry{ @@ -448,22 +448,22 @@ func TestAssetsForAddress(t *testing.T) { }, } - _, err = q.InsertTrustLine(brlTrustLine) + _, err = q.InsertTrustLine(tt.Ctx, brlTrustLine) tt.Assert.NoError(err) - err = q.BeginTx(&sql.TxOptions{ + err = q.BeginTx(tt.Ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }) assert.NoError(t, err) - defer q.Rollback() + defer q.Rollback(tt.Ctx) - assets, balances, err := q.AssetsForAddress(usdTrustLine.Data.TrustLine.AccountId.Address()) + assets, balances, err := q.AssetsForAddress(tt.Ctx, usdTrustLine.Data.TrustLine.AccountId.Address()) tt.Assert.NoError(err) tt.Assert.Empty(assets) tt.Assert.Empty(balances) - assets, balances, err = q.AssetsForAddress(account1.Data.Account.AccountId.Address()) + assets, balances, err = q.AssetsForAddress(tt.Ctx, account1.Data.Account.AccountId.Address()) tt.Assert.NoError(err) assetsToBalance := map[string]xdr.Int64{} diff --git a/services/horizon/internal/health.go b/services/horizon/internal/health.go index b15214fc03..c41e4c8007 100644 --- a/services/horizon/internal/health.go +++ b/services/horizon/internal/health.go @@ -68,7 +68,7 @@ func (h healthCheck) runCheck() healthResponse { CoreUp: true, CoreSynced: true, } - if err := h.session.Ping(dbPingTimeout); err != nil { + if err := h.session.Ping(h.ctx, dbPingTimeout); err != nil { healthLogger.Warnf("could not ping db: %s", err) response.DatabaseConnected = false } diff --git a/services/horizon/internal/health_test.go b/services/horizon/internal/health_test.go index 7e1fc4d9c5..c235f6c8ce 100644 --- a/services/horizon/internal/health_test.go +++ b/services/horizon/internal/health_test.go @@ -118,9 +118,9 @@ func TestHealthCheck(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - session := &db.MockSession{} - session.On("Ping", dbPingTimeout).Return(tc.pingErr).Once() ctx := context.Background() + session := &db.MockSession{} + session.On("Ping", ctx, dbPingTimeout).Return(tc.pingErr).Once() core := &mockStellarCore{} core.On("Info", ctx).Return(tc.coreResponse, tc.coreErr).Once() @@ -180,8 +180,9 @@ func TestHealthCheckCache(t *testing.T) { assert.True(t, h.cache.lastUpdate.Equal(time.Unix(0, 0))) } + ctx := context.Background() session := &db.MockSession{} - session.On("Ping", dbPingTimeout).Return(nil).Once() + session.On("Ping", ctx, dbPingTimeout).Return(nil).Once() core := &mockStellarCore{} core.On("Info", h.ctx).Return(&stellarcore.InfoResponse{}, fmt.Errorf("core err")).Once() h.session = session diff --git a/services/horizon/internal/httpt_test.go b/services/horizon/internal/httpt_test.go index 11628fb319..1799822d5d 100644 --- a/services/horizon/internal/httpt_test.go +++ b/services/horizon/internal/httpt_test.go @@ -1,6 +1,7 @@ package horizon import ( + "context" "net/http" "net/http/httptest" "net/url" @@ -41,7 +42,7 @@ func startHTTPTest(t *testing.T, scenario string) *HTTPT { }`) ret.App.config.StellarCoreURL = ret.coreServer.URL - ret.App.UpdateLedgerState() + ret.App.UpdateLedgerState(context.Background()) return ret } @@ -98,7 +99,7 @@ func (ht *HTTPT) Post( // setting the retention count to the provided number. func (ht *HTTPT) ReapHistory(retention uint) { ht.App.reaper.RetentionCount = retention - err := ht.App.DeleteUnretainedHistory() + err := ht.App.DeleteUnretainedHistory(context.Background()) ht.Require.NoError(err) - ht.App.UpdateLedgerState() + ht.App.UpdateLedgerState(context.Background()) } diff --git a/services/horizon/internal/httpx/handler.go b/services/horizon/internal/httpx/handler.go index 39fd3c15f5..24ea92c338 100644 --- a/services/horizon/internal/httpx/handler.go +++ b/services/horizon/internal/httpx/handler.go @@ -104,14 +104,14 @@ func repeatableReadStream( return func() ([]sse.Event, error) { if session != nil { - err := session.BeginTx(&sql.TxOptions{ + err := session.BeginTx(r.Context(), &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }) if err != nil { return nil, errors.Wrap(err, "Error starting repeatable read transaction") } - defer session.Rollback() + defer session.Rollback(r.Context()) } return generateEvents() diff --git a/services/horizon/internal/httpx/middleware.go b/services/horizon/internal/httpx/middleware.go index b4d77faf81..164bc0d5fb 100644 --- a/services/horizon/internal/httpx/middleware.go +++ b/services/horizon/internal/httpx/middleware.go @@ -224,7 +224,6 @@ func NewHistoryMiddleware(ledgerState *ledger.State, staleThreshold int32, sessi } requestSession := session.Clone() - requestSession.Ctx = r.Context() h.ServeHTTP(w, r.WithContext( context.WithValue( r.Context(), @@ -246,15 +245,15 @@ type StateMiddleware struct { NoStateVerification bool } -func ingestionStatus(q *history.Q) (uint32, bool, error) { - version, err := q.GetIngestVersion() +func ingestionStatus(ctx context.Context, q *history.Q) (uint32, bool, error) { + version, err := q.GetIngestVersion(ctx) if err != nil { return 0, false, supportErrors.Wrap( err, "Error running GetIngestVersion", ) } - lastIngestedLedger, err := q.GetLastLedgerIngestNonBlocking() + lastIngestedLedger, err := q.GetLastLedgerIngestNonBlocking(ctx) if err != nil { return 0, false, supportErrors.Wrap( err, "Error running GetLastLedgerIngestNonBlocking", @@ -262,7 +261,7 @@ func ingestionStatus(q *history.Q) (uint32, bool, error) { } var lastHistoryLedger uint32 - err = q.LatestLedger(&lastHistoryLedger) + err = q.LatestLedger(ctx, &lastHistoryLedger) if err != nil { return 0, false, supportErrors.Wrap(err, "Error running LatestLedger") } @@ -277,6 +276,7 @@ func ingestionStatus(q *history.Q) (uint32, bool, error) { // WrapFunc executes the middleware on a given HTTP handler function func (m *StateMiddleware) WrapFunc(h http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() session := m.HorizonSession.Clone() q := &history.Q{session} sseRequest := render.Negotiate(r) == render.MimeEventStream @@ -286,8 +286,7 @@ func (m *StateMiddleware) WrapFunc(h http.HandlerFunc) http.HandlerFunc { // Otherwise, because the ingestion system is running concurrently with this request, // it is possible to have one read fetch data from ledger N and another read // fetch data from ledger N+1 . - session.Ctx = r.Context() - err := session.BeginTx(&sql.TxOptions{ + err := session.BeginTx(ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }) @@ -296,10 +295,10 @@ func (m *StateMiddleware) WrapFunc(h http.HandlerFunc) http.HandlerFunc { problem.Render(r.Context(), w, err) return } - defer session.Rollback() + defer session.Rollback(ctx) if !m.NoStateVerification { - stateInvalid, invalidErr := q.GetExpStateInvalid() + stateInvalid, invalidErr := q.GetExpStateInvalid(ctx) if invalidErr != nil { invalidErr = supportErrors.Wrap(invalidErr, "Error running GetExpStateInvalid") problem.Render(r.Context(), w, invalidErr) @@ -311,7 +310,7 @@ func (m *StateMiddleware) WrapFunc(h http.HandlerFunc) http.HandlerFunc { } } - lastIngestedLedger, ready, err := ingestionStatus(q) + lastIngestedLedger, ready, err := ingestionStatus(ctx, q) if err != nil { problem.Render(r.Context(), w, err) return @@ -325,7 +324,7 @@ func (m *StateMiddleware) WrapFunc(h http.HandlerFunc) http.HandlerFunc { // otherwise, the stream will not pick up updates occurring in future // ledgers if sseRequest { - if err = session.Rollback(); err != nil { + if err = session.Rollback(ctx); err != nil { problem.Render( r.Context(), w, diff --git a/services/horizon/internal/httpx/stream_handler_test.go b/services/horizon/internal/httpx/stream_handler_test.go index fa293ca479..ffc1149512 100644 --- a/services/horizon/internal/httpx/stream_handler_test.go +++ b/services/horizon/internal/httpx/stream_handler_test.go @@ -13,6 +13,7 @@ import ( "testing" "github.com/go-chi/chi" + "github.com/stretchr/testify/mock" "github.com/stellar/go/services/horizon/internal/actions" horizonContext "github.com/stellar/go/services/horizon/internal/context" @@ -477,17 +478,17 @@ func TestRepeatableReadStream(t *testing.T) { } session := &db.MockSession{} - session.On("BeginTx", &sql.TxOptions{ + session.On("BeginTx", mock.Anything, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - session.On("Rollback").Return(nil).Once() + session.On("Rollback", mock.Anything).Return(nil).Once() - session.On("BeginTx", &sql.TxOptions{ + session.On("BeginTx", mock.Anything, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - session.On("Rollback").Return(nil).Once() + session.On("Rollback", mock.Anything).Return(nil).Once() request := streamRequest(t, "limit=2") request = request.WithContext(context.WithValue( @@ -516,17 +517,17 @@ func TestRepeatableReadStream(t *testing.T) { } session := &db.MockSession{} - session.On("BeginTx", &sql.TxOptions{ + session.On("BeginTx", mock.Anything, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - session.On("Rollback").Return(nil).Once() + session.On("Rollback", mock.Anything).Return(nil).Once() - session.On("BeginTx", &sql.TxOptions{ + session.On("BeginTx", mock.Anything, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - session.On("Rollback").Return(nil).Once() + session.On("Rollback", mock.Anything).Return(nil).Once() request := streamRequest(t, "") request = request.WithContext(context.WithValue( diff --git a/services/horizon/internal/ingest/build_state_test.go b/services/horizon/internal/ingest/build_state_test.go index 72c73f563c..6b13539043 100644 --- a/services/horizon/internal/ingest/build_state_test.go +++ b/services/horizon/internal/ingest/build_state_test.go @@ -20,6 +20,7 @@ func TestBuildStateTestSuite(t *testing.T) { type BuildStateTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ historyAdapter *mockHistoryArchiveAdapter ledgerBackend *ledgerbackend.MockDatabaseBackend @@ -31,6 +32,7 @@ type BuildStateTestSuite struct { } func (s *BuildStateTestSuite) SetupTest() { + s.ctx = context.Background() s.historyQ = &mockDBQ{} s.runner = &mockProcessorsRunner{} s.historyAdapter = &mockHistoryArchiveAdapter{} @@ -39,7 +41,7 @@ func (s *BuildStateTestSuite) SetupTest() { s.checkpointLedger = uint32(63) s.lastLedger = 0 s.system = &system{ - ctx: context.Background(), + ctx: s.ctx, historyQ: s.historyQ, historyAdapter: s.historyAdapter, ledgerBackend: s.ledgerBackend, @@ -48,8 +50,8 @@ func (s *BuildStateTestSuite) SetupTest() { } s.system.initMetrics() - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() s.ledgerBackend.On("IsPrepared", ledgerbackend.UnboundedRange(63)).Return(false, nil).Once() s.ledgerBackend.On("PrepareRange", ledgerbackend.UnboundedRange(63)).Return(nil).Once() @@ -76,11 +78,11 @@ func (s *BuildStateTestSuite) TearDownTest() { } func (s *BuildStateTestSuite) mockCommonHistoryQ() { - s.historyQ.On("GetLastLedgerIngest").Return(s.lastLedger, nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", s.lastLedger).Return(nil).Once() - s.historyQ.On("UpdateExpStateInvalid", false).Return(nil).Once() - s.historyQ.On("TruncateIngestStateTables").Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(s.lastLedger, nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.lastLedger).Return(nil).Once() + s.historyQ.On("UpdateExpStateInvalid", s.ctx, false).Return(nil).Once() + s.historyQ.On("TruncateIngestStateTables", s.ctx).Return(nil).Once() s.stellarCoreClient.On( "SetCursor", mock.AnythingOfType("*context.timerCtx"), @@ -134,7 +136,7 @@ func (s *BuildStateTestSuite) TestRangeNotPreparedSuccessPrepareGetLedgerFail() func (s *BuildStateTestSuite) TestBeginReturnsError() { // Recreate mock in this single test to remove assertions. *s.historyQ = mockDBQ{} - s.historyQ.On("Begin").Return(errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(errors.New("my error")).Once() next, err := buildState{checkpointLedger: s.checkpointLedger}.run(s.system) s.Assert().Error(err) @@ -143,7 +145,7 @@ func (s *BuildStateTestSuite) TestBeginReturnsError() { } func (s *BuildStateTestSuite) TestGetLastLedgerIngestReturnsError() { - s.historyQ.On("GetLastLedgerIngest").Return(s.lastLedger, errors.New("my error")).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(s.lastLedger, errors.New("my error")).Once() next, err := buildState{checkpointLedger: s.checkpointLedger}.run(s.system) s.Assert().Error(err) @@ -151,8 +153,8 @@ func (s *BuildStateTestSuite) TestGetLastLedgerIngestReturnsError() { s.Assert().Equal(transition{node: startState{}, sleepDuration: defaultSleep}, next) } func (s *BuildStateTestSuite) TestGetIngestVersionReturnsError() { - s.historyQ.On("GetLastLedgerIngest").Return(s.lastLedger, nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, errors.New("my error")).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(s.lastLedger, nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, errors.New("my error")).Once() next, err := buildState{checkpointLedger: s.checkpointLedger}.run(s.system) s.Assert().Error(err) @@ -161,8 +163,8 @@ func (s *BuildStateTestSuite) TestGetIngestVersionReturnsError() { } func (s *BuildStateTestSuite) TestAnotherInstanceHasCompletedBuildState() { - s.historyQ.On("GetLastLedgerIngest").Return(s.checkpointLedger, nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(s.checkpointLedger, nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() next, err := buildState{checkpointLedger: s.checkpointLedger}.run(s.system) s.Assert().NoError(err) @@ -170,9 +172,9 @@ func (s *BuildStateTestSuite) TestAnotherInstanceHasCompletedBuildState() { } func (s *BuildStateTestSuite) TestUpdateLastLedgerIngestReturnsError() { - s.historyQ.On("GetLastLedgerIngest").Return(s.lastLedger, nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", s.lastLedger).Return(errors.New("my error")).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(s.lastLedger, nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.lastLedger).Return(errors.New("my error")).Once() s.stellarCoreClient.On( "SetCursor", mock.AnythingOfType("*context.timerCtx"), @@ -188,10 +190,10 @@ func (s *BuildStateTestSuite) TestUpdateLastLedgerIngestReturnsError() { } func (s *BuildStateTestSuite) TestUpdateExpStateInvalidReturnsError() { - s.historyQ.On("GetLastLedgerIngest").Return(s.lastLedger, nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", s.lastLedger).Return(nil).Once() - s.historyQ.On("UpdateExpStateInvalid", false).Return(errors.New("my error")).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(s.lastLedger, nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.lastLedger).Return(nil).Once() + s.historyQ.On("UpdateExpStateInvalid", s.ctx, false).Return(errors.New("my error")).Once() s.stellarCoreClient.On( "SetCursor", mock.AnythingOfType("*context.timerCtx"), @@ -207,11 +209,11 @@ func (s *BuildStateTestSuite) TestUpdateExpStateInvalidReturnsError() { } func (s *BuildStateTestSuite) TestTruncateIngestStateTablesReturnsError() { - s.historyQ.On("GetLastLedgerIngest").Return(s.lastLedger, nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", s.lastLedger).Return(nil).Once() - s.historyQ.On("UpdateExpStateInvalid", false).Return(nil).Once() - s.historyQ.On("TruncateIngestStateTables").Return(errors.New("my error")).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(s.lastLedger, nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.lastLedger).Return(nil).Once() + s.historyQ.On("UpdateExpStateInvalid", s.ctx, false).Return(nil).Once() + s.historyQ.On("TruncateIngestStateTables", s.ctx).Return(errors.New("my error")).Once() s.stellarCoreClient.On( "SetCursor", @@ -244,11 +246,11 @@ func (s *BuildStateTestSuite) TestRunHistoryArchiveIngestionGenesisReturnsError( // Recreate mock in this single test to remove assertions. *s.ledgerBackend = ledgerbackend.MockDatabaseBackend{} - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(0)).Return(nil).Once() - s.historyQ.On("UpdateExpStateInvalid", false).Return(nil).Once() - s.historyQ.On("TruncateIngestStateTables").Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(0)).Return(nil).Once() + s.historyQ.On("UpdateExpStateInvalid", s.ctx, false).Return(nil).Once() + s.historyQ.On("TruncateIngestStateTables", s.ctx).Return(nil).Once() s.stellarCoreClient.On( "SetCursor", mock.AnythingOfType("*context.timerCtx"), @@ -273,10 +275,10 @@ func (s *BuildStateTestSuite) TestUpdateLastLedgerIngestAfterIngestReturnsError( On("RunHistoryArchiveIngestion", s.checkpointLedger, MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}). Return(ingest.StatsChangeProcessorResults{}, nil). Once() - s.historyQ.On("UpdateIngestVersion", CurrentVersion). + s.historyQ.On("UpdateIngestVersion", s.ctx, CurrentVersion). Return(nil). Once() - s.historyQ.On("UpdateLastLedgerIngest", s.checkpointLedger). + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.checkpointLedger). Return(errors.New("my error")). Once() next, err := buildState{checkpointLedger: s.checkpointLedger}.run(s.system) @@ -292,7 +294,7 @@ func (s *BuildStateTestSuite) TestUpdateIngestVersionIngestReturnsError() { On("RunHistoryArchiveIngestion", s.checkpointLedger, MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}). Return(ingest.StatsChangeProcessorResults{}, nil). Once() - s.historyQ.On("UpdateIngestVersion", CurrentVersion). + s.historyQ.On("UpdateIngestVersion", s.ctx, CurrentVersion). Return(errors.New("my error")). Once() next, err := buildState{checkpointLedger: s.checkpointLedger}.run(s.system) @@ -308,13 +310,13 @@ func (s *BuildStateTestSuite) TestUpdateCommitReturnsError() { On("RunHistoryArchiveIngestion", s.checkpointLedger, MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}). Return(ingest.StatsChangeProcessorResults{}, nil). Once() - s.historyQ.On("UpdateLastLedgerIngest", s.checkpointLedger). + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.checkpointLedger). Return(nil). Once() - s.historyQ.On("UpdateIngestVersion", CurrentVersion). + s.historyQ.On("UpdateIngestVersion", s.ctx, CurrentVersion). Return(nil). Once() - s.historyQ.On("Commit"). + s.historyQ.On("Commit", s.ctx). Return(errors.New("my error")). Once() next, err := buildState{checkpointLedger: s.checkpointLedger}.run(s.system) @@ -330,13 +332,13 @@ func (s *BuildStateTestSuite) TestBuildStateSucceeds() { On("RunHistoryArchiveIngestion", s.checkpointLedger, MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}). Return(ingest.StatsChangeProcessorResults{}, nil). Once() - s.historyQ.On("UpdateLastLedgerIngest", s.checkpointLedger). + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.checkpointLedger). Return(nil). Once() - s.historyQ.On("UpdateIngestVersion", CurrentVersion). + s.historyQ.On("UpdateIngestVersion", s.ctx, CurrentVersion). Return(nil). Once() - s.historyQ.On("Commit"). + s.historyQ.On("Commit", s.ctx). Return(nil). Once() @@ -358,13 +360,13 @@ func (s *BuildStateTestSuite) TestUpdateCommitReturnsErrorStop() { On("RunHistoryArchiveIngestion", s.checkpointLedger, MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}). Return(ingest.StatsChangeProcessorResults{}, nil). Once() - s.historyQ.On("UpdateLastLedgerIngest", s.checkpointLedger). + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.checkpointLedger). Return(nil). Once() - s.historyQ.On("UpdateIngestVersion", CurrentVersion). + s.historyQ.On("UpdateIngestVersion", s.ctx, CurrentVersion). Return(nil). Once() - s.historyQ.On("Commit"). + s.historyQ.On("Commit", s.ctx). Return(errors.New("my error")). Once() next, err := buildState{checkpointLedger: s.checkpointLedger, stop: true}.run(s.system) @@ -380,13 +382,13 @@ func (s *BuildStateTestSuite) TestBuildStateSucceedStop() { On("RunHistoryArchiveIngestion", s.checkpointLedger, MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}). Return(ingest.StatsChangeProcessorResults{}, nil). Once() - s.historyQ.On("UpdateLastLedgerIngest", s.checkpointLedger). + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, s.checkpointLedger). Return(nil). Once() - s.historyQ.On("UpdateIngestVersion", CurrentVersion). + s.historyQ.On("UpdateIngestVersion", s.ctx, CurrentVersion). Return(nil). Once() - s.historyQ.On("Commit"). + s.historyQ.On("Commit", s.ctx). Return(nil). Once() diff --git a/services/horizon/internal/ingest/db_integration_test.go b/services/horizon/internal/ingest/db_integration_test.go index 63a870d7b3..6f20de97bf 100644 --- a/services/horizon/internal/ingest/db_integration_test.go +++ b/services/horizon/internal/ingest/db_integration_test.go @@ -3,6 +3,7 @@ package ingest import ( + "context" "io" "io/ioutil" "path/filepath" @@ -57,6 +58,7 @@ func TestDBTestSuite(t *testing.T) { type DBTestSuite struct { suite.Suite + ctx context.Context sampleFile string sequence uint32 ledgerBackend *ledgerbackend.MockDatabaseBackend @@ -87,6 +89,7 @@ func (s *DBTestSuite) SetupTest() { }) s.Assert().NoError(err) s.system = sIface.(*system) + s.ctx = s.system.ctx s.sequence = uint32(28660351) s.setupMocksForBuildState() @@ -99,7 +102,7 @@ func (s *DBTestSuite) SetupTest() { func (s *DBTestSuite) mockChangeReader() { changeReader, err := loadChanges(s.sampleFile) s.Assert().NoError(err) - s.historyAdapter.On("GetState", s.system.ctx, s.sequence). + s.historyAdapter.On("GetState", s.ctx, s.sequence). Return(ingest.ChangeReader(changeReader), nil).Once() } func (s *DBTestSuite) setupMocksForBuildState() { @@ -153,7 +156,7 @@ func (s *DBTestSuite) TestVersionMismatchTriggersRebuild() { s.TestBuildState() s.Assert().NoError( - s.system.historyQ.UpdateIngestVersion(CurrentVersion - 1), + s.system.historyQ.UpdateIngestVersion(context.Background(), CurrentVersion-1), ) s.setupMocksForBuildState() diff --git a/services/horizon/internal/ingest/fsm.go b/services/horizon/internal/ingest/fsm.go index 0a8d7651b0..88eeafa8b7 100644 --- a/services/horizon/internal/ingest/fsm.go +++ b/services/horizon/internal/ingest/fsm.go @@ -1,6 +1,7 @@ package ingest import ( + "context" "fmt" "strings" "time" @@ -111,18 +112,18 @@ func (startState) String() string { } func (state startState) run(s *system) (transition, error) { - if err := s.historyQ.Begin(); err != nil { + if err := s.historyQ.Begin(s.ctx); err != nil { return start(), errors.Wrap(err, "Error starting a transaction") } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // This will get the value `FOR UPDATE`, blocking it for other nodes. - lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest() + lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest(s.ctx) if err != nil { return start(), errors.Wrap(err, getLastIngestedErrMsg) } - ingestVersion, err := s.historyQ.GetIngestVersion() + ingestVersion, err := s.historyQ.GetIngestVersion(s.ctx) if err != nil { return start(), errors.Wrap(err, getIngestVersionErrMsg) } @@ -135,7 +136,7 @@ func (state startState) run(s *system) (transition, error) { return stop(), nil } - lastHistoryLedger, err := s.historyQ.GetLatestHistoryLedger() + lastHistoryLedger, err := s.historyQ.GetLatestHistoryLedger(s.ctx) if err != nil { return start(), errors.Wrap(err, "Error getting last history ledger sequence") } @@ -188,11 +189,11 @@ func (state startState) run(s *system) (transition, error) { // Now it's on by default but the latest history ledger is greater // than the latest ingest ledger. We reset the exp ledger sequence // so init state will rebuild the state correctly. - err = s.historyQ.UpdateLastLedgerIngest(0) + err = s.historyQ.UpdateLastLedgerIngest(s.ctx, 0) if err != nil { return start(), errors.Wrap(err, updateLastLedgerIngestErrMsg) } - err = s.historyQ.Commit() + err = s.historyQ.Commit(s.ctx) if err != nil { return start(), errors.Wrap(err, commitErrMsg) } @@ -243,7 +244,7 @@ func (b buildState) run(s *system) (transition, error) { // ProcessorRunner.RunHistoryArchiveIngestion(). var ledgerCloseMeta xdr.LedgerCloseMeta if b.checkpointLedger != 1 { - err := s.maybePrepareRange(b.checkpointLedger) + err := s.maybePrepareRange(s.ctx, b.checkpointLedger) if err != nil { return nextFailState, err } @@ -260,19 +261,19 @@ func (b buildState) run(s *system) (transition, error) { }).Info("Ledger returned from the backend") } - if err := s.historyQ.Begin(); err != nil { + if err := s.historyQ.Begin(s.ctx); err != nil { return nextFailState, errors.Wrap(err, "Error starting a transaction") } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // We need to get this value `FOR UPDATE` so all other instances // are blocked. - lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest() + lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest(s.ctx) if err != nil { return nextFailState, errors.Wrap(err, getLastIngestedErrMsg) } - ingestVersion, err := s.historyQ.GetIngestVersion() + ingestVersion, err := s.historyQ.GetIngestVersion(s.ctx) if err != nil { return nextFailState, errors.Wrap(err, getIngestVersionErrMsg) } @@ -293,20 +294,20 @@ func (b buildState) run(s *system) (transition, error) { log.Info("Starting ingestion system from empty state...") // Clear last_ingested_ledger in key value store - err = s.historyQ.UpdateLastLedgerIngest(0) + err = s.historyQ.UpdateLastLedgerIngest(s.ctx, 0) if err != nil { return nextFailState, errors.Wrap(err, updateLastLedgerIngestErrMsg) } // Clear invalid state in key value store. It's possible that upgraded // ingestion is fixing it. - err = s.historyQ.UpdateExpStateInvalid(false) + err = s.historyQ.UpdateExpStateInvalid(s.ctx, false) if err != nil { return nextFailState, errors.Wrap(err, updateExpStateInvalidErrMsg) } // State tables should be empty. - err = s.historyQ.TruncateIngestStateTables() + err = s.historyQ.TruncateIngestStateTables(s.ctx) if err != nil { return nextFailState, errors.Wrap(err, "Error clearing ingest tables") } @@ -331,11 +332,11 @@ func (b buildState) run(s *system) (transition, error) { return nextFailState, errors.Wrap(err, "Error ingesting history archive") } - if err = s.historyQ.UpdateIngestVersion(CurrentVersion); err != nil { + if err = s.historyQ.UpdateIngestVersion(s.ctx, CurrentVersion); err != nil { return nextFailState, errors.Wrap(err, "Error updating ingestion version") } - if err = s.completeIngestion(b.checkpointLedger); err != nil { + if err = s.completeIngestion(s.ctx, b.checkpointLedger); err != nil { return nextFailState, err } @@ -371,7 +372,7 @@ func (r resumeState) run(s *system) (transition, error) { ingestLedger := r.latestSuccessfullyProcessedLedger + 1 - err := s.maybePrepareRange(ingestLedger) + err := s.maybePrepareRange(s.ctx, ingestLedger) if err != nil { return start(), err } @@ -387,14 +388,14 @@ func (r resumeState) run(s *system) (transition, error) { "duration": time.Since(startTime).Seconds(), }).Info("Ledger returned from the backend") - if err = s.historyQ.Begin(); err != nil { + if err = s.historyQ.Begin(s.ctx); err != nil { return retryResume(r), errors.Wrap(err, "Error starting a transaction") } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // This will get the value `FOR UPDATE`, blocking it for other nodes. - lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest() + lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest(s.ctx) if err != nil { return retryResume(r), errors.Wrap(err, getLastIngestedErrMsg) } @@ -411,7 +412,7 @@ func (r resumeState) run(s *system) (transition, error) { }), nil } - ingestVersion, err := s.historyQ.GetIngestVersion() + ingestVersion, err := s.historyQ.GetIngestVersion(s.ctx) if err != nil { return retryResume(r), errors.Wrap(err, getIngestVersionErrMsg) } @@ -424,7 +425,7 @@ func (r resumeState) run(s *system) (transition, error) { return start(), nil } - lastHistoryLedger, err := s.historyQ.GetLatestHistoryLedger() + lastHistoryLedger, err := s.historyQ.GetLatestHistoryLedger(s.ctx) if err != nil { return retryResume(r), errors.Wrap(err, "could not get latest history ledger") } @@ -455,7 +456,7 @@ func (r resumeState) run(s *system) (transition, error) { return retryResume(r), errors.Wrap(err, "Error running processors on ledger") } - if err = s.completeIngestion(ingestLedger); err != nil { + if err = s.completeIngestion(s.ctx, ingestLedger); err != nil { return retryResume(r), err } @@ -530,22 +531,22 @@ func (h historyRangeState) run(s *system) (transition, error) { return start(), errors.Errorf("invalid range: [%d, %d]", h.fromLedger, h.toLedger) } - err := s.maybePrepareRange(h.fromLedger) + err := s.maybePrepareRange(s.ctx, h.fromLedger) if err != nil { return start(), err } - if err = s.historyQ.Begin(); err != nil { + if err = s.historyQ.Begin(s.ctx); err != nil { return start(), errors.Wrap(err, "Error starting a transaction") } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // acquire distributed lock so no one else can perform ingestion operations. - if _, err = s.historyQ.GetLastLedgerIngest(); err != nil { + if _, err = s.historyQ.GetLastLedgerIngest(s.ctx); err != nil { return start(), errors.Wrap(err, getLastIngestedErrMsg) } - lastHistoryLedger, err := s.historyQ.GetLatestHistoryLedger() + lastHistoryLedger, err := s.historyQ.GetLatestHistoryLedger(s.ctx) if err != nil { return start(), errors.Wrap(err, "could not get latest history ledger") } @@ -567,7 +568,7 @@ func (h historyRangeState) run(s *system) (transition, error) { ledgerCloseMeta, err = s.ledgerBackend.GetLedgerBlocking(cur) if err != nil { // Commit finished work in case of ledger backend error. - commitErr := s.historyQ.Commit() + commitErr := s.historyQ.Commit(s.ctx) if commitErr != nil { log.WithError(commitErr).Error("Error commiting partial range results") } else { @@ -586,7 +587,7 @@ func (h historyRangeState) run(s *system) (transition, error) { } } - if err = s.historyQ.Commit(); err != nil { + if err = s.historyQ.Commit(s.ctx); err != nil { return start(), errors.Wrap(err, commitErrMsg) } @@ -649,7 +650,7 @@ func (h reingestHistoryRangeState) ingestRange(s *system, fromLedger, toLedger u return errors.Wrap(err, "Invalid range") } - err = s.historyQ.DeleteRangeAll(start, end) + err = s.historyQ.DeleteRangeAll(s.ctx, start, end) if err != nil { return errors.Wrap(err, "error in DeleteRangeAll") } @@ -704,13 +705,13 @@ func (h reingestHistoryRangeState) run(s *system) (transition, error) { startTime = time.Now() if h.force { - if err := s.historyQ.Begin(); err != nil { + if err := s.historyQ.Begin(s.ctx); err != nil { return stop(), errors.Wrap(err, "Error starting a transaction") } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // acquire distributed lock so no one else can perform ingestion operations. - if _, err := s.historyQ.GetLastLedgerIngest(); err != nil { + if _, err := s.historyQ.GetLastLedgerIngest(s.ctx); err != nil { return stop(), errors.Wrap(err, getLastIngestedErrMsg) } @@ -718,11 +719,11 @@ func (h reingestHistoryRangeState) run(s *system) (transition, error) { return stop(), err } - if err := s.historyQ.Commit(); err != nil { + if err := s.historyQ.Commit(s.ctx); err != nil { return stop(), errors.Wrap(err, commitErrMsg) } } else { - lastIngestedLedger, err := s.historyQ.GetLastLedgerIngestNonBlocking() + lastIngestedLedger, err := s.historyQ.GetLastLedgerIngestNonBlocking(s.ctx) if err != nil { return stop(), errors.Wrap(err, getLastIngestedErrMsg) } @@ -733,10 +734,10 @@ func (h reingestHistoryRangeState) run(s *system) (transition, error) { for cur := h.fromLedger; cur <= h.toLedger; cur++ { err := func(ledger uint32) error { - if err := s.historyQ.Begin(); err != nil { + if err := s.historyQ.Begin(s.ctx); err != nil { return errors.Wrap(err, "Error starting a transaction") } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // ingest each ledger in a separate transaction to prevent deadlocks // when acquiring ShareLocks from multiple parallel reingest range processes @@ -744,7 +745,7 @@ func (h reingestHistoryRangeState) run(s *system) (transition, error) { return err } - if err := s.historyQ.Commit(); err != nil { + if err := s.historyQ.Commit(s.ctx); err != nil { return errors.Wrap(err, commitErrMsg) } @@ -798,14 +799,14 @@ func (v verifyRangeState) run(s *system) (transition, error) { return stop(), errors.Errorf("invalid range: [%d, %d]", v.fromLedger, v.toLedger) } - if err := s.historyQ.Begin(); err != nil { + if err := s.historyQ.Begin(s.ctx); err != nil { err = errors.Wrap(err, "Error starting a transaction") return stop(), err } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // Simple check if DB clean - lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest() + lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest(s.ctx) if err != nil { err = errors.Wrap(err, getLastIngestedErrMsg) return stop(), err @@ -851,7 +852,7 @@ func (v verifyRangeState) run(s *system) (transition, error) { return stop(), err } - if err = s.completeIngestion(v.fromLedger); err != nil { + if err = s.completeIngestion(s.ctx, v.fromLedger); err != nil { return stop(), err } @@ -872,7 +873,7 @@ func (v verifyRangeState) run(s *system) (transition, error) { }).Info("Processing ledger") startTime := time.Now() - if err = s.historyQ.Begin(); err != nil { + if err = s.historyQ.Begin(s.ctx); err != nil { err = errors.Wrap(err, "Error starting a transaction") return stop(), err } @@ -897,7 +898,7 @@ func (v verifyRangeState) run(s *system) (transition, error) { return stop(), err } - if err = s.completeIngestion(sequence); err != nil { + if err = s.completeIngestion(s.ctx, sequence); err != nil { return stop(), err } @@ -928,14 +929,14 @@ func (stressTestState) String() string { } func (stressTestState) run(s *system) (transition, error) { - if err := s.historyQ.Begin(); err != nil { + if err := s.historyQ.Begin(s.ctx); err != nil { err = errors.Wrap(err, "Error starting a transaction") return stop(), err } - defer s.historyQ.Rollback() + defer s.historyQ.Rollback(s.ctx) // Simple check if DB clean - lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest() + lastIngestedLedger, err := s.historyQ.GetLastLedgerIngest(s.ctx) if err != nil { err = errors.Wrap(err, getLastIngestedErrMsg) return stop(), err @@ -973,7 +974,7 @@ func (stressTestState) run(s *system) (transition, error) { return stop(), err } - if err = s.completeIngestion(sequence); err != nil { + if err = s.completeIngestion(s.ctx, sequence); err != nil { return stop(), err } @@ -995,17 +996,17 @@ func (stressTestState) run(s *system) (transition, error) { return stop(), nil } -func (s *system) completeIngestion(ledger uint32) error { +func (s *system) completeIngestion(ctx context.Context, ledger uint32) error { if ledger == 0 { return errors.New("ledger must be positive") } - if err := s.historyQ.UpdateLastLedgerIngest(ledger); err != nil { + if err := s.historyQ.UpdateLastLedgerIngest(ctx, ledger); err != nil { err = errors.Wrap(err, updateLastLedgerIngestErrMsg) return err } - if err := s.historyQ.Commit(); err != nil { + if err := s.historyQ.Commit(ctx); err != nil { return errors.Wrap(err, commitErrMsg) } @@ -1013,7 +1014,7 @@ func (s *system) completeIngestion(ledger uint32) error { } // maybePrepareRange checks if the range is prepared and, if not, prepares it. -func (s *system) maybePrepareRange(from uint32) error { +func (s *system) maybePrepareRange(ctx context.Context, from uint32) error { ledgerRange := ledgerbackend.UnboundedRange(from) prepared, err := s.ledgerBackend.IsPrepared(ledgerRange) diff --git a/services/horizon/internal/ingest/group_processors.go b/services/horizon/internal/ingest/group_processors.go index d2389676cc..b35f940a6b 100644 --- a/services/horizon/internal/ingest/group_processors.go +++ b/services/horizon/internal/ingest/group_processors.go @@ -1,6 +1,7 @@ package ingest import ( + "context" "fmt" "time" @@ -26,10 +27,10 @@ func newGroupChangeProcessors(processors []horizonChangeProcessor) *groupChangeP } } -func (g groupChangeProcessors) ProcessChange(change ingest.Change) error { +func (g groupChangeProcessors) ProcessChange(ctx context.Context, change ingest.Change) error { for _, p := range g.processors { startTime := time.Now() - if err := p.ProcessChange(change); err != nil { + if err := p.ProcessChange(ctx, change); err != nil { return errors.Wrapf(err, "error in %T.ProcessChange", p) } g.AddRunDuration(fmt.Sprintf("%T", p), startTime) @@ -37,10 +38,10 @@ func (g groupChangeProcessors) ProcessChange(change ingest.Change) error { return nil } -func (g groupChangeProcessors) Commit() error { +func (g groupChangeProcessors) Commit(ctx context.Context) error { for _, p := range g.processors { startTime := time.Now() - if err := p.Commit(); err != nil { + if err := p.Commit(ctx); err != nil { return errors.Wrapf(err, "error in %T.Commit", p) } g.AddRunDuration(fmt.Sprintf("%T", p), startTime) @@ -60,10 +61,10 @@ func newGroupTransactionProcessors(processors []horizonTransactionProcessor) *gr } } -func (g groupTransactionProcessors) ProcessTransaction(tx ingest.LedgerTransaction) error { +func (g groupTransactionProcessors) ProcessTransaction(ctx context.Context, tx ingest.LedgerTransaction) error { for _, p := range g.processors { startTime := time.Now() - if err := p.ProcessTransaction(tx); err != nil { + if err := p.ProcessTransaction(ctx, tx); err != nil { return errors.Wrapf(err, "error in %T.ProcessTransaction", p) } g.AddRunDuration(fmt.Sprintf("%T", p), startTime) @@ -71,10 +72,10 @@ func (g groupTransactionProcessors) ProcessTransaction(tx ingest.LedgerTransacti return nil } -func (g groupTransactionProcessors) Commit() error { +func (g groupTransactionProcessors) Commit(ctx context.Context) error { for _, p := range g.processors { startTime := time.Now() - if err := p.Commit(); err != nil { + if err := p.Commit(ctx); err != nil { return errors.Wrapf(err, "error in %T.Commit", p) } g.AddRunDuration(fmt.Sprintf("%T", p), startTime) diff --git a/services/horizon/internal/ingest/group_processors_test.go b/services/horizon/internal/ingest/group_processors_test.go index eaa357fa80..6848c24a66 100644 --- a/services/horizon/internal/ingest/group_processors_test.go +++ b/services/horizon/internal/ingest/group_processors_test.go @@ -3,6 +3,7 @@ package ingest import ( + "context" "errors" "testing" @@ -18,13 +19,13 @@ type mockHorizonChangeProcessor struct { mock.Mock } -func (m *mockHorizonChangeProcessor) ProcessChange(change ingest.Change) error { - args := m.Called(change) +func (m *mockHorizonChangeProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { + args := m.Called(ctx, change) return args.Error(0) } -func (m *mockHorizonChangeProcessor) Commit() error { - args := m.Called() +func (m *mockHorizonChangeProcessor) Commit(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } @@ -34,18 +35,19 @@ type mockHorizonTransactionProcessor struct { mock.Mock } -func (m *mockHorizonTransactionProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) error { - args := m.Called(transaction) +func (m *mockHorizonTransactionProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) error { + args := m.Called(ctx, transaction) return args.Error(0) } -func (m *mockHorizonTransactionProcessor) Commit() error { - args := m.Called() +func (m *mockHorizonTransactionProcessor) Commit(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } type GroupChangeProcessorsTestSuiteLedger struct { suite.Suite + ctx context.Context processors *groupChangeProcessors processorA *mockHorizonChangeProcessor processorB *mockHorizonChangeProcessor @@ -56,6 +58,7 @@ func TestGroupChangeProcessorsTestSuiteLedger(t *testing.T) { } func (s *GroupChangeProcessorsTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.processorA = &mockHorizonChangeProcessor{} s.processorB = &mockHorizonChangeProcessor{} s.processors = newGroupChangeProcessors([]horizonChangeProcessor{ @@ -72,10 +75,10 @@ func (s *GroupChangeProcessorsTestSuiteLedger) TearDownTest() { func (s *GroupChangeProcessorsTestSuiteLedger) TestProcessChangeFails() { change := ingest.Change{} s.processorA. - On("ProcessChange", change). + On("ProcessChange", s.ctx, change). Return(errors.New("transient error")).Once() - err := s.processors.ProcessChange(change) + err := s.processors.ProcessChange(s.ctx, change) s.Assert().Error(err) s.Assert().EqualError(err, "error in *ingest.mockHorizonChangeProcessor.ProcessChange: transient error") } @@ -83,40 +86,41 @@ func (s *GroupChangeProcessorsTestSuiteLedger) TestProcessChangeFails() { func (s *GroupChangeProcessorsTestSuiteLedger) TestProcessChangeSucceeds() { change := ingest.Change{} s.processorA. - On("ProcessChange", change). + On("ProcessChange", s.ctx, change). Return(nil).Once() s.processorB. - On("ProcessChange", change). + On("ProcessChange", s.ctx, change). Return(nil).Once() - err := s.processors.ProcessChange(change) + err := s.processors.ProcessChange(s.ctx, change) s.Assert().NoError(err) } func (s *GroupChangeProcessorsTestSuiteLedger) TestCommitFails() { s.processorA. - On("Commit"). + On("Commit", s.ctx). Return(errors.New("transient error")).Once() - err := s.processors.Commit() + err := s.processors.Commit(s.ctx) s.Assert().Error(err) s.Assert().EqualError(err, "error in *ingest.mockHorizonChangeProcessor.Commit: transient error") } func (s *GroupChangeProcessorsTestSuiteLedger) TestCommitSucceeds() { s.processorA. - On("Commit"). + On("Commit", s.ctx). Return(nil).Once() s.processorB. - On("Commit"). + On("Commit", s.ctx). Return(nil).Once() - err := s.processors.Commit() + err := s.processors.Commit(s.ctx) s.Assert().NoError(err) } type GroupTransactionProcessorsTestSuiteLedger struct { suite.Suite + ctx context.Context processors *groupTransactionProcessors processorA *mockHorizonTransactionProcessor processorB *mockHorizonTransactionProcessor @@ -127,6 +131,7 @@ func TestGroupTransactionProcessorsTestSuiteLedger(t *testing.T) { } func (s *GroupTransactionProcessorsTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.processorA = &mockHorizonTransactionProcessor{} s.processorB = &mockHorizonTransactionProcessor{} s.processors = newGroupTransactionProcessors([]horizonTransactionProcessor{ @@ -143,10 +148,10 @@ func (s *GroupTransactionProcessorsTestSuiteLedger) TearDownTest() { func (s *GroupTransactionProcessorsTestSuiteLedger) TestProcessTransactionFails() { transaction := ingest.LedgerTransaction{} s.processorA. - On("ProcessTransaction", transaction). + On("ProcessTransaction", s.ctx, transaction). Return(errors.New("transient error")).Once() - err := s.processors.ProcessTransaction(transaction) + err := s.processors.ProcessTransaction(s.ctx, transaction) s.Assert().Error(err) s.Assert().EqualError(err, "error in *ingest.mockHorizonTransactionProcessor.ProcessTransaction: transient error") } @@ -154,34 +159,34 @@ func (s *GroupTransactionProcessorsTestSuiteLedger) TestProcessTransactionFails( func (s *GroupTransactionProcessorsTestSuiteLedger) TestProcessTransactionSucceeds() { transaction := ingest.LedgerTransaction{} s.processorA. - On("ProcessTransaction", transaction). + On("ProcessTransaction", s.ctx, transaction). Return(nil).Once() s.processorB. - On("ProcessTransaction", transaction). + On("ProcessTransaction", s.ctx, transaction). Return(nil).Once() - err := s.processors.ProcessTransaction(transaction) + err := s.processors.ProcessTransaction(s.ctx, transaction) s.Assert().NoError(err) } func (s *GroupTransactionProcessorsTestSuiteLedger) TestCommitFails() { s.processorA. - On("Commit"). + On("Commit", s.ctx). Return(errors.New("transient error")).Once() - err := s.processors.Commit() + err := s.processors.Commit(s.ctx) s.Assert().Error(err) s.Assert().EqualError(err, "error in *ingest.mockHorizonTransactionProcessor.Commit: transient error") } func (s *GroupTransactionProcessorsTestSuiteLedger) TestCommitSucceeds() { s.processorA. - On("Commit"). + On("Commit", s.ctx). Return(nil).Once() s.processorB. - On("Commit"). + On("Commit", s.ctx). Return(nil).Once() - err := s.processors.Commit() + err := s.processors.Commit(s.ctx) s.Assert().NoError(err) } diff --git a/services/horizon/internal/ingest/ingest_history_range_state_test.go b/services/horizon/internal/ingest/ingest_history_range_state_test.go index f6a5b8181b..751e5bbfa3 100644 --- a/services/horizon/internal/ingest/ingest_history_range_state_test.go +++ b/services/horizon/internal/ingest/ingest_history_range_state_test.go @@ -22,6 +22,7 @@ func TestIngestHistoryRangeStateTestSuite(t *testing.T) { type IngestHistoryRangeStateTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ historyAdapter *mockHistoryArchiveAdapter ledgerBackend *ledgerbackend.MockDatabaseBackend @@ -30,12 +31,13 @@ type IngestHistoryRangeStateTestSuite struct { } func (s *IngestHistoryRangeStateTestSuite) SetupTest() { + s.ctx = context.Background() s.historyQ = &mockDBQ{} s.ledgerBackend = &ledgerbackend.MockDatabaseBackend{} s.historyAdapter = &mockHistoryArchiveAdapter{} s.runner = &mockProcessorsRunner{} s.system = &system{ - ctx: context.Background(), + ctx: s.ctx, historyQ: s.historyQ, historyAdapter: s.historyAdapter, ledgerBackend: s.ledgerBackend, @@ -43,7 +45,7 @@ func (s *IngestHistoryRangeStateTestSuite) SetupTest() { } s.system.initMetrics() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() s.ledgerBackend.On("IsPrepared", ledgerbackend.UnboundedRange(100)).Return(false, nil).Once() s.ledgerBackend.On("PrepareRange", ledgerbackend.UnboundedRange(100)).Return(nil).Once() @@ -101,7 +103,7 @@ func (s *IngestHistoryRangeStateTestSuite) TestBeginReturnsError() { // Recreate mock in this single test to remove Rollback assertion. *s.historyQ = mockDBQ{} - s.historyQ.On("Begin").Return(errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(errors.New("my error")).Once() next, err := historyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().Error(err) @@ -110,8 +112,8 @@ func (s *IngestHistoryRangeStateTestSuite) TestBeginReturnsError() { } func (s *IngestHistoryRangeStateTestSuite) TestGetLastLedgerIngestReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), errors.New("my error")).Once() next, err := historyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().Error(err) @@ -120,9 +122,9 @@ func (s *IngestHistoryRangeStateTestSuite) TestGetLastLedgerIngestReturnsError() } func (s *IngestHistoryRangeStateTestSuite) TestGetLatestLedgerReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(0), errors.New("my error")).Once() next, err := historyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().Error(err) @@ -133,9 +135,9 @@ func (s *IngestHistoryRangeStateTestSuite) TestGetLatestLedgerReturnsError() { // TestAnotherNodeIngested tests the case when another node has ingested the range. // In such case we go back to `init` state without processing. func (s *IngestHistoryRangeStateTestSuite) TestAnotherNodeIngested() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(200), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(200), nil).Once() next, err := historyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().NoError(err) @@ -143,9 +145,9 @@ func (s *IngestHistoryRangeStateTestSuite) TestAnotherNodeIngested() { } func (s *IngestHistoryRangeStateTestSuite) TestRunTransactionProcessorsOnLedgerReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(99), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(99), nil).Once() meta := xdr.LedgerCloseMeta{ V0: &xdr.LedgerCloseMetaV0{ @@ -171,9 +173,9 @@ func (s *IngestHistoryRangeStateTestSuite) TestRunTransactionProcessorsOnLedgerR } func (s *IngestHistoryRangeStateTestSuite) TestSuccess() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(99), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(99), nil).Once() for i := 100; i <= 200; i++ { meta := xdr.LedgerCloseMeta{ @@ -194,7 +196,7 @@ func (s *IngestHistoryRangeStateTestSuite) TestSuccess() { ).Once() } - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() next, err := historyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().NoError(err) @@ -202,9 +204,9 @@ func (s *IngestHistoryRangeStateTestSuite) TestSuccess() { } func (s *IngestHistoryRangeStateTestSuite) TestSuccessOneLedger() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(99), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(99), nil).Once() meta := xdr.LedgerCloseMeta{ V0: &xdr.LedgerCloseMetaV0{ @@ -223,7 +225,7 @@ func (s *IngestHistoryRangeStateTestSuite) TestSuccessOneLedger() { nil, ).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() next, err := historyRangeState{fromLedger: 100, toLedger: 100}.run(s.system) s.Assert().NoError(err) @@ -231,9 +233,9 @@ func (s *IngestHistoryRangeStateTestSuite) TestSuccessOneLedger() { } func (s *IngestHistoryRangeStateTestSuite) TestCommitsWorkOnLedgerBackendFailure() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(99), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(99), nil).Once() meta := xdr.LedgerCloseMeta{ V0: &xdr.LedgerCloseMetaV0{ @@ -254,7 +256,7 @@ func (s *IngestHistoryRangeStateTestSuite) TestCommitsWorkOnLedgerBackendFailure nil, ).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() next, err := historyRangeState{fromLedger: 100, toLedger: 102}.run(s.system) s.Assert().Error(err) @@ -268,6 +270,7 @@ func TestReingestHistoryRangeStateTestSuite(t *testing.T) { type ReingestHistoryRangeStateTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ historyAdapter *mockHistoryArchiveAdapter ledgerBackend *mockLedgerBackend @@ -276,12 +279,13 @@ type ReingestHistoryRangeStateTestSuite struct { } func (s *ReingestHistoryRangeStateTestSuite) SetupTest() { + s.ctx = context.Background() s.historyQ = &mockDBQ{} s.historyAdapter = &mockHistoryArchiveAdapter{} s.ledgerBackend = &mockLedgerBackend{} s.runner = &mockProcessorsRunner{} s.system = &system{ - ctx: context.Background(), + ctx: s.ctx, historyQ: s.historyQ, historyAdapter: s.historyAdapter, ledgerBackend: s.ledgerBackend, @@ -289,8 +293,8 @@ func (s *ReingestHistoryRangeStateTestSuite) SetupTest() { } s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("Rollback").Return(nil).Once() - s.historyQ.On("Begin").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() s.ledgerBackend.On("PrepareRange", ledgerbackend.BoundedRange(100, 200)).Return(nil).Once() } @@ -324,9 +328,9 @@ func (s *ReingestHistoryRangeStateTestSuite) TestBeginReturnsError() { // Recreate mock in this single test to remove Rollback assertion. *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil) - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(0), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(0), nil).Once() - s.historyQ.On("Begin").Return(errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(errors.New("my error")).Once() err := s.system.ReingestRange(100, 200, false) s.Assert().EqualError(err, "Error starting a transaction: my error") @@ -336,7 +340,7 @@ func (s *ReingestHistoryRangeStateTestSuite) TestGetLastLedgerIngestNonBlockingE *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(0), errors.New("my error")).Once() err := s.system.ReingestRange(100, 200, false) s.Assert().EqualError(err, "Error getting last ingested ledger: my error") @@ -346,7 +350,7 @@ func (s *ReingestHistoryRangeStateTestSuite) TestReingestRangeOverlaps() { *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(190), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(190), nil).Once() err := s.system.ReingestRange(100, 200, false) s.Assert().Equal(err, ErrReingestRangeConflict) @@ -356,7 +360,7 @@ func (s *ReingestHistoryRangeStateTestSuite) TestReingestRangeOverlapsAtEnd() { *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(200), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(200), nil).Once() err := s.system.ReingestRange(100, 200, false) s.Assert().Equal(err, ErrReingestRangeConflict) @@ -365,17 +369,17 @@ func (s *ReingestHistoryRangeStateTestSuite) TestReingestRangeOverlapsAtEnd() { func (s *ReingestHistoryRangeStateTestSuite) TestClearHistoryFails() { *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(0), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(0), nil).Once() - s.historyQ.On("Begin").Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() s.historyQ.On("GetTx").Return(&sqlx.Tx{}).Once() toidFrom := toid.New(100, 0, 0) toidTo := toid.New(101, 0, 0) s.historyQ.On( - "DeleteRangeAll", toidFrom.ToInt64(), toidTo.ToInt64(), + "DeleteRangeAll", s.ctx, toidFrom.ToInt64(), toidTo.ToInt64(), ).Return(errors.New("my error")).Once() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() err := s.system.ReingestRange(100, 200, false) s.Assert().EqualError(err, "error in DeleteRangeAll: my error") @@ -384,14 +388,14 @@ func (s *ReingestHistoryRangeStateTestSuite) TestClearHistoryFails() { func (s *ReingestHistoryRangeStateTestSuite) TestRunTransactionProcessorsOnLedgerReturnsError() { *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(0), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(0), nil).Once() - s.historyQ.On("Begin").Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() s.historyQ.On("GetTx").Return(&sqlx.Tx{}).Once() toidFrom := toid.New(100, 0, 0) toidTo := toid.New(101, 0, 0) s.historyQ.On( - "DeleteRangeAll", toidFrom.ToInt64(), toidTo.ToInt64(), + "DeleteRangeAll", s.ctx, toidFrom.ToInt64(), toidTo.ToInt64(), ).Return(nil).Once() meta := xdr.LedgerCloseMeta{ @@ -411,7 +415,7 @@ func (s *ReingestHistoryRangeStateTestSuite) TestRunTransactionProcessorsOnLedge processorsRunDurations{}, errors.New("my error"), ).Once() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() err := s.system.ReingestRange(100, 200, false) s.Assert().EqualError(err, "error processing ledger sequence=100: my error") @@ -420,14 +424,14 @@ func (s *ReingestHistoryRangeStateTestSuite) TestRunTransactionProcessorsOnLedge func (s *ReingestHistoryRangeStateTestSuite) TestCommitFails() { *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(0), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(0), nil).Once() - s.historyQ.On("Begin").Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() s.historyQ.On("GetTx").Return(&sqlx.Tx{}).Once() toidFrom := toid.New(100, 0, 0) toidTo := toid.New(101, 0, 0) s.historyQ.On( - "DeleteRangeAll", toidFrom.ToInt64(), toidTo.ToInt64(), + "DeleteRangeAll", s.ctx, toidFrom.ToInt64(), toidTo.ToInt64(), ).Return(nil).Once() meta := xdr.LedgerCloseMeta{ @@ -447,8 +451,8 @@ func (s *ReingestHistoryRangeStateTestSuite) TestCommitFails() { nil, ).Once() - s.historyQ.On("Commit").Return(errors.New("my error")).Once() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(errors.New("my error")).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() err := s.system.ReingestRange(100, 200, false) s.Assert().EqualError(err, "Error committing db transaction: my error") @@ -457,16 +461,16 @@ func (s *ReingestHistoryRangeStateTestSuite) TestCommitFails() { func (s *ReingestHistoryRangeStateTestSuite) TestSuccess() { *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(0), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(0), nil).Once() for i := uint32(100); i <= uint32(200); i++ { - s.historyQ.On("Begin").Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() s.historyQ.On("GetTx").Return(&sqlx.Tx{}).Once() toidFrom := toid.New(int32(i), 0, 0) toidTo := toid.New(int32(i+1), 0, 0) s.historyQ.On( - "DeleteRangeAll", toidFrom.ToInt64(), toidTo.ToInt64(), + "DeleteRangeAll", s.ctx, toidFrom.ToInt64(), toidTo.ToInt64(), ).Return(nil).Once() meta := xdr.LedgerCloseMeta{ @@ -486,8 +490,8 @@ func (s *ReingestHistoryRangeStateTestSuite) TestSuccess() { nil, ).Once() - s.historyQ.On("Commit").Return(nil).Once() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() } err := s.system.ReingestRange(100, 200, false) @@ -495,13 +499,13 @@ func (s *ReingestHistoryRangeStateTestSuite) TestSuccess() { } func (s *ReingestHistoryRangeStateTestSuite) TestSuccessOneLedger() { - s.historyQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(0), nil).Once() + s.historyQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(0), nil).Once() s.historyQ.On("GetTx").Return(&sqlx.Tx{}).Once() toidFrom := toid.New(100, 0, 0) toidTo := toid.New(101, 0, 0) s.historyQ.On( - "DeleteRangeAll", toidFrom.ToInt64(), toidTo.ToInt64(), + "DeleteRangeAll", s.ctx, toidFrom.ToInt64(), toidTo.ToInt64(), ).Return(nil).Once() meta := xdr.LedgerCloseMeta{ @@ -519,7 +523,7 @@ func (s *ReingestHistoryRangeStateTestSuite) TestSuccessOneLedger() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() // Recreate mock in this single test to remove previous assertion. *s.ledgerBackend = mockLedgerBackend{} @@ -531,21 +535,21 @@ func (s *ReingestHistoryRangeStateTestSuite) TestSuccessOneLedger() { } func (s *ReingestHistoryRangeStateTestSuite) TestGetLastLedgerIngestError() { - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), errors.New("my error")).Once() err := s.system.ReingestRange(100, 200, true) s.Assert().EqualError(err, "Error getting last ingested ledger: my error") } func (s *ReingestHistoryRangeStateTestSuite) TestReingestRangeForce() { - s.historyQ.On("GetLastLedgerIngest").Return(uint32(190), nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(190), nil).Once() s.historyQ.On("GetTx").Return(&sqlx.Tx{}).Once() toidFrom := toid.New(100, 0, 0) toidTo := toid.New(201, 0, 0) s.historyQ.On( - "DeleteRangeAll", toidFrom.ToInt64(), toidTo.ToInt64(), + "DeleteRangeAll", s.ctx, toidFrom.ToInt64(), toidTo.ToInt64(), ).Return(nil).Once() for i := 100; i <= 200; i++ { @@ -567,7 +571,7 @@ func (s *ReingestHistoryRangeStateTestSuite) TestReingestRangeForce() { ).Once() } - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() err := s.system.ReingestRange(100, 200, true) s.Assert().NoError(err) diff --git a/services/horizon/internal/ingest/init_state_test.go b/services/horizon/internal/ingest/init_state_test.go index c5858fa494..a209cab7fb 100644 --- a/services/horizon/internal/ingest/init_state_test.go +++ b/services/horizon/internal/ingest/init_state_test.go @@ -16,22 +16,24 @@ func TestInitStateTestSuite(t *testing.T) { type InitStateTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ historyAdapter *mockHistoryArchiveAdapter system *system } func (s *InitStateTestSuite) SetupTest() { + s.ctx = context.Background() s.historyQ = &mockDBQ{} s.historyAdapter = &mockHistoryArchiveAdapter{} s.system = &system{ - ctx: context.Background(), + ctx: s.ctx, historyQ: s.historyQ, historyAdapter: s.historyAdapter, } s.system.initMetrics() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() } func (s *InitStateTestSuite) TearDownTest() { @@ -43,7 +45,7 @@ func (s *InitStateTestSuite) TearDownTest() { func (s *InitStateTestSuite) TestBeginReturnsError() { // Recreate mock in this single test to remove Rollback assertion. *s.historyQ = mockDBQ{} - s.historyQ.On("Begin").Return(errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(errors.New("my error")).Once() next, err := startState{}.run(s.system) s.Assert().Error(err) @@ -52,8 +54,8 @@ func (s *InitStateTestSuite) TestBeginReturnsError() { } func (s *InitStateTestSuite) TestGetLastLedgerIngestReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), errors.New("my error")).Once() next, err := startState{}.run(s.system) s.Assert().Error(err) @@ -62,9 +64,9 @@ func (s *InitStateTestSuite) TestGetLastLedgerIngestReturnsError() { } func (s *InitStateTestSuite) TestGetIngestVersionReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, errors.New("my error")).Once() next, err := startState{}.run(s.system) s.Assert().Error(err) @@ -73,9 +75,9 @@ func (s *InitStateTestSuite) TestGetIngestVersionReturnsError() { } func (s *InitStateTestSuite) TestCurrentVersionIsOutdated() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(1), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion+1, nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(1), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion+1, nil).Once() next, err := startState{}.run(s.system) s.Assert().NoError(err) @@ -83,10 +85,10 @@ func (s *InitStateTestSuite) TestCurrentVersionIsOutdated() { } func (s *InitStateTestSuite) TestGetLatestLedgerReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(0), errors.New("my error")).Once() next, err := startState{}.run(s.system) s.Assert().Error(err) @@ -95,10 +97,10 @@ func (s *InitStateTestSuite) TestGetLatestLedgerReturnsError() { } func (s *InitStateTestSuite) TestBuildStateEmptyDatabase() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(0), nil).Once() s.historyAdapter.On("GetLatestLedgerSequence").Return(uint32(63), nil).Once() @@ -111,10 +113,10 @@ func (s *InitStateTestSuite) TestBuildStateEmptyDatabase() { } func (s *InitStateTestSuite) TestBuildStateEmptyDatabaseFromSuggestedCheckpoint() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(0), nil).Once() next, err := startState{suggestedCheckpoint: 127}.run(s.system) s.Assert().NoError(err) @@ -128,10 +130,10 @@ func (s *InitStateTestSuite) TestBuildStateEmptyDatabaseFromSuggestedCheckpoint( // * the ingest system version has been incremented or no ingest ledger, // * the old system is in front of the latest checkpoint. func (s *InitStateTestSuite) TestBuildStateWait() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(100), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(100), nil).Once() s.historyAdapter.On("GetLatestLedgerSequence").Return(uint32(63), nil).Once() @@ -147,10 +149,10 @@ func (s *InitStateTestSuite) TestBuildStateWait() { // * the ingest system version has been incremented or no ingest ledger, // * the old system is behind the latest checkpoint. func (s *InitStateTestSuite) TestBuildStateCatchup() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(100), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(100), nil).Once() s.historyAdapter.On("GetLatestLedgerSequence").Return(uint32(127), nil).Once() @@ -169,10 +171,10 @@ func (s *InitStateTestSuite) TestBuildStateCatchup() { // * the ingest system version has been incremented or no ingest ledger, // * the old system latest ledger is equal to the latest checkpoint. func (s *InitStateTestSuite) TestBuildStateOldHistory() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(127), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(127), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(127), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(127), nil).Once() s.historyAdapter.On("GetLatestLedgerSequence").Return(uint32(127), nil).Once() @@ -191,13 +193,13 @@ func (s *InitStateTestSuite) TestBuildStateOldHistory() { // * state doesn't need to be rebuilt, // * history is in front of ingest. func (s *InitStateTestSuite) TestResumeStateInFront() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(130), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(130), nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(0)).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(0)).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() next, err := startState{}.run(s.system) s.Assert().NoError(err) @@ -208,10 +210,10 @@ func (s *InitStateTestSuite) TestResumeStateInFront() { // * state doesn't need to be rebuilt, // * history is behind of ingest. func (s *InitStateTestSuite) TestResumeStateBehind() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(130), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(100), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(130), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(100), nil).Once() next, err := startState{}.run(s.system) s.Assert().NoError(err) @@ -229,10 +231,10 @@ func (s *InitStateTestSuite) TestResumeStateBehind() { // * there are no ledgers in history tables. // In such case we load offers and continue ingesting the next ledger. func (s *InitStateTestSuite) TestResumeStateBehindHistory0() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(130), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(130), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(0), nil).Once() next, err := startState{}.run(s.system) s.Assert().NoError(err) @@ -249,10 +251,10 @@ func (s *InitStateTestSuite) TestResumeStateBehindHistory0() { // * state doesn't need to be rebuilt, // * history is in sync with ingest. func (s *InitStateTestSuite) TestResumeStateSync() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(130), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(130), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(130), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(130), nil).Once() next, err := startState{}.run(s.system) s.Assert().NoError(err) diff --git a/services/horizon/internal/ingest/main.go b/services/horizon/internal/ingest/main.go index 79feb9a44e..a19890b703 100644 --- a/services/horizon/internal/ingest/main.go +++ b/services/horizon/internal/ingest/main.go @@ -218,7 +218,6 @@ func NewSystem(config Config) (System, error) { } } else { coreSession := config.CoreSession.Clone() - coreSession.Ctx = ctx ledgerBackend, err = ledgerbackend.NewDatabaseBackendFromSession(coreSession, config.NetworkPassphrase) if err != nil { cancel() @@ -227,7 +226,6 @@ func NewSystem(config Config) (System, error) { } historyQ := &history.Q{config.HistorySession.Clone()} - historyQ.Ctx = ctx historyAdapter := newHistoryArchiveAdapter(archive) @@ -279,7 +277,7 @@ func (s *system) initMetrics() { Help: "equals 1 if state invalid, 0 otherwise", }, func() float64 { - invalid, err := s.historyQ.CloneIngestionQ().GetExpStateInvalid() + invalid, err := s.historyQ.CloneIngestionQ().GetExpStateInvalid(s.ctx) if err != nil { log.WithError(err).Error("Error in initMetrics/GetExpStateInvalid") return 0 @@ -487,7 +485,7 @@ func (s *system) runStateMachine(cur stateMachineNode) error { } func (s *system) maybeVerifyState(lastIngestedLedger uint32) { - stateInvalid, err := s.historyQ.GetExpStateInvalid() + stateInvalid, err := s.historyQ.GetExpStateInvalid(s.ctx) if err != nil && !isCancelledError(err) { log.WithField("err", err).Error("Error getting state invalid value") } @@ -509,7 +507,7 @@ func (s *system) maybeVerifyState(lastIngestedLedger uint32) { errorCount := s.incrementStateVerificationErrors() switch errors.Cause(err).(type) { case ingest.StateError: - markStateInvalid(s.historyQ, err) + markStateInvalid(s.ctx, s.historyQ, err) default: logger := log.WithField("err", err).Warn if errorCount >= stateVerificationErrorThreshold { @@ -572,10 +570,10 @@ func (s *system) Shutdown() { } } -func markStateInvalid(historyQ history.IngestionQ, err error) { +func markStateInvalid(ctx context.Context, historyQ history.IngestionQ, err error) { log.WithField("err", err).Error("STATE IS INVALID!") q := historyQ.CloneIngestionQ() - if err := q.UpdateExpStateInvalid(true); err != nil { + if err := q.UpdateExpStateInvalid(ctx, true); err != nil { log.WithField("err", err).Error(updateExpStateInvalidErrMsg) } } diff --git a/services/horizon/internal/ingest/main_test.go b/services/horizon/internal/ingest/main_test.go index 92d99262d6..bddafb3239 100644 --- a/services/horizon/internal/ingest/main_test.go +++ b/services/horizon/internal/ingest/main_test.go @@ -79,14 +79,8 @@ func TestCheckVerifyStateVersion(t *testing.T) { func TestNewSystem(t *testing.T) { config := Config{ - CoreSession: &db.Session{ - DB: &sqlx.DB{}, - Ctx: context.Background(), - }, - HistorySession: &db.Session{ - DB: &sqlx.DB{}, - Ctx: context.Background(), - }, + CoreSession: &db.Session{DB: &sqlx.DB{}}, + HistorySession: &db.Session{DB: &sqlx.DB{}}, DisableStateVerification: true, HistoryArchiveURL: "https://history.stellar.org/prd/core-live/core_live_001", CheckpointFrequency: 64, @@ -125,7 +119,7 @@ func TestStateMachineTransition(t *testing.T) { } historyQ.On("GetTx").Return(nil).Once() - historyQ.On("Begin").Return(errors.New("my error")).Once() + historyQ.On("Begin", system.ctx).Return(errors.New("my error")).Once() historyQ.On("GetTx").Return(&sqlx.Tx{}).Once() assert.PanicsWithValue(t, "unexpected transaction", func() { @@ -142,7 +136,7 @@ func TestContextCancel(t *testing.T) { } historyQ.On("GetTx").Return(nil).Once() - historyQ.On("Begin").Return(errors.New("my error")).Once() + historyQ.On("Begin", system.ctx).Return(errors.New("my error")).Once() cancel() assert.NoError(t, system.runStateMachine(startState{})) @@ -183,10 +177,10 @@ func TestMaybeVerifyStateGetExpStateInvalidDBErrCancelOrContextCanceled(t *testi log = logger defer func() { log = oldLogger }() - historyQ.On("GetExpStateInvalid").Return(false, db.ErrCancelled).Once() + historyQ.On("GetExpStateInvalid", system.ctx).Return(false, db.ErrCancelled).Once() system.maybeVerifyState(0) - historyQ.On("GetExpStateInvalid").Return(false, context.Canceled).Once() + historyQ.On("GetExpStateInvalid", system.ctx).Return(false, context.Canceled).Once() system.maybeVerifyState(0) logged := done() @@ -210,15 +204,15 @@ func TestMaybeVerifyInternalDBErrCancelOrContextCanceled(t *testing.T) { log = logger defer func() { log = oldLogger }() - historyQ.On("GetExpStateInvalid").Return(false, nil).Twice() - historyQ.On("Rollback").Return(nil).Twice() + historyQ.On("GetExpStateInvalid", system.ctx, mock.Anything).Return(false, nil).Twice() + historyQ.On("Rollback", system.ctx, mock.Anything).Return(nil).Twice() historyQ.On("CloneIngestionQ").Return(historyQ).Twice() - historyQ.On("BeginTx", mock.Anything).Return(db.ErrCancelled).Once() + historyQ.On("BeginTx", system.ctx, mock.Anything).Return(db.ErrCancelled).Once() system.maybeVerifyState(63) system.wg.Wait() - historyQ.On("BeginTx", mock.Anything).Return(context.Canceled).Once() + historyQ.On("BeginTx", system.ctx, mock.Anything).Return(context.Canceled).Once() system.maybeVerifyState(63) system.wg.Wait() @@ -247,13 +241,13 @@ type mockDBQ struct { history.MockQTrustLines } -func (m *mockDBQ) Begin() error { - args := m.Called() +func (m *mockDBQ) Begin(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } -func (m *mockDBQ) BeginTx(txOpts *sql.TxOptions) error { - args := m.Called(txOpts) +func (m *mockDBQ) BeginTx(ctx context.Context, txOpts *sql.TxOptions) error { + args := m.Called(ctx, txOpts) return args.Error(0) } @@ -262,13 +256,13 @@ func (m *mockDBQ) CloneIngestionQ() history.IngestionQ { return args.Get(0).(history.IngestionQ) } -func (m *mockDBQ) Commit() error { - args := m.Called() +func (m *mockDBQ) Commit(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } -func (m *mockDBQ) Rollback() error { - args := m.Called() +func (m *mockDBQ) Rollback(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } @@ -280,63 +274,63 @@ func (m *mockDBQ) GetTx() *sqlx.Tx { return args.Get(0).(*sqlx.Tx) } -func (m *mockDBQ) GetLastLedgerIngest() (uint32, error) { - args := m.Called() +func (m *mockDBQ) GetLastLedgerIngest(ctx context.Context) (uint32, error) { + args := m.Called(ctx) return args.Get(0).(uint32), args.Error(1) } -func (m *mockDBQ) GetOfferCompactionSequence() (uint32, error) { - args := m.Called() +func (m *mockDBQ) GetOfferCompactionSequence(ctx context.Context) (uint32, error) { + args := m.Called(ctx) return args.Get(0).(uint32), args.Error(1) } -func (m *mockDBQ) GetLastLedgerIngestNonBlocking() (uint32, error) { - args := m.Called() +func (m *mockDBQ) GetLastLedgerIngestNonBlocking(ctx context.Context) (uint32, error) { + args := m.Called(ctx) return args.Get(0).(uint32), args.Error(1) } -func (m *mockDBQ) GetIngestVersion() (int, error) { - args := m.Called() +func (m *mockDBQ) GetIngestVersion(ctx context.Context) (int, error) { + args := m.Called(ctx) return args.Get(0).(int), args.Error(1) } -func (m *mockDBQ) UpdateLastLedgerIngest(sequence uint32) error { - args := m.Called(sequence) +func (m *mockDBQ) UpdateLastLedgerIngest(ctx context.Context, sequence uint32) error { + args := m.Called(ctx, sequence) return args.Error(0) } -func (m *mockDBQ) UpdateExpStateInvalid(invalid bool) error { - args := m.Called(invalid) +func (m *mockDBQ) UpdateExpStateInvalid(ctx context.Context, invalid bool) error { + args := m.Called(ctx, invalid) return args.Error(0) } -func (m *mockDBQ) UpdateIngestVersion(version int) error { - args := m.Called(version) +func (m *mockDBQ) UpdateIngestVersion(ctx context.Context, version int) error { + args := m.Called(ctx, version) return args.Error(0) } -func (m *mockDBQ) GetExpStateInvalid() (bool, error) { - args := m.Called() +func (m *mockDBQ) GetExpStateInvalid(ctx context.Context) (bool, error) { + args := m.Called(ctx) return args.Get(0).(bool), args.Error(1) } -func (m *mockDBQ) GetAllOffers() ([]history.Offer, error) { - args := m.Called() +func (m *mockDBQ) GetAllOffers(ctx context.Context) ([]history.Offer, error) { + args := m.Called(ctx) return args.Get(0).([]history.Offer), args.Error(1) } -func (m *mockDBQ) GetLatestHistoryLedger() (uint32, error) { - args := m.Called() +func (m *mockDBQ) GetLatestHistoryLedger(ctx context.Context) (uint32, error) { + args := m.Called(ctx) return args.Get(0).(uint32), args.Error(1) } -func (m *mockDBQ) TruncateIngestStateTables() error { - args := m.Called() +func (m *mockDBQ) TruncateIngestStateTables(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } -func (m *mockDBQ) DeleteRangeAll(start, end int64) error { - args := m.Called(start, end) +func (m *mockDBQ) DeleteRangeAll(ctx context.Context, start, end int64) error { + args := m.Called(ctx, start, end) return args.Error(0) } @@ -357,8 +351,8 @@ func (m *mockDBQ) NewTradeBatchInsertBuilder(maxBatchSize int) history.TradeBatc return args.Get(0).(history.TradeBatchInsertBuilder) } -func (m *mockDBQ) CreateAssets(assets []xdr.Asset, batchSize int) (map[string]history.Asset, error) { - args := m.Called(assets) +func (m *mockDBQ) CreateAssets(ctx context.Context, assets []xdr.Asset, batchSize int) (map[string]history.Asset, error) { + args := m.Called(ctx, assets) return args.Get(0).(map[string]history.Asset), args.Error(1) } diff --git a/services/horizon/internal/ingest/orderbook.go b/services/horizon/internal/ingest/orderbook.go index cf3805e699..fc057afddb 100644 --- a/services/horizon/internal/ingest/orderbook.go +++ b/services/horizon/internal/ingest/orderbook.go @@ -55,25 +55,25 @@ type ingestionStatus struct { LastOfferCompactionLedger uint32 } -func (o *OrderBookStream) getIngestionStatus() (ingestionStatus, error) { +func (o *OrderBookStream) getIngestionStatus(ctx context.Context) (ingestionStatus, error) { var status ingestionStatus var err error - status.StateInvalid, err = o.historyQ.GetExpStateInvalid() + status.StateInvalid, err = o.historyQ.GetExpStateInvalid(ctx) if err != nil { return status, errors.Wrap(err, "Error from GetExpStateInvalid") } var lastHistoryLedger uint32 - lastHistoryLedger, err = o.historyQ.GetLatestHistoryLedger() + lastHistoryLedger, err = o.historyQ.GetLatestHistoryLedger(ctx) if err != nil { return status, errors.Wrap(err, "Error from GetLatestHistoryLedger") } - status.LastIngestedLedger, err = o.historyQ.GetLastLedgerIngestNonBlocking() + status.LastIngestedLedger, err = o.historyQ.GetLastLedgerIngestNonBlocking(ctx) if err != nil { return status, errors.Wrap(err, "Error from GetLastLedgerIngestNonBlocking") } - status.LastOfferCompactionLedger, err = o.historyQ.GetOfferCompactionSequence() + status.LastOfferCompactionLedger, err = o.historyQ.GetOfferCompactionSequence(ctx) if err != nil { return status, errors.Wrap(err, "Error from GetOfferCompactionSequence") } @@ -103,7 +103,7 @@ func addOfferToGraph(graph orderbook.OBGraph, offer history.Offer) { } // update returns true if the order book graph was reset -func (o *OrderBookStream) update(status ingestionStatus) (bool, error) { +func (o *OrderBookStream) update(ctx context.Context, status ingestionStatus) (bool, error) { reset := o.lastLedger == 0 if status.StateInvalid { log.WithField("status", status).Warn("ingestion state is invalid") @@ -135,7 +135,7 @@ func (o *OrderBookStream) update(status ingestionStatus) (bool, error) { defer o.graph.Discard() - offers, err := o.historyQ.GetAllOffers() + offers, err := o.historyQ.GetAllOffers(ctx) if err != nil { return true, errors.Wrap(err, "Error from GetAllOffers") } @@ -159,7 +159,7 @@ func (o *OrderBookStream) update(status ingestionStatus) (bool, error) { defer o.graph.Discard() - offers, err := o.historyQ.GetUpdatedOffers(o.lastLedger) + offers, err := o.historyQ.GetUpdatedOffers(ctx, o.lastLedger) if err != nil { return false, errors.Wrap(err, "Error from GetUpdatedOffers") } @@ -180,9 +180,9 @@ func (o *OrderBookStream) update(status ingestionStatus) (bool, error) { return false, nil } -func (o *OrderBookStream) verifyAllOffers() { +func (o *OrderBookStream) verifyAllOffers(ctx context.Context) { offers := o.graph.Offers() - ingestionOffers, err := o.historyQ.GetAllOffers() + ingestionOffers, err := o.historyQ.GetAllOffers(ctx) if err != nil { if !isCancelledError(err) { log.WithError(err).Info("Could not verify offers because of error from GetAllOffers") @@ -231,18 +231,18 @@ func (o *OrderBookStream) verifyAllOffers() { // last time Update() was called. Those changes will then be applied to the in memory order book graph. // After calling this function, the the in memory order book graph should be consistent with the // Horizon DB (assuming no error is returned). -func (o *OrderBookStream) Update() error { - if err := o.historyQ.BeginTx(&sql.TxOptions{ReadOnly: true, Isolation: sql.LevelRepeatableRead}); err != nil { +func (o *OrderBookStream) Update(ctx context.Context) error { + if err := o.historyQ.BeginTx(ctx, &sql.TxOptions{ReadOnly: true, Isolation: sql.LevelRepeatableRead}); err != nil { return errors.Wrap(err, "Error starting repeatable read transaction") } - defer o.historyQ.Rollback() + defer o.historyQ.Rollback(ctx) - status, err := o.getIngestionStatus() + status, err := o.getIngestionStatus(ctx) if err != nil { return errors.Wrap(err, "Error obtaining ingestion status") } - if reset, err := o.update(status); err != nil { + if reset, err := o.update(ctx, status); err != nil { return errors.Wrap(err, "Error updating") } else if reset { return nil @@ -255,7 +255,7 @@ func (o *OrderBookStream) Update() error { time.Since(o.lastVerification) >= verificationFrequency+jitter if requiresVerification { - o.verifyAllOffers() + o.verifyAllOffers(ctx) } return nil } @@ -268,7 +268,7 @@ func (o *OrderBookStream) Run(ctx context.Context) { for { select { case <-ticker.C: - if err := o.Update(); err != nil && !isCancelledError(err) { + if err := o.Update(ctx); err != nil && !isCancelledError(err) { log.WithError(err).Error("could not apply updates from order book stream") } case <-ctx.Done(): diff --git a/services/horizon/internal/ingest/orderbook_test.go b/services/horizon/internal/ingest/orderbook_test.go index ddb37372db..1535e45c13 100644 --- a/services/horizon/internal/ingest/orderbook_test.go +++ b/services/horizon/internal/ingest/orderbook_test.go @@ -3,6 +3,7 @@ package ingest import ( + "context" "fmt" "testing" "time" @@ -14,6 +15,7 @@ import ( type IngestionStatusTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ stream *OrderBookStream } @@ -23,6 +25,7 @@ func TestIngestionStatus(t *testing.T) { } func (t *IngestionStatusTestSuite) SetupTest() { + t.ctx = context.Background() t.historyQ = &mockDBQ{} t.stream = NewOrderBookStream(t.historyQ, &mockOrderBookGraph{}) } @@ -32,81 +35,81 @@ func (t *IngestionStatusTestSuite) TearDownTest() { } func (t *IngestionStatusTestSuite) TestGetExpStateInvalidError() { - t.historyQ.On("GetExpStateInvalid"). + t.historyQ.On("GetExpStateInvalid", t.ctx). Return(false, fmt.Errorf("state invalid error")). Once() - _, err := t.stream.getIngestionStatus() + _, err := t.stream.getIngestionStatus(t.ctx) t.Assert().EqualError(err, "Error from GetExpStateInvalid: state invalid error") } func (t *IngestionStatusTestSuite) TestGetLatestLedgerError() { - t.historyQ.On("GetExpStateInvalid"). + t.historyQ.On("GetExpStateInvalid", t.ctx). Return(false, nil). Once() - t.historyQ.On("GetLatestHistoryLedger"). + t.historyQ.On("GetLatestHistoryLedger", t.ctx). Return(uint32(0), fmt.Errorf("latest ledger error")). Once() - _, err := t.stream.getIngestionStatus() + _, err := t.stream.getIngestionStatus(t.ctx) t.Assert().EqualError(err, "Error from GetLatestHistoryLedger: latest ledger error") } func (t *IngestionStatusTestSuite) TestGetLastLedgerIngestNonBlockingError() { - t.historyQ.On("GetExpStateInvalid"). + t.historyQ.On("GetExpStateInvalid", t.ctx). Return(false, nil). Once() - t.historyQ.On("GetLatestHistoryLedger"). + t.historyQ.On("GetLatestHistoryLedger", t.ctx). Return(uint32(200), nil). Once() - t.historyQ.On("GetLastLedgerIngestNonBlocking"). + t.historyQ.On("GetLastLedgerIngestNonBlocking", t.ctx). Return(uint32(0), fmt.Errorf("ingest error")). Once() - _, err := t.stream.getIngestionStatus() + _, err := t.stream.getIngestionStatus(t.ctx) t.Assert().EqualError(err, "Error from GetLastLedgerIngestNonBlocking: ingest error") } func (t *IngestionStatusTestSuite) TestGetOfferCompactionSequenceError() { - t.historyQ.On("GetExpStateInvalid"). + t.historyQ.On("GetExpStateInvalid", t.ctx). Return(false, nil). Once() - t.historyQ.On("GetLatestHistoryLedger"). + t.historyQ.On("GetLatestHistoryLedger", t.ctx). Return(uint32(200), nil). Once() - t.historyQ.On("GetLastLedgerIngestNonBlocking"). + t.historyQ.On("GetLastLedgerIngestNonBlocking", t.ctx). Return(uint32(200), nil). Once() - t.historyQ.On("GetOfferCompactionSequence"). + t.historyQ.On("GetOfferCompactionSequence", t.ctx). Return(uint32(0), fmt.Errorf("compaction error")). Once() - _, err := t.stream.getIngestionStatus() + _, err := t.stream.getIngestionStatus(t.ctx) t.Assert().EqualError(err, "Error from GetOfferCompactionSequence: compaction error") } func (t *IngestionStatusTestSuite) TestStateInvalid() { - t.historyQ.On("GetExpStateInvalid"). + t.historyQ.On("GetExpStateInvalid", t.ctx). Return(true, nil). Once() - t.historyQ.On("GetLatestHistoryLedger"). + t.historyQ.On("GetLatestHistoryLedger", t.ctx). Return(uint32(200), nil). Once() - t.historyQ.On("GetLastLedgerIngestNonBlocking"). + t.historyQ.On("GetLastLedgerIngestNonBlocking", t.ctx). Return(uint32(200), nil). Once() - t.historyQ.On("GetOfferCompactionSequence"). + t.historyQ.On("GetOfferCompactionSequence", t.ctx). Return(uint32(100), nil). Once() - status, err := t.stream.getIngestionStatus() + status, err := t.stream.getIngestionStatus(t.ctx) t.Assert().NoError(err) t.Assert().Equal(ingestionStatus{ HistoryConsistentWithState: true, @@ -117,23 +120,23 @@ func (t *IngestionStatusTestSuite) TestStateInvalid() { } func (t *IngestionStatusTestSuite) TestHistoryInconsistentWithState() { - t.historyQ.On("GetExpStateInvalid"). + t.historyQ.On("GetExpStateInvalid", t.ctx). Return(true, nil). Once() - t.historyQ.On("GetLatestHistoryLedger"). + t.historyQ.On("GetLatestHistoryLedger", t.ctx). Return(uint32(200), nil). Once() - t.historyQ.On("GetLastLedgerIngestNonBlocking"). + t.historyQ.On("GetLastLedgerIngestNonBlocking", t.ctx). Return(uint32(201), nil). Once() - t.historyQ.On("GetOfferCompactionSequence"). + t.historyQ.On("GetOfferCompactionSequence", t.ctx). Return(uint32(100), nil). Once() - status, err := t.stream.getIngestionStatus() + status, err := t.stream.getIngestionStatus(t.ctx) t.Assert().NoError(err) t.Assert().Equal(ingestionStatus{ HistoryConsistentWithState: false, @@ -144,23 +147,23 @@ func (t *IngestionStatusTestSuite) TestHistoryInconsistentWithState() { } func (t *IngestionStatusTestSuite) TestHistoryLatestLedgerZero() { - t.historyQ.On("GetExpStateInvalid"). + t.historyQ.On("GetExpStateInvalid", t.ctx). Return(false, nil). Once() - t.historyQ.On("GetLatestHistoryLedger"). + t.historyQ.On("GetLatestHistoryLedger", t.ctx). Return(uint32(0), nil). Once() - t.historyQ.On("GetLastLedgerIngestNonBlocking"). + t.historyQ.On("GetLastLedgerIngestNonBlocking", t.ctx). Return(uint32(201), nil). Once() - t.historyQ.On("GetOfferCompactionSequence"). + t.historyQ.On("GetOfferCompactionSequence", t.ctx). Return(uint32(100), nil). Once() - status, err := t.stream.getIngestionStatus() + status, err := t.stream.getIngestionStatus(t.ctx) t.Assert().NoError(err) t.Assert().Equal(ingestionStatus{ HistoryConsistentWithState: true, @@ -172,6 +175,7 @@ func (t *IngestionStatusTestSuite) TestHistoryLatestLedgerZero() { type UpdateOrderBookStreamTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ graph *mockOrderBookGraph stream *OrderBookStream @@ -182,6 +186,7 @@ func TestUpdateOrderBookStream(t *testing.T) { } func (t *UpdateOrderBookStreamTestSuite) SetupTest() { + t.ctx = context.Background() t.historyQ = &mockDBQ{} t.graph = &mockOrderBookGraph{} t.stream = NewOrderBookStream(t.historyQ, t.graph) @@ -201,12 +206,12 @@ func (t *UpdateOrderBookStreamTestSuite) TestGetAllOffersError() { } t.graph.On("Clear").Return().Once() t.graph.On("Discard").Return().Once() - t.historyQ.On("GetAllOffers"). + t.historyQ.On("GetAllOffers", t.ctx). Return([]history.Offer{}, fmt.Errorf("offers error")). Once() t.stream.lastLedger = 300 - _, err := t.stream.update(status) + _, err := t.stream.update(t.ctx, status) t.Assert().EqualError(err, "Error from GetAllOffers: offers error") t.Assert().Equal(uint32(0), t.stream.lastLedger) } @@ -232,7 +237,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestResetApplyError() { SellerId: xdr.MustAddress(sellerID), OfferId: 20, } - t.historyQ.On("GetAllOffers"). + t.historyQ.On("GetAllOffers", t.ctx). Return([]history.Offer{offer, otherOffer}, nil). Once() @@ -244,7 +249,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestResetApplyError() { Once() t.stream.lastLedger = 300 - _, err := t.stream.update(status) + _, err := t.stream.update(t.ctx, status) t.Assert().EqualError(err, "Error applying changes to order book: apply error") t.Assert().Equal(uint32(0), t.stream.lastLedger) } @@ -265,7 +270,7 @@ func (t *UpdateOrderBookStreamTestSuite) mockReset(status ingestionStatus) { OfferId: 20, } offers := []history.Offer{offer, otherOffer} - t.historyQ.On("GetAllOffers"). + t.historyQ.On("GetAllOffers", t.ctx). Return(offers, nil). Once() @@ -286,7 +291,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestFirstUpdateSucceeds() { } t.mockReset(status) - reset, err := t.stream.update(status) + reset, err := t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(201), t.stream.lastLedger) t.Assert().True(reset) @@ -301,7 +306,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestInvalidState() { } t.graph.On("Clear").Return().Once() - reset, err := t.stream.update(status) + reset, err := t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(0), t.stream.lastLedger) t.Assert().True(reset) @@ -310,7 +315,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestInvalidState() { t.graph.On("Clear").Return().Once() - reset, err = t.stream.update(status) + reset, err = t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(0), t.stream.lastLedger) t.Assert().True(reset) @@ -325,7 +330,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestHistoryInconsistentWithState() { } t.graph.On("Clear").Return().Once() - reset, err := t.stream.update(status) + reset, err := t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(0), t.stream.lastLedger) t.Assert().True(reset) @@ -334,7 +339,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestHistoryInconsistentWithState() { t.graph.On("Clear").Return().Once() - reset, err = t.stream.update(status) + reset, err = t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(0), t.stream.lastLedger) t.Assert().True(reset) @@ -350,7 +355,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestLastIngestedLedgerBehindStream() { t.mockReset(status) t.stream.lastLedger = 300 - reset, err := t.stream.update(status) + reset, err := t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(201), t.stream.lastLedger) t.Assert().True(reset) @@ -366,7 +371,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestStreamBehindLastCompactionLedger() t.mockReset(status) t.stream.lastLedger = 99 - reset, err := t.stream.update(status) + reset, err := t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(201), t.stream.lastLedger) t.Assert().True(reset) @@ -381,7 +386,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestStreamLedgerEqualsLastIngestedLedge } t.stream.lastLedger = 201 - reset, err := t.stream.update(status) + reset, err := t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(uint32(201), t.stream.lastLedger) t.Assert().False(reset) @@ -397,11 +402,11 @@ func (t *UpdateOrderBookStreamTestSuite) TestGetUpdatedOffersError() { t.graph.On("Discard").Return().Once() t.stream.lastLedger = 100 - t.historyQ.MockQOffers.On("GetUpdatedOffers", uint32(100)). + t.historyQ.MockQOffers.On("GetUpdatedOffers", t.ctx, uint32(100)). Return([]history.Offer{}, fmt.Errorf("updated offers error")). Once() - _, err := t.stream.update(status) + _, err := t.stream.update(t.ctx, status) t.Assert().EqualError(err, "Error from GetUpdatedOffers: updated offers error") t.Assert().Equal(uint32(100), t.stream.lastLedger) } @@ -423,7 +428,7 @@ func (t *UpdateOrderBookStreamTestSuite) mockUpdate() { } deletedOffer := history.Offer{OfferID: 30, SellerID: sellerID, LastModifiedLedger: 103, Deleted: true} offers := []history.Offer{offer, otherOffer, deletedOffer} - t.historyQ.MockQOffers.On("GetUpdatedOffers", t.stream.lastLedger). + t.historyQ.MockQOffers.On("GetUpdatedOffers", t.ctx, t.stream.lastLedger). Return(offers, nil). Once() @@ -446,7 +451,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestApplyUpdatesError() { Return(fmt.Errorf("apply error")). Once() - _, err := t.stream.update(status) + _, err := t.stream.update(t.ctx, status) t.Assert().EqualError(err, "Error applying changes to order book: apply error") t.Assert().Equal(uint32(100), t.stream.lastLedger) } @@ -465,7 +470,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestApplyUpdatesSucceeds() { Return(nil). Once() - reset, err := t.stream.update(status) + reset, err := t.stream.update(t.ctx, status) t.Assert().NoError(err) t.Assert().Equal(status.LastIngestedLedger, t.stream.lastLedger) t.Assert().False(reset) @@ -473,6 +478,7 @@ func (t *UpdateOrderBookStreamTestSuite) TestApplyUpdatesSucceeds() { type VerifyOrderBookStreamTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ graph *mockOrderBookGraph stream *OrderBookStream @@ -484,6 +490,7 @@ func TestVerifyOrderBookStream(t *testing.T) { } func (t *VerifyOrderBookStreamTestSuite) SetupTest() { + t.ctx = context.Background() t.historyQ = &mockDBQ{} t.graph = &mockOrderBookGraph{} t.stream = NewOrderBookStream(t.historyQ, t.graph) @@ -527,22 +534,22 @@ func (t *VerifyOrderBookStreamTestSuite) TearDownTest() { } func (t *VerifyOrderBookStreamTestSuite) TestGetAllOffersError() { - t.historyQ.On("GetAllOffers"). + t.historyQ.On("GetAllOffers", t.ctx). Return([]history.Offer{}, fmt.Errorf("offers error")). Once() t.stream.lastLedger = 300 - t.stream.verifyAllOffers() + t.stream.verifyAllOffers(t.ctx) t.Assert().Equal(uint32(300), t.stream.lastLedger) t.Assert().True(t.stream.lastVerification.Equal(t.initialTime)) } func (t *VerifyOrderBookStreamTestSuite) TestEmptyDBOffers() { var offers []history.Offer - t.historyQ.On("GetAllOffers").Return(offers, nil).Once() + t.historyQ.On("GetAllOffers", t.ctx).Return(offers, nil).Once() t.stream.lastLedger = 300 - t.stream.verifyAllOffers() + t.stream.verifyAllOffers(t.ctx) t.Assert().Equal(uint32(0), t.stream.lastLedger) t.Assert().False(t.stream.lastVerification.Equal(t.initialTime)) } @@ -563,10 +570,10 @@ func (t *VerifyOrderBookStreamTestSuite) TestLengthMismatch() { LastModifiedLedger: 1, }, } - t.historyQ.On("GetAllOffers").Return(offers, nil).Once() + t.historyQ.On("GetAllOffers", t.ctx).Return(offers, nil).Once() t.stream.lastLedger = 300 - t.stream.verifyAllOffers() + t.stream.verifyAllOffers(t.ctx) t.Assert().Equal(uint32(0), t.stream.lastLedger) t.Assert().False(t.stream.lastVerification.Equal(t.initialTime)) } @@ -600,10 +607,10 @@ func (t *VerifyOrderBookStreamTestSuite) TestContentMismatch() { LastModifiedLedger: 1, }, } - t.historyQ.On("GetAllOffers").Return(offers, nil).Once() + t.historyQ.On("GetAllOffers", t.ctx).Return(offers, nil).Once() t.stream.lastLedger = 300 - t.stream.verifyAllOffers() + t.stream.verifyAllOffers(t.ctx) t.Assert().Equal(uint32(0), t.stream.lastLedger) t.Assert().False(t.stream.lastVerification.Equal(t.initialTime)) } @@ -637,10 +644,10 @@ func (t *VerifyOrderBookStreamTestSuite) TestSuccess() { LastModifiedLedger: 1, }, } - t.historyQ.On("GetAllOffers").Return(offers, nil).Once() + t.historyQ.On("GetAllOffers", t.ctx).Return(offers, nil).Once() t.stream.lastLedger = 300 - t.stream.verifyAllOffers() + t.stream.verifyAllOffers(t.ctx) t.Assert().Equal(uint32(300), t.stream.lastLedger) t.Assert().False(t.stream.lastVerification.Equal(t.initialTime)) } diff --git a/services/horizon/internal/ingest/processor_runner.go b/services/horizon/internal/ingest/processor_runner.go index a791304c4c..87c1156a55 100644 --- a/services/horizon/internal/ingest/processor_runner.go +++ b/services/horizon/internal/ingest/processor_runner.go @@ -23,19 +23,19 @@ const ( type horizonChangeProcessor interface { processors.ChangeProcessor - Commit() error + Commit(context.Context) error } type horizonTransactionProcessor interface { processors.LedgerTransactionProcessor - Commit() error + Commit(context.Context) error } type statsChangeProcessor struct { *ingest.StatsChangeProcessor } -func (statsChangeProcessor) Commit() error { +func (statsChangeProcessor) Commit(ctx context.Context) error { return nil } @@ -43,7 +43,7 @@ type statsLedgerTransactionProcessor struct { *processors.StatsLedgerTransactionProcessor } -func (statsLedgerTransactionProcessor) Commit() error { +func (statsLedgerTransactionProcessor) Commit(ctx context.Context) error { return nil } @@ -189,7 +189,7 @@ func (s *ProcessorRunner) RunHistoryArchiveIngestion( changeProcessor := s.buildChangeProcessor(&changeStats, historyArchiveSource, checkpointLedger) if checkpointLedger == 1 { - if err := changeProcessor.ProcessChange(ingest.GenesisChange(s.config.NetworkPassphrase)); err != nil { + if err := changeProcessor.ProcessChange(s.ctx, ingest.GenesisChange(s.config.NetworkPassphrase)); err != nil { return changeStats.GetResults(), errors.Wrap(err, "Error ingesting genesis ledger") } } else { @@ -211,7 +211,7 @@ func (s *ProcessorRunner) RunHistoryArchiveIngestion( log.WithField("ledger", checkpointLedger). Info("Processing entries from History Archive Snapshot") - err = processors.StreamChanges(changeProcessor, newloggingChangeReader( + err = processors.StreamChanges(s.ctx, changeProcessor, newloggingChangeReader( changeReader, "historyArchive", checkpointLedger, @@ -223,7 +223,7 @@ func (s *ProcessorRunner) RunHistoryArchiveIngestion( } } - if err := changeProcessor.Commit(); err != nil { + if err := changeProcessor.Commit(s.ctx); err != nil { return changeStats.GetResults(), errors.Wrap(err, "Error commiting changes from processor") } @@ -246,11 +246,11 @@ func (s *ProcessorRunner) runChangeProcessorOnLedger( logFrequency, s.logMemoryStats, ) - if err = processors.StreamChanges(changeProcessor, changeReader); err != nil { + if err = processors.StreamChanges(s.ctx, changeProcessor, changeReader); err != nil { return errors.Wrap(err, "Error streaming changes from ledger") } - err = changeProcessor.Commit() + err = changeProcessor.Commit(s.ctx) if err != nil { return errors.Wrap(err, "Error commiting changes from processor") } @@ -280,13 +280,13 @@ func (s *ProcessorRunner) RunTransactionProcessorsOnLedger(ledger xdr.LedgerClos } groupTransactionProcessors := s.buildTransactionProcessor(&ledgerTransactionStats, transactionReader.GetHeader()) - err = processors.StreamLedgerTransactions(groupTransactionProcessors, transactionReader) + err = processors.StreamLedgerTransactions(s.ctx, groupTransactionProcessors, transactionReader) if err != nil { err = errors.Wrap(err, "Error streaming changes from ledger") return } - err = groupTransactionProcessors.Commit() + err = groupTransactionProcessors.Commit(s.ctx) if err != nil { err = errors.Wrap(err, "Error commiting changes from processor") return diff --git a/services/horizon/internal/ingest/processor_runner_test.go b/services/horizon/internal/ingest/processor_runner_test.go index 32751acd65..48ee414237 100644 --- a/services/horizon/internal/ingest/processor_runner_test.go +++ b/services/horizon/internal/ingest/processor_runner_test.go @@ -18,6 +18,7 @@ import ( ) func TestProcessorRunnerRunHistoryArchiveIngestionGenesis(t *testing.T) { + ctx := context.Background() maxBatchSize := 100000 q := &mockDBQ{} @@ -25,23 +26,23 @@ func TestProcessorRunnerRunHistoryArchiveIngestionGenesis(t *testing.T) { // Batches mockOffersBatchInsertBuilder := &history.MockOffersBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockOffersBatchInsertBuilder) - mockOffersBatchInsertBuilder.On("Exec").Return(nil).Once() + mockOffersBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQOffers.On("NewOffersBatchInsertBuilder", maxBatchSize). Return(mockOffersBatchInsertBuilder).Once() mockAccountDataBatchInsertBuilder := &history.MockAccountDataBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockAccountDataBatchInsertBuilder) - mockAccountDataBatchInsertBuilder.On("Exec").Return(nil).Once() + mockAccountDataBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQData.On("NewAccountDataBatchInsertBuilder", maxBatchSize). Return(mockAccountDataBatchInsertBuilder).Once() mockClaimableBalancesBatchInsertBuilder := &history.MockClaimableBalancesBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockClaimableBalancesBatchInsertBuilder) - mockClaimableBalancesBatchInsertBuilder.On("Exec").Return(nil).Once() + mockClaimableBalancesBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQClaimableBalances.On("NewClaimableBalancesBatchInsertBuilder", maxBatchSize). Return(mockClaimableBalancesBatchInsertBuilder).Once() - q.MockQAccounts.On("UpsertAccounts", []xdr.LedgerEntry{ + q.MockQAccounts.On("UpsertAccounts", ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: 1, Data: xdr.LedgerEntryData{ @@ -58,20 +59,21 @@ func TestProcessorRunnerRunHistoryArchiveIngestionGenesis(t *testing.T) { mockAccountSignersBatchInsertBuilder := &history.MockAccountSignersBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockAccountSignersBatchInsertBuilder) - mockAccountSignersBatchInsertBuilder.On("Add", history.AccountSigner{ + mockAccountSignersBatchInsertBuilder.On("Add", ctx, history.AccountSigner{ Account: "GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN7", Signer: "GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN7", Weight: 1, Sponsor: null.String{}, }).Return(nil).Once() - mockAccountSignersBatchInsertBuilder.On("Exec").Return(nil).Once() + mockAccountSignersBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQSigners.On("NewAccountSignersBatchInsertBuilder", maxBatchSize). Return(mockAccountSignersBatchInsertBuilder).Once() - q.MockQAssetStats.On("InsertAssetStats", []history.ExpAssetStat{}, 100000). + q.MockQAssetStats.On("InsertAssetStats", ctx, []history.ExpAssetStat{}, 100000). Return(nil) runner := ProcessorRunner{ + ctx: ctx, config: Config{ NetworkPassphrase: network.PublicNetworkPassphrase, }, @@ -83,6 +85,7 @@ func TestProcessorRunnerRunHistoryArchiveIngestionGenesis(t *testing.T) { } func TestProcessorRunnerRunHistoryArchiveIngestionHistoryArchive(t *testing.T) { + ctx := context.Background() maxBatchSize := 100000 config := Config{ @@ -103,11 +106,7 @@ func TestProcessorRunnerRunHistoryArchiveIngestionHistoryArchive(t *testing.T) { m.On("Close").Return(nil).Once() historyAdapter. - On( - "GetState", - mock.AnythingOfType("*context.emptyCtx"), - uint32(63), - ). + On("GetState", ctx, uint32(63)). Return( m, nil, @@ -116,23 +115,23 @@ func TestProcessorRunnerRunHistoryArchiveIngestionHistoryArchive(t *testing.T) { // Batches mockOffersBatchInsertBuilder := &history.MockOffersBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockOffersBatchInsertBuilder) - mockOffersBatchInsertBuilder.On("Exec").Return(nil).Once() + mockOffersBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQOffers.On("NewOffersBatchInsertBuilder", maxBatchSize). Return(mockOffersBatchInsertBuilder).Once() mockAccountDataBatchInsertBuilder := &history.MockAccountDataBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockAccountDataBatchInsertBuilder) - mockAccountDataBatchInsertBuilder.On("Exec").Return(nil).Once() + mockAccountDataBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQData.On("NewAccountDataBatchInsertBuilder", maxBatchSize). Return(mockAccountDataBatchInsertBuilder).Once() mockClaimableBalancesBatchInsertBuilder := &history.MockClaimableBalancesBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockClaimableBalancesBatchInsertBuilder) - mockClaimableBalancesBatchInsertBuilder.On("Exec").Return(nil).Once() + mockClaimableBalancesBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQClaimableBalances.On("NewClaimableBalancesBatchInsertBuilder", maxBatchSize). Return(mockClaimableBalancesBatchInsertBuilder).Once() - q.MockQAccounts.On("UpsertAccounts", []xdr.LedgerEntry{ + q.MockQAccounts.On("UpsertAccounts", ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: 1, Data: xdr.LedgerEntryData{ @@ -149,20 +148,20 @@ func TestProcessorRunnerRunHistoryArchiveIngestionHistoryArchive(t *testing.T) { mockAccountSignersBatchInsertBuilder := &history.MockAccountSignersBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockAccountSignersBatchInsertBuilder) - mockAccountSignersBatchInsertBuilder.On("Add", history.AccountSigner{ + mockAccountSignersBatchInsertBuilder.On("Add", ctx, history.AccountSigner{ Account: "GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN7", Signer: "GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN7", Weight: 1, }).Return(nil).Once() - mockAccountSignersBatchInsertBuilder.On("Exec").Return(nil).Once() + mockAccountSignersBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQSigners.On("NewAccountSignersBatchInsertBuilder", maxBatchSize). Return(mockAccountSignersBatchInsertBuilder).Once() - q.MockQAssetStats.On("InsertAssetStats", []history.ExpAssetStat{}, 100000). + q.MockQAssetStats.On("InsertAssetStats", ctx, []history.ExpAssetStat{}, 100000). Return(nil) runner := ProcessorRunner{ - ctx: context.Background(), + ctx: ctx, config: config, historyQ: q, historyAdapter: historyAdapter, @@ -173,6 +172,7 @@ func TestProcessorRunnerRunHistoryArchiveIngestionHistoryArchive(t *testing.T) { } func TestProcessorRunnerRunHistoryArchiveIngestionProtocolVersionNotSupported(t *testing.T) { + ctx := context.Background() maxBatchSize := 100000 config := Config{ @@ -205,11 +205,11 @@ func TestProcessorRunnerRunHistoryArchiveIngestionProtocolVersionNotSupported(t q.MockQSigners.On("NewAccountSignersBatchInsertBuilder", maxBatchSize). Return(mockAccountSignersBatchInsertBuilder).Once() - q.MockQAssetStats.On("InsertAssetStats", []history.ExpAssetStat{}, 100000). + q.MockQAssetStats.On("InsertAssetStats", ctx, []history.ExpAssetStat{}, 100000). Return(nil) runner := ProcessorRunner{ - ctx: context.Background(), + ctx: ctx, config: config, historyQ: q, historyAdapter: historyAdapter, @@ -220,6 +220,7 @@ func TestProcessorRunnerRunHistoryArchiveIngestionProtocolVersionNotSupported(t } func TestProcessorRunnerBuildChangeProcessor(t *testing.T) { + ctx := context.Background() maxBatchSize := 100000 q := &mockDBQ{} @@ -234,6 +235,7 @@ func TestProcessorRunnerBuildChangeProcessor(t *testing.T) { Return(&history.MockAccountSignersBatchInsertBuilder{}).Twice() runner := ProcessorRunner{ + ctx: ctx, historyQ: q, } @@ -254,6 +256,7 @@ func TestProcessorRunnerBuildChangeProcessor(t *testing.T) { assert.IsType(t, &processors.TrustLinesProcessor{}, processor.processors[6]) runner = ProcessorRunner{ + ctx: ctx, historyQ: q, } @@ -274,6 +277,7 @@ func TestProcessorRunnerBuildChangeProcessor(t *testing.T) { } func TestProcessorRunnerBuildTransactionProcessor(t *testing.T) { + ctx := context.Background() maxBatchSize := 100000 q := &mockDBQ{} @@ -285,6 +289,7 @@ func TestProcessorRunnerBuildTransactionProcessor(t *testing.T) { Return(&history.MockTransactionsBatchInsertBuilder{}).Twice() runner := ProcessorRunner{ + ctx: ctx, config: Config{}, historyQ: q, } @@ -304,6 +309,7 @@ func TestProcessorRunnerBuildTransactionProcessor(t *testing.T) { } func TestProcessorRunnerRunAllProcessorsOnLedger(t *testing.T) { + ctx := context.Background() maxBatchSize := 100000 config := Config{ @@ -326,13 +332,13 @@ func TestProcessorRunnerRunAllProcessorsOnLedger(t *testing.T) { // Batches mockOffersBatchInsertBuilder := &history.MockOffersBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockOffersBatchInsertBuilder) - mockOffersBatchInsertBuilder.On("Exec").Return(nil).Once() + mockOffersBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQOffers.On("NewOffersBatchInsertBuilder", maxBatchSize). Return(mockOffersBatchInsertBuilder).Once() mockAccountDataBatchInsertBuilder := &history.MockAccountDataBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockAccountDataBatchInsertBuilder) - mockAccountDataBatchInsertBuilder.On("Exec").Return(nil).Once() + mockAccountDataBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQData.On("NewAccountDataBatchInsertBuilder", maxBatchSize). Return(mockAccountDataBatchInsertBuilder).Once() @@ -343,27 +349,27 @@ func TestProcessorRunnerRunAllProcessorsOnLedger(t *testing.T) { mockOperationsBatchInsertBuilder := &history.MockOperationsBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockOperationsBatchInsertBuilder) - mockOperationsBatchInsertBuilder.On("Exec").Return(nil).Once() + mockOperationsBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQOperations.On("NewOperationBatchInsertBuilder", maxBatchSize). Return(mockOperationsBatchInsertBuilder).Twice() mockTransactionsBatchInsertBuilder := &history.MockTransactionsBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockTransactionsBatchInsertBuilder) - mockTransactionsBatchInsertBuilder.On("Exec").Return(nil).Once() + mockTransactionsBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQTransactions.On("NewTransactionBatchInsertBuilder", maxBatchSize). Return(mockTransactionsBatchInsertBuilder).Twice() mockClaimableBalancesBatchInsertBuilder := &history.MockClaimableBalancesBatchInsertBuilder{} defer mock.AssertExpectationsForObjects(t, mockClaimableBalancesBatchInsertBuilder) - mockClaimableBalancesBatchInsertBuilder.On("Exec").Return(nil).Once() + mockClaimableBalancesBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() q.MockQClaimableBalances.On("NewClaimableBalancesBatchInsertBuilder", maxBatchSize). Return(mockClaimableBalancesBatchInsertBuilder).Once() - q.MockQLedgers.On("InsertLedger", ledger.V0.LedgerHeader, 0, 0, 0, 0, CurrentVersion). + q.MockQLedgers.On("InsertLedger", ctx, ledger.V0.LedgerHeader, 0, 0, 0, 0, CurrentVersion). Return(int64(1), nil).Once() runner := ProcessorRunner{ - ctx: context.Background(), + ctx: ctx, config: config, historyQ: q, } @@ -373,6 +379,7 @@ func TestProcessorRunnerRunAllProcessorsOnLedger(t *testing.T) { } func TestProcessorRunnerRunAllProcessorsOnLedgerProtocolVersionNotSupported(t *testing.T) { + ctx := context.Background() maxBatchSize := 100000 config := Config{ @@ -424,7 +431,7 @@ func TestProcessorRunnerRunAllProcessorsOnLedgerProtocolVersionNotSupported(t *t Return(mockClaimableBalancesBatchInsertBuilder).Once() runner := ProcessorRunner{ - ctx: context.Background(), + ctx: ctx, config: config, historyQ: q, } diff --git a/services/horizon/internal/ingest/processors/account_data_processor.go b/services/horizon/internal/ingest/processors/account_data_processor.go index acd06c5948..411a6a7c0d 100644 --- a/services/horizon/internal/ingest/processors/account_data_processor.go +++ b/services/horizon/internal/ingest/processors/account_data_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/errors" @@ -23,7 +25,7 @@ func (p *AccountDataProcessor) reset() { p.cache = ingest.NewChangeCompactor() } -func (p *AccountDataProcessor) ProcessChange(change ingest.Change) error { +func (p *AccountDataProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { // We're interested in data only if change.Type != xdr.LedgerEntryTypeData { return nil @@ -35,7 +37,7 @@ func (p *AccountDataProcessor) ProcessChange(change ingest.Change) error { } if p.cache.Size() > maxBatchSize { - err = p.Commit() + err = p.Commit(ctx) if err != nil { return errors.Wrap(err, "error in Commit") } @@ -45,7 +47,7 @@ func (p *AccountDataProcessor) ProcessChange(change ingest.Change) error { return nil } -func (p *AccountDataProcessor) Commit() error { +func (p *AccountDataProcessor) Commit(ctx context.Context) error { batch := p.dataQ.NewAccountDataBatchInsertBuilder(maxBatchSize) changes := p.cache.GetChanges() @@ -59,7 +61,7 @@ func (p *AccountDataProcessor) Commit() error { case change.Pre == nil && change.Post != nil: // Created action = "inserting" - err = batch.Add(*change.Post) + err = batch.Add(ctx, *change.Post) rowsAffected = 1 // We don't track this when batch inserting case change.Pre != nil && change.Post == nil: // Removed @@ -69,7 +71,7 @@ func (p *AccountDataProcessor) Commit() error { if err != nil { return errors.Wrap(err, "Error creating ledger key") } - rowsAffected, err = p.dataQ.RemoveAccountData(*ledgerKey.Data) + rowsAffected, err = p.dataQ.RemoveAccountData(ctx, *ledgerKey.Data) default: // Updated action = "updating" @@ -78,7 +80,7 @@ func (p *AccountDataProcessor) Commit() error { if err != nil { return errors.Wrap(err, "Error creating ledger key") } - rowsAffected, err = p.dataQ.UpdateAccountData(*change.Post) + rowsAffected, err = p.dataQ.UpdateAccountData(ctx, *change.Post) } if err != nil { @@ -96,7 +98,7 @@ func (p *AccountDataProcessor) Commit() error { } } - err := batch.Exec() + err := batch.Exec(ctx) if err != nil { return errors.Wrap(err, "error executing batch") } diff --git a/services/horizon/internal/ingest/processors/accounts_data_processor_test.go b/services/horizon/internal/ingest/processors/accounts_data_processor_test.go index fec0b3bb0a..7ba09b4822 100644 --- a/services/horizon/internal/ingest/processors/accounts_data_processor_test.go +++ b/services/horizon/internal/ingest/processors/accounts_data_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stellar/go/ingest" @@ -17,12 +18,14 @@ func TestAccountsDataProcessorTestSuiteState(t *testing.T) { type AccountsDataProcessorTestSuiteState struct { suite.Suite + ctx context.Context processor *AccountDataProcessor mockQ *history.MockQData mockBatchInsertBuilder *history.MockAccountDataBatchInsertBuilder } func (s *AccountsDataProcessorTestSuiteState) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQData{} s.mockBatchInsertBuilder = &history.MockAccountDataBatchInsertBuilder{} @@ -34,8 +37,8 @@ func (s *AccountsDataProcessorTestSuiteState) SetupTest() { } func (s *AccountsDataProcessorTestSuiteState) TearDownTest() { - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) s.mockBatchInsertBuilder.AssertExpectations(s.T()) @@ -59,9 +62,9 @@ func (s *AccountsDataProcessorTestSuiteState) TestCreatesAccounts() { }, LastModifiedLedgerSeq: lastModifiedLedgerSeq, } - s.mockBatchInsertBuilder.On("Add", entry).Return(nil).Once() + s.mockBatchInsertBuilder.On("Add", s.ctx, entry).Return(nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeData, Pre: nil, Post: &entry, @@ -75,12 +78,14 @@ func TestAccountsDataProcessorTestSuiteLedger(t *testing.T) { type AccountsDataProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *AccountDataProcessor mockQ *history.MockQData mockBatchInsertBuilder *history.MockAccountDataBatchInsertBuilder } func (s *AccountsDataProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQData{} s.mockBatchInsertBuilder = &history.MockAccountDataBatchInsertBuilder{} @@ -92,8 +97,8 @@ func (s *AccountsDataProcessorTestSuiteLedger) SetupTest() { } func (s *AccountsDataProcessorTestSuiteLedger) TearDownTest() { - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) } @@ -109,7 +114,7 @@ func (s *AccountsDataProcessorTestSuiteLedger) TestNewAccountData() { } lastModifiedLedgerSeq := xdr.Uint32(123) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeData, Pre: nil, Post: &xdr.LedgerEntry{ @@ -136,7 +141,7 @@ func (s *AccountsDataProcessorTestSuiteLedger) TestNewAccountData() { LastModifiedLedgerSeq: lastModifiedLedgerSeq, } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeData, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -150,7 +155,7 @@ func (s *AccountsDataProcessorTestSuiteLedger) TestNewAccountData() { s.Assert().NoError(err) // We use LedgerEntryChangesCache so all changes are squashed - s.mockBatchInsertBuilder.On("Add", updatedEntry).Return(nil).Once() + s.mockBatchInsertBuilder.On("Add", s.ctx, updatedEntry).Return(nil).Once() } func (s *AccountsDataProcessorTestSuiteLedger) TestUpdateAccountData() { @@ -175,7 +180,7 @@ func (s *AccountsDataProcessorTestSuiteLedger) TestUpdateAccountData() { LastModifiedLedgerSeq: lastModifiedLedgerSeq, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeData, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -188,11 +193,11 @@ func (s *AccountsDataProcessorTestSuiteLedger) TestUpdateAccountData() { }) s.Assert().NoError(err) - s.mockQ.On("UpdateAccountData", updatedEntry).Return(int64(1), nil).Once() + s.mockQ.On("UpdateAccountData", s.ctx, updatedEntry).Return(int64(1), nil).Once() } func (s *AccountsDataProcessorTestSuiteLedger) TestRemoveAccountData() { - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeData, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -210,6 +215,7 @@ func (s *AccountsDataProcessorTestSuiteLedger) TestRemoveAccountData() { s.mockQ.On( "RemoveAccountData", + s.ctx, xdr.LedgerKeyData{ AccountId: xdr.MustAddress("GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML"), DataName: "test", diff --git a/services/horizon/internal/ingest/processors/accounts_processor.go b/services/horizon/internal/ingest/processors/accounts_processor.go index 8f82d8712d..289ad23de5 100644 --- a/services/horizon/internal/ingest/processors/accounts_processor.go +++ b/services/horizon/internal/ingest/processors/accounts_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/errors" @@ -23,7 +25,7 @@ func (p *AccountsProcessor) reset() { p.cache = ingest.NewChangeCompactor() } -func (p *AccountsProcessor) ProcessChange(change ingest.Change) error { +func (p *AccountsProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { if change.Type != xdr.LedgerEntryTypeAccount { return nil } @@ -34,7 +36,7 @@ func (p *AccountsProcessor) ProcessChange(change ingest.Change) error { } if p.cache.Size() > maxBatchSize { - err = p.Commit() + err = p.Commit(ctx) if err != nil { return errors.Wrap(err, "error in Commit") } @@ -44,7 +46,7 @@ func (p *AccountsProcessor) ProcessChange(change ingest.Change) error { return nil } -func (p *AccountsProcessor) Commit() error { +func (p *AccountsProcessor) Commit(ctx context.Context) error { batchUpsertAccounts := []xdr.LedgerEntry{} changes := p.cache.GetChanges() @@ -66,7 +68,7 @@ func (p *AccountsProcessor) Commit() error { // Removed account := change.Pre.Data.MustAccount() accountID := account.AccountId.Address() - rowsAffected, err := p.accountsQ.RemoveAccount(accountID) + rowsAffected, err := p.accountsQ.RemoveAccount(ctx, accountID) if err != nil { return err @@ -86,7 +88,7 @@ func (p *AccountsProcessor) Commit() error { // Upsert accounts if len(batchUpsertAccounts) > 0 { - err := p.accountsQ.UpsertAccounts(batchUpsertAccounts) + err := p.accountsQ.UpsertAccounts(ctx, batchUpsertAccounts) if err != nil { return errors.Wrap(err, "errors in UpsertAccounts") } diff --git a/services/horizon/internal/ingest/processors/accounts_processor_test.go b/services/horizon/internal/ingest/processors/accounts_processor_test.go index b9707ecc3e..65dc2997e9 100644 --- a/services/horizon/internal/ingest/processors/accounts_processor_test.go +++ b/services/horizon/internal/ingest/processors/accounts_processor_test.go @@ -18,18 +18,20 @@ func TestAccountsProcessorTestSuiteState(t *testing.T) { type AccountsProcessorTestSuiteState struct { suite.Suite + ctx context.Context processor *AccountsProcessor mockQ *history.MockQAccounts } func (s *AccountsProcessorTestSuiteState) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQAccounts{} s.processor = NewAccountsProcessor(s.mockQ) } func (s *AccountsProcessorTestSuiteState) TearDownTest() { - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) } @@ -46,7 +48,7 @@ func (s *AccountsProcessorTestSuiteState) TestCreatesAccounts() { // We use LedgerEntryChangesCache so all changes are squashed s.mockQ.On( - "UpsertAccounts", + "UpsertAccounts", s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -58,7 +60,7 @@ func (s *AccountsProcessorTestSuiteState) TestCreatesAccounts() { }, ).Return(nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -78,19 +80,20 @@ func TestAccountsProcessorTestSuiteLedger(t *testing.T) { type AccountsProcessorTestSuiteLedger struct { suite.Suite - context context.Context + ctx context.Context processor *AccountsProcessor mockQ *history.MockQAccounts } func (s *AccountsProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQAccounts{} s.processor = NewAccountsProcessor(s.mockQ) } func (s *AccountsProcessorTestSuiteLedger) TearDownTest() { - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) } @@ -105,7 +108,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestNewAccount() { } lastModifiedLedgerSeq := xdr.Uint32(123) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -124,7 +127,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestNewAccount() { HomeDomain: "stellar.org", } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -146,6 +149,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestNewAccount() { // We use LedgerEntryChangesCache so all changes are squashed s.mockQ.On( "UpsertAccounts", + s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -161,10 +165,11 @@ func (s *AccountsProcessorTestSuiteLedger) TestNewAccount() { func (s *AccountsProcessorTestSuiteLedger) TestRemoveAccount() { s.mockQ.On( "RemoveAccount", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", ).Return(int64(1), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -187,7 +192,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestProcessUpgradeChange() { } lastModifiedLedgerSeq := xdr.Uint32(123) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -206,7 +211,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestProcessUpgradeChange() { HomeDomain: "stellar.org", } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -227,6 +232,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestProcessUpgradeChange() { s.mockQ.On( "UpsertAccounts", + s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: lastModifiedLedgerSeq + 1, @@ -240,7 +246,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestProcessUpgradeChange() { } func (s *AccountsProcessorTestSuiteLedger) TestFeeProcessedBeforeEverythingElse() { - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -263,7 +269,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestFeeProcessedBeforeEverythingElse( }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -293,6 +299,7 @@ func (s *AccountsProcessorTestSuiteLedger) TestFeeProcessedBeforeEverythingElse( s.mockQ.On( "UpsertAccounts", + s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: 0, diff --git a/services/horizon/internal/ingest/processors/asset_stats_processor.go b/services/horizon/internal/ingest/processors/asset_stats_processor.go index f8f20cbc83..818465d984 100644 --- a/services/horizon/internal/ingest/processors/asset_stats_processor.go +++ b/services/horizon/internal/ingest/processors/asset_stats_processor.go @@ -1,6 +1,7 @@ package processors import ( + "context" "database/sql" "github.com/stellar/go/ingest" @@ -39,12 +40,12 @@ func (p *AssetStatsProcessor) reset() { p.assetStatSet = AssetStatSet{} } -func (p *AssetStatsProcessor) ProcessChange(change ingest.Change) error { +func (p *AssetStatsProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { if change.Type != xdr.LedgerEntryTypeClaimableBalance && change.Type != xdr.LedgerEntryTypeTrustline { return nil } if p.useLedgerEntryCache { - return p.addToCache(change) + return p.addToCache(ctx, change) } if change.Pre != nil || change.Post == nil { return errors.New("AssetStatsProcessor is in insert only mode") @@ -60,14 +61,14 @@ func (p *AssetStatsProcessor) ProcessChange(change ingest.Change) error { } } -func (p *AssetStatsProcessor) addToCache(change ingest.Change) error { +func (p *AssetStatsProcessor) addToCache(ctx context.Context, change ingest.Change) error { err := p.cache.AddChange(change) if err != nil { return errors.Wrap(err, "error adding to ledgerCache") } if p.cache.Size() > maxBatchSize { - err = p.Commit() + err = p.Commit(ctx) if err != nil { return errors.Wrap(err, "error in Commit") } @@ -76,9 +77,9 @@ func (p *AssetStatsProcessor) addToCache(change ingest.Change) error { return nil } -func (p *AssetStatsProcessor) Commit() error { +func (p *AssetStatsProcessor) Commit(ctx context.Context) error { if !p.useLedgerEntryCache { - return p.assetStatsQ.InsertAssetStats(p.assetStatSet.All(), maxBatchSize) + return p.assetStatsQ.InsertAssetStats(ctx, p.assetStatSet.All(), maxBatchSize) } changes := p.cache.GetChanges() @@ -104,7 +105,7 @@ func (p *AssetStatsProcessor) Commit() error { var stat history.ExpAssetStat var err error - stat, err = p.assetStatsQ.GetAssetStat( + stat, err = p.assetStatsQ.GetAssetStat(ctx, delta.AssetType, delta.AssetCode, delta.AssetIssuer, @@ -148,7 +149,7 @@ func (p *AssetStatsProcessor) Commit() error { // Insert var errInsert error - rowsAffected, errInsert = p.assetStatsQ.InsertAssetStat(delta) + rowsAffected, errInsert = p.assetStatsQ.InsertAssetStat(ctx, delta) if errInsert != nil { return errors.Wrap(errInsert, "could not insert asset stat") } @@ -176,7 +177,7 @@ func (p *AssetStatsProcessor) Commit() error { delta.AssetIssuer, )) } - rowsAffected, err = p.assetStatsQ.RemoveAssetStat( + rowsAffected, err = p.assetStatsQ.RemoveAssetStat(ctx, delta.AssetType, delta.AssetCode, delta.AssetIssuer, @@ -186,7 +187,7 @@ func (p *AssetStatsProcessor) Commit() error { } } else { // Update - rowsAffected, err = p.assetStatsQ.UpdateAssetStat(history.ExpAssetStat{ + rowsAffected, err = p.assetStatsQ.UpdateAssetStat(ctx, history.ExpAssetStat{ AssetType: delta.AssetType, AssetCode: delta.AssetCode, AssetIssuer: delta.AssetIssuer, diff --git a/services/horizon/internal/ingest/processors/asset_stats_processor_test.go b/services/horizon/internal/ingest/processors/asset_stats_processor_test.go index 53c15d9c3a..78ef55ea31 100644 --- a/services/horizon/internal/ingest/processors/asset_stats_processor_test.go +++ b/services/horizon/internal/ingest/processors/asset_stats_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "database/sql" "testing" @@ -18,17 +19,19 @@ func TestAssetStatsProcessorTestSuiteState(t *testing.T) { type AssetStatsProcessorTestSuiteState struct { suite.Suite + ctx context.Context processor *AssetStatsProcessor mockQ *history.MockQAssetStats } func (s *AssetStatsProcessorTestSuiteState) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQAssetStats{} s.processor = NewAssetStatsProcessor(s.mockQ, false) } func (s *AssetStatsProcessorTestSuiteState) TearDownTest() { - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) } @@ -40,7 +43,7 @@ func (s *AssetStatsProcessorTestSuiteState) TestCreateTrustLine() { } lastModifiedLedgerSeq := xdr.Uint32(123) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -53,7 +56,7 @@ func (s *AssetStatsProcessorTestSuiteState) TestCreateTrustLine() { }) s.Assert().NoError(err) - s.mockQ.On("InsertAssetStats", []history.ExpAssetStat{ + s.mockQ.On("InsertAssetStats", s.ctx, []history.ExpAssetStat{ { AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), @@ -77,7 +80,7 @@ func (s *AssetStatsProcessorTestSuiteState) TestCreateTrustLineUnauthorized() { Asset: xdr.MustNewCreditAsset("EUR", trustLineIssuer.Address()), } lastModifiedLedgerSeq := xdr.Uint32(123) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -90,7 +93,7 @@ func (s *AssetStatsProcessorTestSuiteState) TestCreateTrustLineUnauthorized() { }) s.Assert().NoError(err) - s.mockQ.On("InsertAssetStats", []history.ExpAssetStat{ + s.mockQ.On("InsertAssetStats", s.ctx, []history.ExpAssetStat{ { AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), @@ -114,11 +117,13 @@ func TestAssetStatsProcessorTestSuiteLedger(t *testing.T) { type AssetStatsProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *AssetStatsProcessor mockQ *history.MockQAssetStats } func (s *AssetStatsProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQAssetStats{} s.processor = NewAssetStatsProcessor(s.mockQ, true) @@ -150,7 +155,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalance() { // test inserts - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: nil, Post: &xdr.LedgerEntry{ @@ -163,7 +168,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalance() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: nil, Post: &xdr.LedgerEntry{ @@ -185,7 +190,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalance() { }, } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: nil, Post: &xdr.LedgerEntry{ @@ -203,7 +208,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalance() { updatedClaimableBalance := claimableBalance updatedClaimableBalance.Amount *= 2 - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -222,12 +227,12 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalance() { }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), ).Return(history.ExpAssetStat{}, sql.ErrNoRows).Once() - s.mockQ.On("InsertAssetStat", history.ExpAssetStat{ + s.mockQ.On("InsertAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "EUR", @@ -244,12 +249,12 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalance() { NumAccounts: 0, }).Return(int64(1), nil).Once() - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", trustLineIssuer.Address(), ).Return(history.ExpAssetStat{}, sql.ErrNoRows).Once() - s.mockQ.On("InsertAssetStat", history.ExpAssetStat{ + s.mockQ.On("InsertAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "USD", @@ -266,12 +271,12 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalance() { NumAccounts: 0, }).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { // should be ignored because it's not an trust line type - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -300,7 +305,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { } lastModifiedLedgerSeq := xdr.Uint32(1234) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -313,7 +318,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -338,7 +343,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { Balance: 10, } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -357,7 +362,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -376,12 +381,12 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), ).Return(history.ExpAssetStat{}, sql.ErrNoRows).Once() - s.mockQ.On("InsertAssetStat", history.ExpAssetStat{ + s.mockQ.On("InsertAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "EUR", @@ -398,12 +403,12 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { NumAccounts: 1, }).Return(int64(1), nil).Once() - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", trustLineIssuer.Address(), ).Return(history.ExpAssetStat{}, sql.ErrNoRows).Once() - s.mockQ.On("InsertAssetStat", history.ExpAssetStat{ + s.mockQ.On("InsertAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "USD", @@ -420,7 +425,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertTrustLine() { NumAccounts: 0, }).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalanceAndTrustline() { @@ -441,7 +446,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalanceAndTrustl } lastModifiedLedgerSeq := xdr.Uint32(1234) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: nil, Post: &xdr.LedgerEntry{ @@ -454,7 +459,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalanceAndTrustl }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -467,12 +472,12 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalanceAndTrustl }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), ).Return(history.ExpAssetStat{}, sql.ErrNoRows).Once() - s.mockQ.On("InsertAssetStat", history.ExpAssetStat{ + s.mockQ.On("InsertAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "EUR", @@ -490,7 +495,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestInsertClaimableBalanceAndTrustl NumAccounts: 1, }).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLine() { @@ -509,7 +514,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLine() { Flags: xdr.Uint32(xdr.TrustLineFlagsAuthorizedFlag), } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -528,7 +533,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLine() { }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), @@ -546,7 +551,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLine() { Amount: "100", NumAccounts: 1, }, nil).Once() - s.mockQ.On("UpdateAssetStat", history.ExpAssetStat{ + s.mockQ.On("UpdateAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "EUR", @@ -561,7 +566,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLine() { NumAccounts: 1, }).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() { @@ -607,7 +612,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() Flags: xdr.Uint32(xdr.TrustLineFlagsAuthorizedToMaintainLiabilitiesFlag), } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -626,7 +631,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -645,7 +650,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -664,7 +669,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), @@ -684,7 +689,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() Amount: "0", NumAccounts: 0, }, nil).Once() - s.mockQ.On("UpdateAssetStat", history.ExpAssetStat{ + s.mockQ.On("UpdateAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "EUR", @@ -701,7 +706,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() NumAccounts: 1, }).Return(int64(1), nil).Once() - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", trustLineIssuer.Address(), @@ -721,7 +726,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() Amount: "100", NumAccounts: 1, }, nil).Once() - s.mockQ.On("UpdateAssetStat", history.ExpAssetStat{ + s.mockQ.On("UpdateAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "USD", @@ -738,7 +743,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() NumAccounts: 0, }).Return(int64(1), nil).Once() - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "ETH", trustLineIssuer.Address(), @@ -758,7 +763,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() Amount: "100", NumAccounts: 1, }, nil).Once() - s.mockQ.On("UpdateAssetStat", history.ExpAssetStat{ + s.mockQ.On("UpdateAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "ETH", @@ -775,7 +780,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() NumAccounts: 0, }).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveClaimableBalance() { @@ -796,7 +801,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveClaimableBalance() { }, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -808,7 +813,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveClaimableBalance() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -820,7 +825,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveClaimableBalance() { }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), @@ -840,13 +845,13 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveClaimableBalance() { Amount: "0", NumAccounts: 0, }, nil).Once() - s.mockQ.On("RemoveAssetStat", + s.mockQ.On("RemoveAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), ).Return(int64(1), nil).Once() - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", trustLineIssuer.Address(), @@ -867,7 +872,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveClaimableBalance() { Amount: "0", NumAccounts: 0, }, nil).Once() - s.mockQ.On("UpdateAssetStat", history.ExpAssetStat{ + s.mockQ.On("UpdateAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "USD", @@ -882,7 +887,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveClaimableBalance() { NumAccounts: 0, }).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveTrustLine() { @@ -898,7 +903,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveTrustLine() { Balance: 0, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -910,7 +915,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveTrustLine() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -922,7 +927,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveTrustLine() { }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), @@ -942,13 +947,13 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveTrustLine() { Amount: "0", NumAccounts: 1, }, nil).Once() - s.mockQ.On("RemoveAssetStat", + s.mockQ.On("RemoveAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), ).Return(int64(1), nil).Once() - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", trustLineIssuer.Address(), @@ -968,13 +973,13 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestRemoveTrustLine() { Amount: "0", NumAccounts: 0, }, nil).Once() - s.mockQ.On("RemoveAssetStat", + s.mockQ.On("RemoveAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", trustLineIssuer.Address(), ).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AssetStatsProcessorTestSuiteLedger) TestProcessUpgradeChange() { @@ -987,7 +992,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestProcessUpgradeChange() { Flags: xdr.Uint32(xdr.TrustLineFlagsAuthorizedFlag), } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Post: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -1006,7 +1011,7 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestProcessUpgradeChange() { Flags: xdr.Uint32(xdr.TrustLineFlagsAuthorizedFlag), } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -1025,12 +1030,12 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestProcessUpgradeChange() { }) s.Assert().NoError(err) - s.mockQ.On("GetAssetStat", + s.mockQ.On("GetAssetStat", s.ctx, xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", trustLineIssuer.Address(), ).Return(history.ExpAssetStat{}, sql.ErrNoRows).Once() - s.mockQ.On("InsertAssetStat", history.ExpAssetStat{ + s.mockQ.On("InsertAssetStat", s.ctx, history.ExpAssetStat{ AssetType: xdr.AssetTypeAssetTypeCreditAlphanum4, AssetIssuer: trustLineIssuer.Address(), AssetCode: "EUR", @@ -1046,5 +1051,5 @@ func (s *AssetStatsProcessorTestSuiteLedger) TestProcessUpgradeChange() { Amount: "10", NumAccounts: 1, }).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } diff --git a/services/horizon/internal/ingest/processors/change_processors.go b/services/horizon/internal/ingest/processors/change_processors.go index eab4305604..6c939288b8 100644 --- a/services/horizon/internal/ingest/processors/change_processors.go +++ b/services/horizon/internal/ingest/processors/change_processors.go @@ -1,6 +1,7 @@ package processors import ( + "context" "io" "github.com/stellar/go/ingest" @@ -8,14 +9,15 @@ import ( ) type ChangeProcessor interface { - ProcessChange(change ingest.Change) error + ProcessChange(ctx context.Context, change ingest.Change) error } type LedgerTransactionProcessor interface { - ProcessTransaction(transaction ingest.LedgerTransaction) error + ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) error } func StreamLedgerTransactions( + ctx context.Context, txProcessor LedgerTransactionProcessor, reader *ingest.LedgerTransactionReader, ) error { @@ -27,7 +29,7 @@ func StreamLedgerTransactions( if err != nil { return errors.Wrap(err, "could not read transaction") } - if err = txProcessor.ProcessTransaction(tx); err != nil { + if err = txProcessor.ProcessTransaction(ctx, tx); err != nil { return errors.Wrapf( err, "could not process transaction %v", @@ -38,6 +40,7 @@ func StreamLedgerTransactions( } func StreamChanges( + ctx context.Context, changeProcessor ChangeProcessor, reader ingest.ChangeReader, ) error { @@ -50,7 +53,7 @@ func StreamChanges( return errors.Wrap(err, "could not read transaction") } - if err = changeProcessor.ProcessChange(change); err != nil { + if err = changeProcessor.ProcessChange(ctx, change); err != nil { return errors.Wrap( err, "could not process change", diff --git a/services/horizon/internal/ingest/processors/change_processors_test.go b/services/horizon/internal/ingest/processors/change_processors_test.go index 1b3104aa59..829552543f 100644 --- a/services/horizon/internal/ingest/processors/change_processors_test.go +++ b/services/horizon/internal/ingest/processors/change_processors_test.go @@ -1,6 +1,7 @@ package processors import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -11,6 +12,7 @@ import ( func TestStreamReaderError(t *testing.T) { tt := assert.New(t) + ctx := context.Background() mockChangeReader := &ingest.MockChangeReader{} mockChangeReader. @@ -18,12 +20,13 @@ func TestStreamReaderError(t *testing.T) { Return(ingest.Change{}, errors.New("transient error")).Once() mockChangeProcessor := &MockChangeProcessor{} - err := StreamChanges(mockChangeProcessor, mockChangeReader) + err := StreamChanges(ctx, mockChangeProcessor, mockChangeReader) tt.EqualError(err, "could not read transaction: transient error") } func TestStreamChangeProcessorError(t *testing.T) { tt := assert.New(t) + ctx := context.Background() change := ingest.Change{} mockChangeReader := &ingest.MockChangeReader{} @@ -34,11 +37,11 @@ func TestStreamChangeProcessorError(t *testing.T) { mockChangeProcessor := &MockChangeProcessor{} mockChangeProcessor. On( - "ProcessChange", + "ProcessChange", ctx, change, ). Return(errors.New("transient error")).Once() - err := StreamChanges(mockChangeProcessor, mockChangeReader) + err := StreamChanges(ctx, mockChangeProcessor, mockChangeReader) tt.EqualError(err, "could not process change: transient error") } diff --git a/services/horizon/internal/ingest/processors/claimable_balances_change_processor.go b/services/horizon/internal/ingest/processors/claimable_balances_change_processor.go index 79dc442697..390172217a 100644 --- a/services/horizon/internal/ingest/processors/claimable_balances_change_processor.go +++ b/services/horizon/internal/ingest/processors/claimable_balances_change_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/errors" @@ -24,7 +26,7 @@ func (p *ClaimableBalancesChangeProcessor) reset() { p.cache = ingest.NewChangeCompactor() } -func (p *ClaimableBalancesChangeProcessor) ProcessChange(change ingest.Change) error { +func (p *ClaimableBalancesChangeProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { if change.Type != xdr.LedgerEntryTypeClaimableBalance { return nil } @@ -35,7 +37,7 @@ func (p *ClaimableBalancesChangeProcessor) ProcessChange(change ingest.Change) e } if p.cache.Size() > maxBatchSize { - err = p.Commit() + err = p.Commit(ctx) if err != nil { return errors.Wrap(err, "error in Commit") } @@ -45,7 +47,7 @@ func (p *ClaimableBalancesChangeProcessor) ProcessChange(change ingest.Change) e return nil } -func (p *ClaimableBalancesChangeProcessor) Commit() error { +func (p *ClaimableBalancesChangeProcessor) Commit(ctx context.Context) error { batch := p.qClaimableBalances.NewClaimableBalancesBatchInsertBuilder(maxBatchSize) changes := p.cache.GetChanges() @@ -59,7 +61,7 @@ func (p *ClaimableBalancesChangeProcessor) Commit() error { case change.Pre == nil && change.Post != nil: // Created action = "inserting" - err = batch.Add(change.Post) + err = batch.Add(ctx, change.Post) rowsAffected = 1 case change.Pre != nil && change.Post == nil: // Removed @@ -69,7 +71,7 @@ func (p *ClaimableBalancesChangeProcessor) Commit() error { if err != nil { return errors.Wrap(err, "Error creating ledger key") } - rowsAffected, err = p.qClaimableBalances.RemoveClaimableBalance(cBalance) + rowsAffected, err = p.qClaimableBalances.RemoveClaimableBalance(ctx, cBalance) default: // Updated action = "updating" @@ -78,7 +80,7 @@ func (p *ClaimableBalancesChangeProcessor) Commit() error { if err != nil { return errors.Wrap(err, "Error creating ledger key") } - rowsAffected, err = p.qClaimableBalances.UpdateClaimableBalance(*change.Post) + rowsAffected, err = p.qClaimableBalances.UpdateClaimableBalance(ctx, *change.Post) } if err != nil { @@ -99,7 +101,7 @@ func (p *ClaimableBalancesChangeProcessor) Commit() error { } } - err := batch.Exec() + err := batch.Exec(ctx) if err != nil { return errors.Wrap(err, "error executing batch") } diff --git a/services/horizon/internal/ingest/processors/claimable_balances_change_processor_test.go b/services/horizon/internal/ingest/processors/claimable_balances_change_processor_test.go index 049fb90fa9..93b5792017 100644 --- a/services/horizon/internal/ingest/processors/claimable_balances_change_processor_test.go +++ b/services/horizon/internal/ingest/processors/claimable_balances_change_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stretchr/testify/suite" @@ -18,12 +19,14 @@ func TestClaimableBalancesChangeProcessorTestSuiteState(t *testing.T) { type ClaimableBalancesChangeProcessorTestSuiteState struct { suite.Suite + ctx context.Context processor *ClaimableBalancesChangeProcessor mockQ *history.MockQClaimableBalances mockBatchInsertBuilder *history.MockClaimableBalancesBatchInsertBuilder } func (s *ClaimableBalancesChangeProcessorTestSuiteState) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQClaimableBalances{} s.mockBatchInsertBuilder = &history.MockClaimableBalancesBatchInsertBuilder{} @@ -35,8 +38,8 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteState) SetupTest() { } func (s *ClaimableBalancesChangeProcessorTestSuiteState) TearDownTest() { - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) s.mockBatchInsertBuilder.AssertExpectations(s.T()) } @@ -57,7 +60,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteState) TestCreatesClaimableBal Amount: 10, } - s.mockBatchInsertBuilder.On("Add", &xdr.LedgerEntry{ + s.mockBatchInsertBuilder.On("Add", s.ctx, &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, Data: xdr.LedgerEntryData{ Type: xdr.LedgerEntryTypeClaimableBalance, @@ -65,7 +68,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteState) TestCreatesClaimableBal }, }).Return(nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: nil, Post: &xdr.LedgerEntry{ @@ -85,12 +88,14 @@ func TestClaimableBalancesChangeProcessorTestSuiteLedger(t *testing.T) { type ClaimableBalancesChangeProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *ClaimableBalancesChangeProcessor mockQ *history.MockQClaimableBalances mockBatchInsertBuilder *history.MockClaimableBalancesBatchInsertBuilder } func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQClaimableBalances{} s.mockBatchInsertBuilder = &history.MockClaimableBalancesBatchInsertBuilder{} @@ -102,8 +107,8 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) SetupTest() { } func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TearDownTest() { - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) } @@ -135,7 +140,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TestNewClaimableBalanc }, }, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: nil, Post: &entry, @@ -158,7 +163,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TestNewClaimableBalanc } entry.LastModifiedLedgerSeq = entry.LastModifiedLedgerSeq - 1 - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &entry, Post: &updated, @@ -168,6 +173,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TestNewClaimableBalanc // We use LedgerEntryChangesCache so all changes are squashed s.mockBatchInsertBuilder.On( "Add", + s.ctx, &updated, ).Return(nil).Once() } @@ -213,7 +219,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TestUpdateClaimableBal }, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &pre, Post: &updated, @@ -222,6 +228,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TestUpdateClaimableBal s.mockQ.On( "UpdateClaimableBalance", + s.ctx, updated, ).Return(int64(1), nil).Once() } @@ -250,7 +257,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TestRemoveClaimableBal }, }, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeClaimableBalance, Pre: &pre, Post: nil, @@ -259,6 +266,7 @@ func (s *ClaimableBalancesChangeProcessorTestSuiteLedger) TestRemoveClaimableBal s.mockQ.On( "RemoveClaimableBalance", + s.ctx, cBalance, ).Return(int64(1), nil).Once() } diff --git a/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor.go b/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor.go index f67d9d0b4f..c301418ca4 100644 --- a/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor.go +++ b/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/toid" @@ -42,7 +44,7 @@ func NewClaimableBalancesTransactionProcessor(Q history.QHistoryClaimableBalance } } -func (p *ClaimableBalancesTransactionProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) error { +func (p *ClaimableBalancesTransactionProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) error { err := p.addTransactionClaimableBalances(p.claimableBalanceSet, p.sequence, transaction) if err != nil { return err @@ -173,17 +175,17 @@ func claimableBalancesForOperations(transaction ingest.LedgerTransaction, sequen return cbs, nil } -func (p *ClaimableBalancesTransactionProcessor) Commit() error { +func (p *ClaimableBalancesTransactionProcessor) Commit(ctx context.Context) error { if len(p.claimableBalanceSet) > 0 { - if err := p.loadClaimableBalanceIDs(p.claimableBalanceSet); err != nil { + if err := p.loadClaimableBalanceIDs(ctx, p.claimableBalanceSet); err != nil { return err } - if err := p.insertDBTransactionClaimableBalances(p.claimableBalanceSet); err != nil { + if err := p.insertDBTransactionClaimableBalances(ctx, p.claimableBalanceSet); err != nil { return err } - if err := p.insertDBOperationsClaimableBalances(p.claimableBalanceSet); err != nil { + if err := p.insertDBOperationsClaimableBalances(ctx, p.claimableBalanceSet); err != nil { return err } } @@ -191,13 +193,13 @@ func (p *ClaimableBalancesTransactionProcessor) Commit() error { return nil } -func (p *ClaimableBalancesTransactionProcessor) loadClaimableBalanceIDs(claimableBalanceSet map[xdr.ClaimableBalanceId]claimableBalance) error { +func (p *ClaimableBalancesTransactionProcessor) loadClaimableBalanceIDs(ctx context.Context, claimableBalanceSet map[xdr.ClaimableBalanceId]claimableBalance) error { ids := make([]xdr.ClaimableBalanceId, 0, len(claimableBalanceSet)) for id := range claimableBalanceSet { ids = append(ids, id) } - toInternalID, err := p.qClaimableBalances.CreateHistoryClaimableBalances(ids, maxBatchSize) + toInternalID, err := p.qClaimableBalances.CreateHistoryClaimableBalances(ctx, ids, maxBatchSize) if err != nil { return errors.Wrap(err, "Could not create claimable balance ids") } @@ -221,35 +223,35 @@ func (p *ClaimableBalancesTransactionProcessor) loadClaimableBalanceIDs(claimabl return nil } -func (p ClaimableBalancesTransactionProcessor) insertDBTransactionClaimableBalances(claimableBalanceSet map[xdr.ClaimableBalanceId]claimableBalance) error { +func (p ClaimableBalancesTransactionProcessor) insertDBTransactionClaimableBalances(ctx context.Context, claimableBalanceSet map[xdr.ClaimableBalanceId]claimableBalance) error { batch := p.qClaimableBalances.NewTransactionClaimableBalanceBatchInsertBuilder(maxBatchSize) for _, entry := range claimableBalanceSet { for transactionID := range entry.transactionSet { - if err := batch.Add(transactionID, entry.internalID); err != nil { + if err := batch.Add(ctx, transactionID, entry.internalID); err != nil { return errors.Wrap(err, "could not insert transaction claimable balance in db") } } } - if err := batch.Exec(); err != nil { + if err := batch.Exec(ctx); err != nil { return errors.Wrap(err, "could not flush transaction claimable balances to db") } return nil } -func (p ClaimableBalancesTransactionProcessor) insertDBOperationsClaimableBalances(claimableBalanceSet map[xdr.ClaimableBalanceId]claimableBalance) error { +func (p ClaimableBalancesTransactionProcessor) insertDBOperationsClaimableBalances(ctx context.Context, claimableBalanceSet map[xdr.ClaimableBalanceId]claimableBalance) error { batch := p.qClaimableBalances.NewOperationClaimableBalanceBatchInsertBuilder(maxBatchSize) for _, entry := range claimableBalanceSet { for operationID := range entry.operationSet { - if err := batch.Add(operationID, entry.internalID); err != nil { + if err := batch.Add(ctx, operationID, entry.internalID); err != nil { return errors.Wrap(err, "could not insert operation claimable balance in db") } } } - if err := batch.Exec(); err != nil { + if err := batch.Exec(ctx); err != nil { return errors.Wrap(err, "could not flush operation claimable balances to db") } return nil diff --git a/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor_test.go b/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor_test.go index a9b1c30792..e482c88ef6 100644 --- a/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor_test.go +++ b/services/horizon/internal/ingest/processors/claimable_balances_transaction_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stretchr/testify/mock" @@ -15,6 +16,7 @@ import ( type ClaimableBalancesTransactionProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *ClaimableBalancesTransactionProcessor mockQ *history.MockQHistoryClaimableBalances mockTransactionBatchInsertBuilder *history.MockTransactionClaimableBalanceBatchInsertBuilder @@ -28,6 +30,7 @@ func TestClaimableBalancesTransactionProcessorTestSuiteLedger(t *testing.T) { } func (s *ClaimableBalancesTransactionProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQHistoryClaimableBalances{} s.mockTransactionBatchInsertBuilder = &history.MockTransactionClaimableBalanceBatchInsertBuilder{} s.mockOperationBatchInsertBuilder = &history.MockOperationClaimableBalanceBatchInsertBuilder{} @@ -46,16 +49,16 @@ func (s *ClaimableBalancesTransactionProcessorTestSuiteLedger) TearDownTest() { } func (s *ClaimableBalancesTransactionProcessorTestSuiteLedger) mockTransactionBatchAdd(transactionID, internalID int64, err error) { - s.mockTransactionBatchInsertBuilder.On("Add", transactionID, internalID).Return(err).Once() + s.mockTransactionBatchInsertBuilder.On("Add", s.ctx, transactionID, internalID).Return(err).Once() } func (s *ClaimableBalancesTransactionProcessorTestSuiteLedger) mockOperationBatchAdd(operationID, internalID int64, err error) { - s.mockOperationBatchInsertBuilder.On("Add", operationID, internalID).Return(err).Once() + s.mockOperationBatchInsertBuilder.On("Add", s.ctx, operationID, internalID).Return(err).Once() } func (s *ClaimableBalancesTransactionProcessorTestSuiteLedger) TestEmptyClaimableBalances() { // What is this expecting? Doesn't seem to assert anything meaningful... - err := s.processor.Commit() + err := s.processor.Commit(context.Background()) s.Assert().NoError(err) } @@ -109,9 +112,9 @@ func (s *ClaimableBalancesTransactionProcessorTestSuiteLedger) testOperationInse hexID, _ := xdr.MarshalHex(balanceID) // Setup a q - s.mockQ.On("CreateHistoryClaimableBalances", mock.AnythingOfType("[]xdr.ClaimableBalanceId"), maxBatchSize). + s.mockQ.On("CreateHistoryClaimableBalances", s.ctx, mock.AnythingOfType("[]xdr.ClaimableBalanceId"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.ClaimableBalanceId) + arg := args.Get(1).([]xdr.ClaimableBalanceId) s.Assert().ElementsMatch( []xdr.ClaimableBalanceId{ balanceID, @@ -126,18 +129,18 @@ func (s *ClaimableBalancesTransactionProcessorTestSuiteLedger) testOperationInse s.mockQ.On("NewTransactionClaimableBalanceBatchInsertBuilder", maxBatchSize). Return(s.mockTransactionBatchInsertBuilder).Once() s.mockTransactionBatchAdd(txnID, internalID, nil) - s.mockTransactionBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockTransactionBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() // Prepare to process operations successfully s.mockQ.On("NewOperationClaimableBalanceBatchInsertBuilder", maxBatchSize). Return(s.mockOperationBatchInsertBuilder).Once() s.mockOperationBatchAdd(opID, internalID, nil) - s.mockOperationBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockOperationBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() // Process the transaction - err := s.processor.ProcessTransaction(txn) + err := s.processor.ProcessTransaction(s.ctx, txn) s.Assert().NoError(err) - err = s.processor.Commit() + err = s.processor.Commit(s.ctx) s.Assert().NoError(err) } diff --git a/services/horizon/internal/ingest/processors/effects_processor.go b/services/horizon/internal/ingest/processors/effects_processor.go index 9708f94d03..93e129cd9c 100644 --- a/services/horizon/internal/ingest/processors/effects_processor.go +++ b/services/horizon/internal/ingest/processors/effects_processor.go @@ -1,6 +1,7 @@ package processors import ( + "context" "encoding/base64" "encoding/json" "fmt" @@ -29,13 +30,13 @@ func NewEffectProcessor(effectsQ history.QEffects, sequence uint32) *EffectProce } } -func (p *EffectProcessor) loadAccountIDs(accountSet map[string]int64) error { +func (p *EffectProcessor) loadAccountIDs(ctx context.Context, accountSet map[string]int64) error { addresses := make([]string, 0, len(accountSet)) for address := range accountSet { addresses = append(addresses, address) } - addressToID, err := p.effectsQ.CreateAccounts(addresses, maxBatchSize) + addressToID, err := p.effectsQ.CreateAccounts(ctx, addresses, maxBatchSize) if err != nil { return errors.Wrap(err, "Could not create account ids") } @@ -73,7 +74,7 @@ func operationsEffects(transaction ingest.LedgerTransaction, sequence uint32) ([ return effects, nil } -func (p *EffectProcessor) insertDBOperationsEffects(effects []effect, accountSet map[string]int64) error { +func (p *EffectProcessor) insertDBOperationsEffects(ctx context.Context, effects []effect, accountSet map[string]int64) error { batch := p.effectsQ.NewEffectBatchInsertBuilder(maxBatchSize) for _, effect := range effects { @@ -90,7 +91,7 @@ func (p *EffectProcessor) insertDBOperationsEffects(effects []effect, accountSet return errors.Wrapf(err, "Error marshaling details for operation effect %v", effect.operationID) } - if err := batch.Add( + if err := batch.Add(ctx, accountID, effect.operationID, effect.order, @@ -101,13 +102,13 @@ func (p *EffectProcessor) insertDBOperationsEffects(effects []effect, accountSet } } - if err := batch.Exec(); err != nil { + if err := batch.Exec(ctx); err != nil { return errors.Wrap(err, "could not flush operation effects to db") } return nil } -func (p *EffectProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) (err error) { +func (p *EffectProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) (err error) { // Failed transactions don't have operation effects if !transaction.Result.Successful() { return nil @@ -123,7 +124,7 @@ func (p *EffectProcessor) ProcessTransaction(transaction ingest.LedgerTransactio return nil } -func (p *EffectProcessor) Commit() (err error) { +func (p *EffectProcessor) Commit(ctx context.Context) (err error) { if len(p.effects) > 0 { accountSet := map[string]int64{} @@ -131,11 +132,11 @@ func (p *EffectProcessor) Commit() (err error) { accountSet[effect.address] = 0 } - if err = p.loadAccountIDs(accountSet); err != nil { + if err = p.loadAccountIDs(ctx, accountSet); err != nil { return err } - if err = p.insertDBOperationsEffects(p.effects, accountSet); err != nil { + if err = p.insertDBOperationsEffects(ctx, p.effects, accountSet); err != nil { return err } } diff --git a/services/horizon/internal/ingest/processors/effects_processor_test.go b/services/horizon/internal/ingest/processors/effects_processor_test.go index 5ff9bf6a0d..8672c82cb3 100644 --- a/services/horizon/internal/ingest/processors/effects_processor_test.go +++ b/services/horizon/internal/ingest/processors/effects_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -19,6 +20,7 @@ import ( type EffectsProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *EffectProcessor mockQ *history.MockQEffects mockBatchInsertBuilder *history.MockEffectBatchInsertBuilder @@ -42,6 +44,7 @@ func TestEffectsProcessorTestSuiteLedger(t *testing.T) { } func (s *EffectsProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQEffects{} s.mockBatchInsertBuilder = &history.MockEffectBatchInsertBuilder{} @@ -131,6 +134,7 @@ func (s *EffectsProcessorTestSuiteLedger) TearDownTest() { func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulEffectBatchAdds() { s.mockBatchInsertBuilder.On( "Add", + s.ctx, s.addressToID[s.addresses[2]], toid.New(int32(s.sequence), 1, 1).ToInt64(), uint32(1), @@ -139,6 +143,7 @@ func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulEffectBatchAdds() { ).Return(nil).Once() s.mockBatchInsertBuilder.On( "Add", + s.ctx, s.addressToID[s.addresses[2]], toid.New(int32(s.sequence), 2, 1).ToInt64(), uint32(1), @@ -147,6 +152,7 @@ func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulEffectBatchAdds() { ).Return(nil).Once() s.mockBatchInsertBuilder.On( "Add", + s.ctx, s.addressToID[s.addresses[1]], toid.New(int32(s.sequence), 2, 1).ToInt64(), uint32(2), @@ -155,6 +161,7 @@ func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulEffectBatchAdds() { ).Return(nil).Once() s.mockBatchInsertBuilder.On( "Add", + s.ctx, s.addressToID[s.addresses[2]], toid.New(int32(s.sequence), 2, 1).ToInt64(), uint32(3), @@ -164,6 +171,7 @@ func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulEffectBatchAdds() { s.mockBatchInsertBuilder.On( "Add", + s.ctx, s.addressToID[s.addresses[0]], toid.New(int32(s.sequence), 3, 1).ToInt64(), uint32(1), @@ -173,6 +181,7 @@ func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulEffectBatchAdds() { s.mockBatchInsertBuilder.On( "Add", + s.ctx, s.addressToID[s.addresses[0]], toid.New(int32(s.sequence), 3, 1).ToInt64(), uint32(2), @@ -184,16 +193,17 @@ func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulEffectBatchAdds() { func (s *EffectsProcessorTestSuiteLedger) mockSuccessfulCreateAccounts() { s.mockQ.On( "CreateAccounts", + s.ctx, mock.AnythingOfType("[]string"), maxBatchSize, ).Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch(s.addresses, arg) }).Return(s.addressToID, nil).Once() } func (s *EffectsProcessorTestSuiteLedger) TestEmptyEffects() { - err := s.processor.Commit() + err := s.processor.Commit(context.Background()) s.Assert().NoError(err) } @@ -204,25 +214,25 @@ func (s *EffectsProcessorTestSuiteLedger) TestIngestEffectsSucceeds() { s.mockSuccessfulEffectBatchAdds() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().NoError(err) } func (s *EffectsProcessorTestSuiteLedger) TestCreateAccountsFails() { - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Return(s.addressToID, errors.New("transient error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().EqualError(err, "Could not create account ids: transient error") } @@ -232,7 +242,7 @@ func (s *EffectsProcessorTestSuiteLedger) TestBatchAddFails() { Return(s.mockBatchInsertBuilder).Once() s.mockBatchInsertBuilder.On( - "Add", + "Add", s.ctx, s.addressToID[s.addresses[2]], toid.New(int32(s.sequence), 1, 1).ToInt64(), uint32(1), @@ -240,10 +250,10 @@ func (s *EffectsProcessorTestSuiteLedger) TestBatchAddFails() { []byte("{\"new_seq\":300000000000}"), ).Return(errors.New("transient error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().EqualError(err, "could not insert operation effect in db: transient error") } diff --git a/services/horizon/internal/ingest/processors/ledgers_processor.go b/services/horizon/internal/ingest/processors/ledgers_processor.go index e5d846b0e6..01c29b43d9 100644 --- a/services/horizon/internal/ingest/processors/ledgers_processor.go +++ b/services/horizon/internal/ingest/processors/ledgers_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/errors" @@ -29,7 +31,7 @@ func NewLedgerProcessor( } } -func (p *LedgersProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) (err error) { +func (p *LedgersProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) (err error) { opCount := len(transaction.Envelope.Operations()) p.txSetOpCount += opCount if transaction.Result.Successful() { @@ -42,8 +44,8 @@ func (p *LedgersProcessor) ProcessTransaction(transaction ingest.LedgerTransacti return nil } -func (p *LedgersProcessor) Commit() error { - rowsAffected, err := p.ledgersQ.InsertLedger( +func (p *LedgersProcessor) Commit(ctx context.Context) error { + rowsAffected, err := p.ledgersQ.InsertLedger(ctx, p.ledger, p.successTxCount, p.failedTxCount, diff --git a/services/horizon/internal/ingest/processors/ledgers_processor_test.go b/services/horizon/internal/ingest/processors/ledgers_processor_test.go index 67b7b0ae3b..438e269d98 100644 --- a/services/horizon/internal/ingest/processors/ledgers_processor_test.go +++ b/services/horizon/internal/ingest/processors/ledgers_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stellar/go/ingest" @@ -107,8 +108,10 @@ func (s *LedgersProcessorTestSuiteLedger) TearDownTest() { } func (s *LedgersProcessorTestSuiteLedger) TestInsertLedgerSucceeds() { + ctx := context.Background() s.mockQ.On( "InsertLedger", + ctx, s.header, s.successCount, s.failedCount, @@ -118,17 +121,19 @@ func (s *LedgersProcessorTestSuiteLedger) TestInsertLedgerSucceeds() { ).Return(int64(1), nil) for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().NoError(err) } func (s *LedgersProcessorTestSuiteLedger) TestInsertLedgerReturnsError() { + ctx := context.Background() s.mockQ.On( "InsertLedger", + ctx, mock.Anything, mock.Anything, mock.Anything, @@ -137,14 +142,16 @@ func (s *LedgersProcessorTestSuiteLedger) TestInsertLedgerReturnsError() { mock.Anything, ).Return(int64(0), errors.New("transient error")) - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().Error(err) s.Assert().EqualError(err, "Could not insert ledger: transient error") } func (s *LedgersProcessorTestSuiteLedger) TestInsertLedgerNoRowsAffected() { + ctx := context.Background() s.mockQ.On( "InsertLedger", + ctx, mock.Anything, mock.Anything, mock.Anything, @@ -153,7 +160,7 @@ func (s *LedgersProcessorTestSuiteLedger) TestInsertLedgerNoRowsAffected() { mock.Anything, ).Return(int64(0), nil) - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().Error(err) s.Assert().EqualError(err, "0 rows affected when ingesting new ledger: 20") } diff --git a/services/horizon/internal/ingest/processors/mock_change_processor.go b/services/horizon/internal/ingest/processors/mock_change_processor.go index 6df7374aef..6d2ab64a8f 100644 --- a/services/horizon/internal/ingest/processors/mock_change_processor.go +++ b/services/horizon/internal/ingest/processors/mock_change_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stretchr/testify/mock" "github.com/stellar/go/ingest" @@ -12,7 +14,7 @@ type MockChangeProcessor struct { mock.Mock } -func (m *MockChangeProcessor) ProcessChange(change ingest.Change) error { - args := m.Called(change) +func (m *MockChangeProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { + args := m.Called(ctx, change) return args.Error(0) } diff --git a/services/horizon/internal/ingest/processors/offers_processor.go b/services/horizon/internal/ingest/processors/offers_processor.go index 74c55e3f31..5a99d0a24c 100644 --- a/services/horizon/internal/ingest/processors/offers_processor.go +++ b/services/horizon/internal/ingest/processors/offers_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/errors" @@ -32,7 +34,7 @@ func (p *OffersProcessor) reset() { p.removeBatch = []int64{} } -func (p *OffersProcessor) ProcessChange(change ingest.Change) error { +func (p *OffersProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { if change.Type != xdr.LedgerEntryTypeOffer { return nil } @@ -42,7 +44,7 @@ func (p *OffersProcessor) ProcessChange(change ingest.Change) error { } if p.cache.Size() > maxBatchSize { - if err := p.flushCache(); err != nil { + if err := p.flushCache(ctx); err != nil { return errors.Wrap(err, "error in Commit") } p.reset() @@ -68,7 +70,7 @@ func (p *OffersProcessor) ledgerEntryToRow(entry *xdr.LedgerEntry) history.Offer } } -func (p *OffersProcessor) flushCache() error { +func (p *OffersProcessor) flushCache(ctx context.Context) error { changes := p.cache.GetChanges() for _, change := range changes { var rowsAffected int64 @@ -81,7 +83,7 @@ func (p *OffersProcessor) flushCache() error { // Created action = "inserting" row := p.ledgerEntryToRow(change.Post) - err = p.insertBatch.Add(row) + err = p.insertBatch.Add(ctx, row) rowsAffected = 1 // We don't track this when batch inserting case change.Pre != nil && change.Post == nil: // Removed @@ -95,7 +97,7 @@ func (p *OffersProcessor) flushCache() error { offer := change.Post.Data.MustOffer() offerID = offer.OfferId row := p.ledgerEntryToRow(change.Post) - rowsAffected, err = p.offersQ.UpdateOffer(row) + rowsAffected, err = p.offersQ.UpdateOffer(ctx, row) } if err != nil { @@ -112,13 +114,13 @@ func (p *OffersProcessor) flushCache() error { } } - err := p.insertBatch.Exec() + err := p.insertBatch.Exec(ctx) if err != nil { return errors.Wrap(err, "error executing batch") } if len(p.removeBatch) > 0 { - _, err = p.offersQ.RemoveOffers(p.removeBatch, p.sequence) + _, err = p.offersQ.RemoveOffers(ctx, p.removeBatch, p.sequence) if err != nil { return errors.Wrap(err, "error in RemoveOffers") } @@ -127,14 +129,14 @@ func (p *OffersProcessor) flushCache() error { return nil } -func (p *OffersProcessor) Commit() error { - if err := p.flushCache(); err != nil { +func (p *OffersProcessor) Commit(ctx context.Context) error { + if err := p.flushCache(ctx); err != nil { return errors.Wrap(err, "error flushing cache") } if p.sequence > offerCompactionWindow { // trim offers table by removing offers which were deleted before the cutoff ledger - if offerRowsRemoved, err := p.offersQ.CompactOffers(p.sequence - offerCompactionWindow); err != nil { + if offerRowsRemoved, err := p.offersQ.CompactOffers(ctx, p.sequence-offerCompactionWindow); err != nil { return errors.Wrap(err, "could not compact offers") } else { log.WithField("offer_rows_removed", offerRowsRemoved).Info("Trimmed offers table") diff --git a/services/horizon/internal/ingest/processors/offers_processor_test.go b/services/horizon/internal/ingest/processors/offers_processor_test.go index 95135ff703..c49bbaf26a 100644 --- a/services/horizon/internal/ingest/processors/offers_processor_test.go +++ b/services/horizon/internal/ingest/processors/offers_processor_test.go @@ -22,7 +22,7 @@ import ( func TestFuzzOffers(t *testing.T) { tt := test.Start(t) test.ResetHorizonDB(t, tt.HorizonDB) - q := &history.Q{&db.Session{DB: tt.HorizonDB, Ctx: context.Background()}} + q := &history.Q{&db.Session{DB: tt.HorizonDB}} pp := NewOffersProcessor(q, 10) gen := randxdr.NewGenerator() @@ -47,10 +47,10 @@ func TestFuzzOffers(t *testing.T) { } for _, change := range ingest.GetChangesFromLedgerEntryChanges(changes) { - tt.Assert.NoError(pp.ProcessChange(change)) + tt.Assert.NoError(pp.ProcessChange(tt.Ctx, change)) } - tt.Assert.NoError(pp.Commit()) + tt.Assert.NoError(pp.Commit(tt.Ctx)) } func TestOffersProcessorTestSuiteState(t *testing.T) { @@ -59,6 +59,7 @@ func TestOffersProcessorTestSuiteState(t *testing.T) { type OffersProcessorTestSuiteState struct { suite.Suite + ctx context.Context processor *OffersProcessor mockQ *history.MockQOffers mockBatchInsertBuilder *history.MockOffersBatchInsertBuilder @@ -66,6 +67,7 @@ type OffersProcessorTestSuiteState struct { } func (s *OffersProcessorTestSuiteState) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQOffers{} s.mockBatchInsertBuilder = &history.MockOffersBatchInsertBuilder{} @@ -78,9 +80,9 @@ func (s *OffersProcessorTestSuiteState) SetupTest() { } func (s *OffersProcessorTestSuiteState) TearDownTest() { - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.mockQ.On("CompactOffers", s.sequence-100).Return(int64(0), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.mockQ.On("CompactOffers", s.ctx, s.sequence-100).Return(int64(0), nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) s.mockBatchInsertBuilder.AssertExpectations(s.T()) @@ -101,7 +103,7 @@ func (s *OffersProcessorTestSuiteState) TestCreateOffer() { LastModifiedLedgerSeq: lastModifiedLedgerSeq, } - s.mockBatchInsertBuilder.On("Add", history.Offer{ + s.mockBatchInsertBuilder.On("Add", s.ctx, history.Offer{ SellerID: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", OfferID: 1, Pricen: int32(1), @@ -110,7 +112,7 @@ func (s *OffersProcessorTestSuiteState) TestCreateOffer() { LastModifiedLedger: uint32(lastModifiedLedgerSeq), }).Return(nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: nil, Post: &entry, @@ -124,6 +126,7 @@ func TestOffersProcessorTestSuiteLedger(t *testing.T) { type OffersProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *OffersProcessor mockQ *history.MockQOffers mockBatchInsertBuilder *history.MockOffersBatchInsertBuilder @@ -131,6 +134,7 @@ type OffersProcessorTestSuiteLedger struct { } func (s *OffersProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQOffers{} s.mockBatchInsertBuilder = &history.MockOffersBatchInsertBuilder{} @@ -149,7 +153,7 @@ func (s *OffersProcessorTestSuiteLedger) TearDownTest() { func (s *OffersProcessorTestSuiteLedger) setupInsertOffer() { // should be ignored because it's not an offer type - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -172,7 +176,7 @@ func (s *OffersProcessorTestSuiteLedger) setupInsertOffer() { } lastModifiedLedgerSeq := xdr.Uint32(1234) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: nil, Post: &xdr.LedgerEntry{ @@ -199,7 +203,7 @@ func (s *OffersProcessorTestSuiteLedger) setupInsertOffer() { }, } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -213,7 +217,7 @@ func (s *OffersProcessorTestSuiteLedger) setupInsertOffer() { s.Assert().NoError(err) // We use LedgerEntryChangesCache so all changes are squashed - s.mockBatchInsertBuilder.On("Add", history.Offer{ + s.mockBatchInsertBuilder.On("Add", s.ctx, history.Offer{ SellerID: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", OfferID: 2, Pricen: int32(1), @@ -222,32 +226,32 @@ func (s *OffersProcessorTestSuiteLedger) setupInsertOffer() { LastModifiedLedger: uint32(lastModifiedLedgerSeq), }).Return(nil).Once() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() } func (s *OffersProcessorTestSuiteLedger) TestInsertOffer() { s.setupInsertOffer() - s.mockQ.On("CompactOffers", s.sequence-100).Return(int64(0), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockQ.On("CompactOffers", s.ctx, s.sequence-100).Return(int64(0), nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *OffersProcessorTestSuiteLedger) TestSkipCompactionIfSequenceEqualsWindow() { s.processor.sequence = offerCompactionWindow s.setupInsertOffer() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *OffersProcessorTestSuiteLedger) TestSkipCompactionIfSequenceLessThanWindow() { s.processor.sequence = offerCompactionWindow - 1 s.setupInsertOffer() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *OffersProcessorTestSuiteLedger) TestCompactionError() { s.setupInsertOffer() - s.mockQ.On("CompactOffers", s.sequence-100). + s.mockQ.On("CompactOffers", s.ctx, s.sequence-100). Return(int64(0), errors.New("compaction error")).Once() - s.Assert().EqualError(s.processor.Commit(), "could not compact offers: compaction error") + s.Assert().EqualError(s.processor.Commit(s.ctx), "could not compact offers: compaction error") } func (s *OffersProcessorTestSuiteLedger) TestUpdateOfferNoRowsAffected() { @@ -272,7 +276,7 @@ func (s *OffersProcessorTestSuiteLedger) TestUpdateOfferNoRowsAffected() { }, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -285,7 +289,7 @@ func (s *OffersProcessorTestSuiteLedger) TestUpdateOfferNoRowsAffected() { }) s.Assert().NoError(err) - s.mockQ.On("UpdateOffer", history.Offer{ + s.mockQ.On("UpdateOffer", s.ctx, history.Offer{ SellerID: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", OfferID: 2, Pricen: int32(1), @@ -294,14 +298,14 @@ func (s *OffersProcessorTestSuiteLedger) TestUpdateOfferNoRowsAffected() { LastModifiedLedger: uint32(lastModifiedLedgerSeq), }).Return(int64(0), nil).Once() - err = s.processor.Commit() + err = s.processor.Commit(s.ctx) s.Assert().Error(err) s.Assert().IsType(ingest.StateError{}, errors.Cause(err)) s.Assert().EqualError(err, "error flushing cache: 0 rows affected when updating offer 2") } func (s *OffersProcessorTestSuiteLedger) TestRemoveOffer() { - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -317,11 +321,11 @@ func (s *OffersProcessorTestSuiteLedger) TestRemoveOffer() { }) s.Assert().NoError(err) - s.mockQ.On("RemoveOffers", []int64{3}, s.sequence).Return(int64(1), nil).Once() + s.mockQ.On("RemoveOffers", s.ctx, []int64{3}, s.sequence).Return(int64(1), nil).Once() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.mockQ.On("CompactOffers", s.sequence-100).Return(int64(0), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.mockQ.On("CompactOffers", s.ctx, s.sequence-100).Return(int64(0), nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *OffersProcessorTestSuiteLedger) TestProcessUpgradeChange() { @@ -333,7 +337,7 @@ func (s *OffersProcessorTestSuiteLedger) TestProcessUpgradeChange() { } lastModifiedLedgerSeq := xdr.Uint32(1234) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Post: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -359,7 +363,7 @@ func (s *OffersProcessorTestSuiteLedger) TestProcessUpgradeChange() { }, } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -373,7 +377,7 @@ func (s *OffersProcessorTestSuiteLedger) TestProcessUpgradeChange() { s.Assert().NoError(err) // We use LedgerEntryChangesCache so all changes are squashed - s.mockBatchInsertBuilder.On("Add", history.Offer{ + s.mockBatchInsertBuilder.On("Add", s.ctx, history.Offer{ SellerID: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", OfferID: 2, Pricen: int32(1), @@ -382,13 +386,13 @@ func (s *OffersProcessorTestSuiteLedger) TestProcessUpgradeChange() { LastModifiedLedger: uint32(lastModifiedLedgerSeq), }).Return(nil).Once() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.mockQ.On("CompactOffers", s.sequence-100).Return(int64(0), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.mockQ.On("CompactOffers", s.ctx, s.sequence-100).Return(int64(0), nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *OffersProcessorTestSuiteLedger) TestRemoveMultipleOffers() { - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -404,7 +408,7 @@ func (s *OffersProcessorTestSuiteLedger) TestRemoveMultipleOffers() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeOffer, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -420,14 +424,14 @@ func (s *OffersProcessorTestSuiteLedger) TestRemoveMultipleOffers() { }) s.Assert().NoError(err) - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.mockQ.On("CompactOffers", s.sequence-100).Return(int64(0), nil).Once() - s.mockQ.On("RemoveOffers", mock.Anything, s.sequence).Run(func(args mock.Arguments) { + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.mockQ.On("CompactOffers", s.ctx, s.sequence-100).Return(int64(0), nil).Once() + s.mockQ.On("RemoveOffers", s.ctx, mock.Anything, s.sequence).Run(func(args mock.Arguments) { // To fix order issue due to using ChangeCompactor - ids := args.Get(0).([]int64) + ids := args.Get(1).([]int64) s.Assert().ElementsMatch(ids, []int64{3, 4}) }).Return(int64(0), nil).Once() - err = s.processor.Commit() + err = s.processor.Commit(s.ctx) s.Assert().NoError(err) } diff --git a/services/horizon/internal/ingest/processors/operations_processor.go b/services/horizon/internal/ingest/processors/operations_processor.go index 31aa39d7fe..ba9fa3ede6 100644 --- a/services/horizon/internal/ingest/processors/operations_processor.go +++ b/services/horizon/internal/ingest/processors/operations_processor.go @@ -1,6 +1,7 @@ package processors import ( + "context" "encoding/base64" "encoding/json" "fmt" @@ -30,7 +31,7 @@ func NewOperationProcessor(operationsQ history.QOperations, sequence uint32) *Op } // ProcessTransaction process the given transaction -func (p *OperationProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) error { +func (p *OperationProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) error { for i, op := range transaction.Envelope.Operations() { operation := transactionOperationWrapper{ index: uint32(i), @@ -48,7 +49,7 @@ func (p *OperationProcessor) ProcessTransaction(transaction ingest.LedgerTransac return errors.Wrapf(err, "Error marshaling details for operation %v", operation.ID()) } - if err := p.batch.Add( + if err := p.batch.Add(ctx, operation.ID(), operation.TransactionID(), operation.Order(), @@ -63,8 +64,8 @@ func (p *OperationProcessor) ProcessTransaction(transaction ingest.LedgerTransac return nil } -func (p *OperationProcessor) Commit() error { - return p.batch.Exec() +func (p *OperationProcessor) Commit(ctx context.Context) error { + return p.batch.Exec(ctx) } // transactionOperationWrapper represents the data for a single operation within a transaction diff --git a/services/horizon/internal/ingest/processors/operations_processor_test.go b/services/horizon/internal/ingest/processors/operations_processor_test.go index 332138936a..23a9e0e65c 100644 --- a/services/horizon/internal/ingest/processors/operations_processor_test.go +++ b/services/horizon/internal/ingest/processors/operations_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "encoding/json" "testing" @@ -17,6 +18,7 @@ import ( type OperationsProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *OperationProcessor mockQ *history.MockQOperations mockBatchInsertBuilder *history.MockOperationsBatchInsertBuilder @@ -27,6 +29,7 @@ func TestOperationProcessorTestSuiteLedger(t *testing.T) { } func (s *OperationsProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQOperations{} s.mockBatchInsertBuilder = &history.MockOperationsBatchInsertBuilder{} s.mockQ. @@ -64,6 +67,7 @@ func (s *OperationsProcessorTestSuiteLedger) mockBatchInsertAdds(txs []ingest.Le s.mockBatchInsertBuilder.On( "Add", + s.ctx, expected.ID(), expected.TransactionID(), expected.Order(), @@ -110,11 +114,11 @@ func (s *OperationsProcessorTestSuiteLedger) TestAddOperationSucceeds() { err = s.mockBatchInsertAdds(txs, uint32(56)) s.Assert().NoError(err) - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) for _, tx := range txs { - err = s.processor.ProcessTransaction(tx) + err = s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } } @@ -124,7 +128,7 @@ func (s *OperationsProcessorTestSuiteLedger) TestAddOperationFails() { s.mockBatchInsertBuilder. On( - "Add", + "Add", s.ctx, mock.Anything, mock.Anything, mock.Anything, @@ -133,14 +137,14 @@ func (s *OperationsProcessorTestSuiteLedger) TestAddOperationFails() { mock.Anything, ).Return(errors.New("transient error")).Once() - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().Error(err) s.Assert().EqualError(err, "Error batch inserting operation rows: transient error") } func (s *OperationsProcessorTestSuiteLedger) TestExecFails() { - s.mockBatchInsertBuilder.On("Exec").Return(errors.New("transient error")).Once() - err := s.processor.Commit() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(errors.New("transient error")).Once() + err := s.processor.Commit(s.ctx) s.Assert().Error(err) s.Assert().EqualError(err, "transient error") } diff --git a/services/horizon/internal/ingest/processors/participants_processor.go b/services/horizon/internal/ingest/processors/participants_processor.go index 8e17bfe9aa..8b285bb91d 100644 --- a/services/horizon/internal/ingest/processors/participants_processor.go +++ b/services/horizon/internal/ingest/processors/participants_processor.go @@ -3,6 +3,7 @@ package processors import ( + "context" "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/toid" @@ -46,13 +47,13 @@ func (p *participant) addOperationID(id int64) { p.operationSet[id] = struct{}{} } -func (p *ParticipantsProcessor) loadAccountIDs(participantSet map[string]participant) error { +func (p *ParticipantsProcessor) loadAccountIDs(ctx context.Context, participantSet map[string]participant) error { addresses := make([]string, 0, len(participantSet)) for address := range participantSet { addresses = append(addresses, address) } - addressToID, err := p.participantsQ.CreateAccounts(addresses, maxBatchSize) + addressToID, err := p.participantsQ.CreateAccounts(ctx, addresses, maxBatchSize) if err != nil { return errors.Wrap(err, "Could not create account ids") } @@ -226,41 +227,41 @@ func (p *ParticipantsProcessor) addOperationsParticipants( return nil } -func (p *ParticipantsProcessor) insertDBTransactionParticipants(participantSet map[string]participant) error { +func (p *ParticipantsProcessor) insertDBTransactionParticipants(ctx context.Context, participantSet map[string]participant) error { batch := p.participantsQ.NewTransactionParticipantsBatchInsertBuilder(maxBatchSize) for _, entry := range participantSet { for transactionID := range entry.transactionSet { - if err := batch.Add(transactionID, entry.accountID); err != nil { + if err := batch.Add(ctx, transactionID, entry.accountID); err != nil { return errors.Wrap(err, "Could not insert transaction participant in db") } } } - if err := batch.Exec(); err != nil { + if err := batch.Exec(ctx); err != nil { return errors.Wrap(err, "Could not flush transaction participants to db") } return nil } -func (p *ParticipantsProcessor) insertDBOperationsParticipants(participantSet map[string]participant) error { +func (p *ParticipantsProcessor) insertDBOperationsParticipants(ctx context.Context, participantSet map[string]participant) error { batch := p.participantsQ.NewOperationParticipantBatchInsertBuilder(maxBatchSize) for _, entry := range participantSet { for operationID := range entry.operationSet { - if err := batch.Add(operationID, entry.accountID); err != nil { + if err := batch.Add(ctx, operationID, entry.accountID); err != nil { return errors.Wrap(err, "could not insert operation participant in db") } } } - if err := batch.Exec(); err != nil { + if err := batch.Exec(ctx); err != nil { return errors.Wrap(err, "could not flush operation participants to db") } return nil } -func (p *ParticipantsProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) (err error) { +func (p *ParticipantsProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) (err error) { err = p.addTransactionParticipants(p.participantSet, p.sequence, transaction) if err != nil { return err @@ -274,17 +275,17 @@ func (p *ParticipantsProcessor) ProcessTransaction(transaction ingest.LedgerTran return nil } -func (p *ParticipantsProcessor) Commit() (err error) { +func (p *ParticipantsProcessor) Commit(ctx context.Context) (err error) { if len(p.participantSet) > 0 { - if err = p.loadAccountIDs(p.participantSet); err != nil { + if err = p.loadAccountIDs(ctx, p.participantSet); err != nil { return err } - if err = p.insertDBTransactionParticipants(p.participantSet); err != nil { + if err = p.insertDBTransactionParticipants(ctx, p.participantSet); err != nil { return err } - if err = p.insertDBOperationsParticipants(p.participantSet); err != nil { + if err = p.insertDBOperationsParticipants(ctx, p.participantSet); err != nil { return err } } diff --git a/services/horizon/internal/ingest/processors/participants_processor_test.go b/services/horizon/internal/ingest/processors/participants_processor_test.go index a816c1ce5f..cf6fcc5f6d 100644 --- a/services/horizon/internal/ingest/processors/participants_processor_test.go +++ b/services/horizon/internal/ingest/processors/participants_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stretchr/testify/mock" @@ -17,6 +18,7 @@ import ( type ParticipantsProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *ParticipantsProcessor mockQ *history.MockQParticipants mockBatchInsertBuilder *history.MockTransactionParticipantsBatchInsertBuilder @@ -38,6 +40,7 @@ func TestParticipantsProcessorTestSuiteLedger(t *testing.T) { } func (s *ParticipantsProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQParticipants{} s.mockBatchInsertBuilder = &history.MockTransactionParticipantsBatchInsertBuilder{} s.mockOperationsBatchInsertBuilder = &history.MockOperationParticipantBatchInsertBuilder{} @@ -99,37 +102,37 @@ func (s *ParticipantsProcessorTestSuiteLedger) TearDownTest() { func (s *ParticipantsProcessorTestSuiteLedger) mockSuccessfulTransactionBatchAdds() { s.mockBatchInsertBuilder.On( - "Add", s.firstTxID, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.firstTxID, s.addressToID[s.addresses[0]], ).Return(nil).Once() s.mockBatchInsertBuilder.On( - "Add", s.secondTxID, s.addressToID[s.addresses[1]], + "Add", s.ctx, s.secondTxID, s.addressToID[s.addresses[1]], ).Return(nil).Once() s.mockBatchInsertBuilder.On( - "Add", s.secondTxID, s.addressToID[s.addresses[2]], + "Add", s.ctx, s.secondTxID, s.addressToID[s.addresses[2]], ).Return(nil).Once() s.mockBatchInsertBuilder.On( - "Add", s.thirdTxID, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.thirdTxID, s.addressToID[s.addresses[0]], ).Return(nil).Once() } func (s *ParticipantsProcessorTestSuiteLedger) mockSuccessfulOperationBatchAdds() { s.mockOperationsBatchInsertBuilder.On( - "Add", s.firstTxID+1, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.firstTxID+1, s.addressToID[s.addresses[0]], ).Return(nil).Once() s.mockOperationsBatchInsertBuilder.On( - "Add", s.secondTxID+1, s.addressToID[s.addresses[1]], + "Add", s.ctx, s.secondTxID+1, s.addressToID[s.addresses[1]], ).Return(nil).Once() s.mockOperationsBatchInsertBuilder.On( - "Add", s.secondTxID+1, s.addressToID[s.addresses[2]], + "Add", s.ctx, s.secondTxID+1, s.addressToID[s.addresses[2]], ).Return(nil).Once() s.mockOperationsBatchInsertBuilder.On( - "Add", s.thirdTxID+1, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.thirdTxID+1, s.addressToID[s.addresses[0]], ).Return(nil).Once() } func (s *ParticipantsProcessorTestSuiteLedger) TestEmptyParticipants() { - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().NoError(err) } @@ -168,9 +171,9 @@ func (s *ParticipantsProcessorTestSuiteLedger) TestFeeBumptransaction() { addresses[0]: s.addressToID[addresses[0]], addresses[1]: s.addressToID[addresses[1]], } - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( addresses, arg, @@ -182,23 +185,23 @@ func (s *ParticipantsProcessorTestSuiteLedger) TestFeeBumptransaction() { Return(s.mockOperationsBatchInsertBuilder).Once() s.mockBatchInsertBuilder.On( - "Add", feeBumpTxID, addressToID[addresses[0]], + "Add", s.ctx, feeBumpTxID, addressToID[addresses[0]], ).Return(nil).Once() s.mockBatchInsertBuilder.On( - "Add", feeBumpTxID, addressToID[addresses[1]], + "Add", s.ctx, feeBumpTxID, addressToID[addresses[1]], ).Return(nil).Once() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.mockOperationsBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.mockOperationsBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() - s.Assert().NoError(s.processor.ProcessTransaction(feeBumpTx)) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.ProcessTransaction(s.ctx, feeBumpTx)) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *ParticipantsProcessorTestSuiteLedger) TestIngestParticipantsSucceeds() { - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( s.addresses, arg, @@ -212,32 +215,32 @@ func (s *ParticipantsProcessorTestSuiteLedger) TestIngestParticipantsSucceeds() s.mockSuccessfulTransactionBatchAdds() s.mockSuccessfulOperationBatchAdds() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.mockOperationsBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.mockOperationsBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().NoError(err) } func (s *ParticipantsProcessorTestSuiteLedger) TestCreateAccountsFails() { - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Return(s.addressToID, errors.New("transient error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().EqualError(err, "Could not create account ids: transient error") } func (s *ParticipantsProcessorTestSuiteLedger) TestBatchAddFails() { - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( s.addresses, arg, @@ -247,31 +250,31 @@ func (s *ParticipantsProcessorTestSuiteLedger) TestBatchAddFails() { Return(s.mockBatchInsertBuilder).Once() s.mockBatchInsertBuilder.On( - "Add", s.firstTxID, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.firstTxID, s.addressToID[s.addresses[0]], ).Return(errors.New("transient error")).Once() s.mockBatchInsertBuilder.On( - "Add", s.secondTxID, s.addressToID[s.addresses[1]], + "Add", s.ctx, s.secondTxID, s.addressToID[s.addresses[1]], ).Return(nil).Maybe() s.mockBatchInsertBuilder.On( - "Add", s.secondTxID, s.addressToID[s.addresses[2]], + "Add", s.ctx, s.secondTxID, s.addressToID[s.addresses[2]], ).Return(nil).Maybe() s.mockBatchInsertBuilder.On( - "Add", s.thirdTxID, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.thirdTxID, s.addressToID[s.addresses[0]], ).Return(nil).Maybe() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().EqualError(err, "Could not insert transaction participant in db: transient error") } func (s *ParticipantsProcessorTestSuiteLedger) TestOperationParticipantsBatchAddFails() { - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( s.addresses, arg, @@ -285,32 +288,32 @@ func (s *ParticipantsProcessorTestSuiteLedger) TestOperationParticipantsBatchAdd s.mockSuccessfulTransactionBatchAdds() s.mockOperationsBatchInsertBuilder.On( - "Add", s.firstTxID+1, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.firstTxID+1, s.addressToID[s.addresses[0]], ).Return(errors.New("transient error")).Once() s.mockOperationsBatchInsertBuilder.On( - "Add", s.secondTxID+1, s.addressToID[s.addresses[1]], + "Add", s.ctx, s.secondTxID+1, s.addressToID[s.addresses[1]], ).Return(nil).Maybe() s.mockOperationsBatchInsertBuilder.On( - "Add", s.secondTxID+1, s.addressToID[s.addresses[2]], + "Add", s.ctx, s.secondTxID+1, s.addressToID[s.addresses[2]], ).Return(nil).Maybe() s.mockOperationsBatchInsertBuilder.On( - "Add", s.thirdTxID+1, s.addressToID[s.addresses[0]], + "Add", s.ctx, s.thirdTxID+1, s.addressToID[s.addresses[0]], ).Return(nil).Maybe() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().EqualError(err, "could not insert operation participant in db: transient error") } func (s *ParticipantsProcessorTestSuiteLedger) TestBatchAddExecFails() { - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( s.addresses, arg, @@ -321,20 +324,20 @@ func (s *ParticipantsProcessorTestSuiteLedger) TestBatchAddExecFails() { s.mockSuccessfulTransactionBatchAdds() - s.mockBatchInsertBuilder.On("Exec").Return(errors.New("transient error")).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(errors.New("transient error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().EqualError(err, "Could not flush transaction participants to db: transient error") } func (s *ParticipantsProcessorTestSuiteLedger) TestOpeartionBatchAddExecFails() { - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", s.ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( s.addresses, arg, @@ -348,13 +351,13 @@ func (s *ParticipantsProcessorTestSuiteLedger) TestOpeartionBatchAddExecFails() s.mockSuccessfulTransactionBatchAdds() s.mockSuccessfulOperationBatchAdds() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.mockOperationsBatchInsertBuilder.On("Exec").Return(errors.New("transient error")).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.mockOperationsBatchInsertBuilder.On("Exec", s.ctx).Return(errors.New("transient error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(s.ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(s.ctx) s.Assert().EqualError(err, "could not flush operation participants to db: transient error") } diff --git a/services/horizon/internal/ingest/processors/signer_processor_test.go b/services/horizon/internal/ingest/processors/signer_processor_test.go index 79abbc260b..de5c70bddc 100644 --- a/services/horizon/internal/ingest/processors/signer_processor_test.go +++ b/services/horizon/internal/ingest/processors/signer_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/guregu/null" @@ -20,12 +21,14 @@ func TestAccountsSignerProcessorTestSuiteState(t *testing.T) { type AccountsSignerProcessorTestSuiteState struct { suite.Suite + ctx context.Context processor *SignersProcessor mockQ *history.MockQSigners mockBatchInsertBuilder *history.MockAccountSignersBatchInsertBuilder } func (s *AccountsSignerProcessorTestSuiteState) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQSigners{} s.mockBatchInsertBuilder = &history.MockAccountSignersBatchInsertBuilder{} @@ -37,8 +40,8 @@ func (s *AccountsSignerProcessorTestSuiteState) SetupTest() { } func (s *AccountsSignerProcessorTestSuiteState) TearDownTest() { - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) s.mockBatchInsertBuilder.AssertExpectations(s.T()) @@ -50,13 +53,13 @@ func (s *AccountsSignerProcessorTestSuiteState) TestNoEntries() { func (s *AccountsSignerProcessorTestSuiteState) TestCreatesSigners() { s.mockBatchInsertBuilder. - On("Add", history.AccountSigner{ + On("Add", s.ctx, history.AccountSigner{ Account: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", Signer: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", Weight: int32(1), }).Return(nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -72,13 +75,13 @@ func (s *AccountsSignerProcessorTestSuiteState) TestCreatesSigners() { s.Assert().NoError(err) s.mockBatchInsertBuilder. - On("Add", history.AccountSigner{ + On("Add", s.ctx, history.AccountSigner{ Account: "GCCCU34WDY2RATQTOOQKY6SZWU6J5DONY42SWGW2CIXGW4LICAGNRZKX", Signer: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", Weight: int32(10), }).Return(nil).Once() - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -102,7 +105,7 @@ func (s *AccountsSignerProcessorTestSuiteState) TestCreatesSigners() { func (s *AccountsSignerProcessorTestSuiteState) TestCreatesSignerWithSponsor() { s.mockBatchInsertBuilder. - On("Add", history.AccountSigner{ + On("Add", s.ctx, history.AccountSigner{ Account: "GCCCU34WDY2RATQTOOQKY6SZWU6J5DONY42SWGW2CIXGW4LICAGNRZKX", Signer: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", Weight: int32(10), @@ -111,7 +114,7 @@ func (s *AccountsSignerProcessorTestSuiteState) TestCreatesSignerWithSponsor() { sponsorshipDescriptor := xdr.MustAddress("GDWZ6MKJP5ESVIB7O5RW4UFFGSCDILPEKDXWGG4HXXSHEZZPTKLR6UVG") - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -153,11 +156,13 @@ func TestAccountsSignerProcessorTestSuiteLedger(t *testing.T) { type AccountsSignerProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *SignersProcessor mockQ *history.MockQSigners } func (s *AccountsSignerProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQSigners{} s.mockQ. On("NewAccountSignersBatchInsertBuilder", maxBatchSize). @@ -172,13 +177,14 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TearDownTest() { func (s *AccountsSignerProcessorTestSuiteLedger) TestNoTransactions() { // Nothing processed, assertions in TearDownTest. - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(context.Background())) } func (s *AccountsSignerProcessorTestSuiteLedger) TestNewAccount() { s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", int32(1), @@ -186,7 +192,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewAccount() { ). Return(int64(1), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -200,11 +206,11 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewAccount() { }, }) s.Assert().NoError(err) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AccountsSignerProcessorTestSuiteLedger) TestNoUpdatesWhenNoSignerChanges() { - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -226,7 +232,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNoUpdatesWhenNoSignerChange }, }) s.Assert().NoError(err) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AccountsSignerProcessorTestSuiteLedger) TestNewSigner() { @@ -234,6 +240,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewSigner() { s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCBBDQLCTNASZJ3MTKAOYEOWRGSHDFAJVI7VPZUOP7KXNHYR3HP2BUKV", ). @@ -243,6 +250,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewSigner() { s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCBBDQLCTNASZJ3MTKAOYEOWRGSHDFAJVI7VPZUOP7KXNHYR3HP2BUKV", int32(10), @@ -253,6 +261,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewSigner() { s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCAHY6JSXQFKWKP6R7U5JPXDVNV4DJWOWRFLY3Y6YPBF64QRL4BPFDNS", int32(15), @@ -260,7 +269,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewSigner() { ). Return(int64(1), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -296,7 +305,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewSigner() { }, }) s.Assert().NoError(err) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerRemoved() { @@ -304,6 +313,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerRemoved() { s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCBBDQLCTNASZJ3MTKAOYEOWRGSHDFAJVI7VPZUOP7KXNHYR3HP2BUKV", ). @@ -312,6 +322,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerRemoved() { s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCAHY6JSXQFKWKP6R7U5JPXDVNV4DJWOWRFLY3Y6YPBF64QRL4BPFDNS", ). @@ -321,6 +332,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerRemoved() { s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCAHY6JSXQFKWKP6R7U5JPXDVNV4DJWOWRFLY3Y6YPBF64QRL4BPFDNS", int32(15), @@ -328,7 +340,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerRemoved() { ). Return(int64(1), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -364,7 +376,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerRemoved() { }, }) s.Assert().NoError(err) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } // TestSignerPreAuthTxRemovedTxFailed tests if removing preauthorized transaction @@ -374,6 +386,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerPreAuthTxRemovedTxFai s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCBBDQLCTNASZJ3MTKAOYEOWRGSHDFAJVI7VPZUOP7KXNHYR3HP2BUKV", ). @@ -382,6 +395,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerPreAuthTxRemovedTxFai s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "TBU2RRGLXH3E5CQHTD3ODLDF2BWDCYUSSBLLZ5GNW7JXHDIYKXZWHXL7", ). @@ -391,6 +405,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerPreAuthTxRemovedTxFai s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCBBDQLCTNASZJ3MTKAOYEOWRGSHDFAJVI7VPZUOP7KXNHYR3HP2BUKV", int32(10), @@ -398,7 +413,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerPreAuthTxRemovedTxFai ). Return(int64(1), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -434,19 +449,20 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestSignerPreAuthTxRemovedTxFai }, }) s.Assert().NoError(err) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AccountsSignerProcessorTestSuiteLedger) TestRemoveAccount() { s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", ). Return(int64(1), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -460,13 +476,14 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestRemoveAccount() { Post: nil, }) s.Assert().NoError(err) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *AccountsSignerProcessorTestSuiteLedger) TestNewAccountNoRowsAffected() { s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", int32(1), @@ -474,7 +491,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewAccountNoRowsAffected() ). Return(int64(0), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -489,7 +506,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestNewAccountNoRowsAffected() }) s.Assert().NoError(err) - err = s.processor.Commit() + err = s.processor.Commit(s.ctx) s.Assert().Error(err) s.Assert().IsType(ingest.StateError{}, errors.Cause(err)) s.Assert().EqualError( @@ -504,12 +521,13 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestRemoveAccountNoRowsAffected s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", ). Return(int64(0), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -524,7 +542,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestRemoveAccountNoRowsAffected }) s.Assert().NoError(err) - err = s.processor.Commit() + err = s.processor.Commit(s.ctx) s.Assert().Error(err) s.Assert().IsType(ingest.StateError{}, errors.Cause(err)) s.Assert().EqualError( @@ -541,6 +559,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestProcessUpgradeChange() { s.mockQ. On( "RemoveAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCBBDQLCTNASZJ3MTKAOYEOWRGSHDFAJVI7VPZUOP7KXNHYR3HP2BUKV", ). @@ -550,6 +569,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestProcessUpgradeChange() { s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCBBDQLCTNASZJ3MTKAOYEOWRGSHDFAJVI7VPZUOP7KXNHYR3HP2BUKV", int32(12), @@ -560,6 +580,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestProcessUpgradeChange() { s.mockQ. On( "CreateAccountSigner", + s.ctx, "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", "GCAHY6JSXQFKWKP6R7U5JPXDVNV4DJWOWRFLY3Y6YPBF64QRL4BPFDNS", int32(15), @@ -567,7 +588,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestProcessUpgradeChange() { ). Return(int64(1), nil).Once() - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -604,7 +625,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestProcessUpgradeChange() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: 1000, @@ -642,7 +663,7 @@ func (s *AccountsSignerProcessorTestSuiteLedger) TestProcessUpgradeChange() { }, }) s.Assert().NoError(err) - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func createTransactionMeta(opMeta []xdr.OperationMeta) xdr.TransactionMeta { diff --git a/services/horizon/internal/ingest/processors/signers_processor.go b/services/horizon/internal/ingest/processors/signers_processor.go index 0be39ba84e..77fe54ebc2 100644 --- a/services/horizon/internal/ingest/processors/signers_processor.go +++ b/services/horizon/internal/ingest/processors/signers_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/guregu/null" "github.com/stellar/go/ingest" @@ -33,7 +35,7 @@ func (p *SignersProcessor) reset() { p.cache = ingest.NewChangeCompactor() } -func (p *SignersProcessor) ProcessChange(change ingest.Change) error { +func (p *SignersProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { if change.Type != xdr.LedgerEntryTypeAccount { return nil } @@ -45,7 +47,7 @@ func (p *SignersProcessor) ProcessChange(change ingest.Change) error { } if p.cache.Size() > maxBatchSize { - err = p.Commit() + err = p.Commit(ctx) if err != nil { return errors.Wrap(err, "error in Commit") } @@ -69,7 +71,7 @@ func (p *SignersProcessor) ProcessChange(change ingest.Change) error { sponsor = null.StringFrom(sponsorDesc.Address()) } - err := p.batch.Add(history.AccountSigner{ + err := p.batch.Add(ctx, history.AccountSigner{ Account: account, Signer: signer, Weight: weight, @@ -83,9 +85,9 @@ func (p *SignersProcessor) ProcessChange(change ingest.Change) error { return nil } -func (p *SignersProcessor) Commit() error { +func (p *SignersProcessor) Commit(ctx context.Context) error { if !p.useLedgerEntryCache { - return p.batch.Exec() + return p.batch.Exec(ctx) } changes := p.cache.GetChanges() @@ -99,7 +101,7 @@ func (p *SignersProcessor) Commit() error { if change.Pre != nil { preAccountEntry := change.Pre.Data.MustAccount() for signer := range preAccountEntry.SignerSummary() { - rowsAffected, err := p.signersQ.RemoveAccountSigner(preAccountEntry.AccountId.Address(), signer) + rowsAffected, err := p.signersQ.RemoveAccountSigner(ctx, preAccountEntry.AccountId.Address(), signer) if err != nil { return errors.Wrap(err, "Error removing a signer") } @@ -129,7 +131,7 @@ func (p *SignersProcessor) Commit() error { } } - rowsAffected, err := p.signersQ.CreateAccountSigner( + rowsAffected, err := p.signersQ.CreateAccountSigner(ctx, postAccountEntry.AccountId.Address(), signer, weight, diff --git a/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor.go b/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor.go index 1839203b87..999d31e7e9 100644 --- a/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor.go +++ b/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor.go @@ -1,6 +1,7 @@ package processors import ( + "context" "fmt" "github.com/stellar/go/ingest" @@ -47,7 +48,7 @@ type StatsLedgerTransactionProcessorResults struct { OperationsSetTrustLineFlags int64 } -func (p *StatsLedgerTransactionProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) error { +func (p *StatsLedgerTransactionProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) error { p.results.Transactions++ ops := int64(len(transaction.Envelope.Operations())) p.results.Operations += ops diff --git a/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor_test.go b/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor_test.go index 1b83307214..0d6da1e7bd 100644 --- a/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor_test.go +++ b/services/horizon/internal/ingest/processors/stats_ledger_transaction_processor_test.go @@ -1,6 +1,7 @@ package processors import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -13,7 +14,7 @@ func TestStatsLedgerTransactionProcessor(t *testing.T) { processor := &StatsLedgerTransactionProcessor{} // Successful - assert.NoError(t, processor.ProcessTransaction(ingest.LedgerTransaction{ + assert.NoError(t, processor.ProcessTransaction(context.Background(), ingest.LedgerTransaction{ Result: xdr.TransactionResultPair{ Result: xdr.TransactionResult{ Result: xdr.TransactionResultResult{ @@ -54,7 +55,7 @@ func TestStatsLedgerTransactionProcessor(t *testing.T) { })) // Failed - assert.NoError(t, processor.ProcessTransaction(ingest.LedgerTransaction{ + assert.NoError(t, processor.ProcessTransaction(context.Background(), ingest.LedgerTransaction{ Result: xdr.TransactionResultPair{ Result: xdr.TransactionResult{ Result: xdr.TransactionResultResult{ diff --git a/services/horizon/internal/ingest/processors/trades_processor.go b/services/horizon/internal/ingest/processors/trades_processor.go index 8024a240f8..529f3b18c3 100644 --- a/services/horizon/internal/ingest/processors/trades_processor.go +++ b/services/horizon/internal/ingest/processors/trades_processor.go @@ -1,6 +1,7 @@ package processors import ( + "context" "time" "github.com/stellar/go/ingest" @@ -29,7 +30,7 @@ func NewTradeProcessor(tradesQ history.QTrades, ledger xdr.LedgerHeaderHistoryEn } // ProcessTransaction process the given transaction -func (p *TradeProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) (err error) { +func (p *TradeProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) (err error) { if !transaction.Result.Successful() { return nil } @@ -54,16 +55,16 @@ func (p *TradeProcessor) ProcessTransaction(transaction ingest.LedgerTransaction return nil } -func (p *TradeProcessor) Commit() error { +func (p *TradeProcessor) Commit(ctx context.Context) error { if len(p.inserts) > 0 { batch := p.tradesQ.NewTradeBatchInsertBuilder(maxBatchSize) - accountSet, err := p.tradesQ.CreateAccounts(mapKeysToList(p.accountSet), maxBatchSize) + accountSet, err := p.tradesQ.CreateAccounts(ctx, mapKeysToList(p.accountSet), maxBatchSize) if err != nil { return errors.Wrap(err, "Error creating account ids") } var assetMap map[string]history.Asset - assetMap, err = p.tradesQ.CreateAssets(p.assets, maxBatchSize) + assetMap, err = p.tradesQ.CreateAssets(ctx, p.assets, maxBatchSize) if err != nil { return errors.Wrap(err, "Error creating asset ids") } @@ -73,12 +74,12 @@ func (p *TradeProcessor) Commit() error { insert.SellerAccountID = accountSet[insert.Trade.SellerId.Address()] insert.SoldAssetID = assetMap[insert.Trade.AssetSold.String()].ID insert.BoughtAssetID = assetMap[insert.Trade.AssetBought.String()].ID - if err = batch.Add(insert); err != nil { + if err = batch.Add(ctx, insert); err != nil { return errors.Wrap(err, "Error adding trade to batch") } } - if err = batch.Exec(); err != nil { + if err = batch.Exec(ctx); err != nil { return errors.Wrap(err, "Error flushing operation batch") } } diff --git a/services/horizon/internal/ingest/processors/trades_processor_test.go b/services/horizon/internal/ingest/processors/trades_processor_test.go index 5782e893cf..678c94ca45 100644 --- a/services/horizon/internal/ingest/processors/trades_processor_test.go +++ b/services/horizon/internal/ingest/processors/trades_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "fmt" "testing" "time" @@ -156,10 +157,11 @@ func (s *TradeProcessorTestSuiteLedger) TearDownTest() { } func (s *TradeProcessorTestSuiteLedger) TestIgnoreFailedTransactions() { - err := s.processor.ProcessTransaction(createTransaction(false, 1)) + ctx := context.Background() + err := s.processor.ProcessTransaction(ctx, createTransaction(false, 1)) s.Assert().NoError(err) - err = s.processor.Commit() + err = s.processor.Commit(ctx) s.Assert().NoError(err) } @@ -491,20 +493,21 @@ func (s *TradeProcessorTestSuiteLedger) mockReadTradeTransactions( } func (s *TradeProcessorTestSuiteLedger) TestIngestTradesSucceeds() { + ctx := context.Background() inserts := s.mockReadTradeTransactions(s.processor.ledger) - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( mapKeysToList(s.unmuxedAccountToID), arg, ) }).Return(s.unmuxedAccountToID, nil).Once() - s.mockQ.On("CreateAssets", mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). + s.mockQ.On("CreateAssets", ctx, mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.Asset) + arg := args.Get(1).([]xdr.Asset) s.Assert().ElementsMatch( s.assets, arg, @@ -512,28 +515,29 @@ func (s *TradeProcessorTestSuiteLedger) TestIngestTradesSucceeds() { }).Return(s.assetToID, nil).Once() for _, insert := range inserts { - s.mockBatchInsertBuilder.On("Add", []history.InsertTrade{ + s.mockBatchInsertBuilder.On("Add", ctx, []history.InsertTrade{ insert, }).Return(nil).Once() } - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().NoError(err) } func (s *TradeProcessorTestSuiteLedger) TestCreateAccountsError() { + ctx := context.Background() s.mockReadTradeTransactions(s.processor.ledger) - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( mapKeysToList(s.unmuxedAccountToID), arg, @@ -541,30 +545,31 @@ func (s *TradeProcessorTestSuiteLedger) TestCreateAccountsError() { }).Return(map[string]int64{}, fmt.Errorf("create accounts error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().EqualError(err, "Error creating account ids: create accounts error") } func (s *TradeProcessorTestSuiteLedger) TestCreateAssetsError() { + ctx := context.Background() s.mockReadTradeTransactions(s.processor.ledger) - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( mapKeysToList(s.unmuxedAccountToID), arg, ) }).Return(s.unmuxedAccountToID, nil).Once() - s.mockQ.On("CreateAssets", mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). + s.mockQ.On("CreateAssets", ctx, mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.Asset) + arg := args.Get(1).([]xdr.Asset) s.Assert().ElementsMatch( s.assets, arg, @@ -572,111 +577,114 @@ func (s *TradeProcessorTestSuiteLedger) TestCreateAssetsError() { }).Return(s.assetToID, fmt.Errorf("create assets error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().EqualError(err, "Error creating asset ids: create assets error") } func (s *TradeProcessorTestSuiteLedger) TestBatchAddError() { + ctx := context.Background() s.mockReadTradeTransactions(s.processor.ledger) - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( mapKeysToList(s.unmuxedAccountToID), arg, ) }).Return(s.unmuxedAccountToID, nil).Once() - s.mockQ.On("CreateAssets", mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). + s.mockQ.On("CreateAssets", ctx, mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.Asset) + arg := args.Get(1).([]xdr.Asset) s.Assert().ElementsMatch( s.assets, arg, ) }).Return(s.assetToID, nil).Once() - s.mockBatchInsertBuilder.On("Add", mock.AnythingOfType("[]history.InsertTrade")). + s.mockBatchInsertBuilder.On("Add", ctx, mock.AnythingOfType("[]history.InsertTrade")). Return(fmt.Errorf("batch add error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().EqualError(err, "Error adding trade to batch: batch add error") } func (s *TradeProcessorTestSuiteLedger) TestBatchExecError() { + ctx := context.Background() insert := s.mockReadTradeTransactions(s.processor.ledger) - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( mapKeysToList(s.unmuxedAccountToID), arg, ) }).Return(s.unmuxedAccountToID, nil).Once() - s.mockQ.On("CreateAssets", mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). + s.mockQ.On("CreateAssets", ctx, mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.Asset) + arg := args.Get(1).([]xdr.Asset) s.Assert().ElementsMatch( s.assets, arg, ) }).Return(s.assetToID, nil).Once() - s.mockBatchInsertBuilder.On("Add", mock.AnythingOfType("[]history.InsertTrade")). + s.mockBatchInsertBuilder.On("Add", ctx, mock.AnythingOfType("[]history.InsertTrade")). Return(nil).Times(len(insert)) - s.mockBatchInsertBuilder.On("Exec").Return(fmt.Errorf("exec error")).Once() + s.mockBatchInsertBuilder.On("Exec", ctx).Return(fmt.Errorf("exec error")).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().EqualError(err, "Error flushing operation batch: exec error") } func (s *TradeProcessorTestSuiteLedger) TestIgnoreCheckIfSmallLedger() { + ctx := context.Background() insert := s.mockReadTradeTransactions(s.processor.ledger) - s.mockQ.On("CreateAccounts", mock.AnythingOfType("[]string"), maxBatchSize). + s.mockQ.On("CreateAccounts", ctx, mock.AnythingOfType("[]string"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]string) + arg := args.Get(1).([]string) s.Assert().ElementsMatch( mapKeysToList(s.unmuxedAccountToID), arg, ) }).Return(s.unmuxedAccountToID, nil).Once() - s.mockQ.On("CreateAssets", mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). + s.mockQ.On("CreateAssets", ctx, mock.AnythingOfType("[]xdr.Asset"), maxBatchSize). Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.Asset) + arg := args.Get(1).([]xdr.Asset) s.Assert().ElementsMatch( s.assets, arg, ) }).Return(s.assetToID, nil).Once() - s.mockBatchInsertBuilder.On("Add", mock.AnythingOfType("[]history.InsertTrade")). + s.mockBatchInsertBuilder.On("Add", ctx, mock.AnythingOfType("[]history.InsertTrade")). Return(nil).Times(len(insert)) - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", ctx).Return(nil).Once() for _, tx := range s.txs { - err := s.processor.ProcessTransaction(tx) + err := s.processor.ProcessTransaction(ctx, tx) s.Assert().NoError(err) } - err := s.processor.Commit() + err := s.processor.Commit(ctx) s.Assert().NoError(err) } diff --git a/services/horizon/internal/ingest/processors/transactions_processor.go b/services/horizon/internal/ingest/processors/transactions_processor.go index 8ba007bd87..4e47cb96ba 100644 --- a/services/horizon/internal/ingest/processors/transactions_processor.go +++ b/services/horizon/internal/ingest/processors/transactions_processor.go @@ -1,6 +1,7 @@ package processors import ( + "context" "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/errors" @@ -20,16 +21,16 @@ func NewTransactionProcessor(transactionsQ history.QTransactions, sequence uint3 } } -func (p *TransactionProcessor) ProcessTransaction(transaction ingest.LedgerTransaction) error { - if err := p.batch.Add(transaction, p.sequence); err != nil { +func (p *TransactionProcessor) ProcessTransaction(ctx context.Context, transaction ingest.LedgerTransaction) error { + if err := p.batch.Add(ctx, transaction, p.sequence); err != nil { return errors.Wrap(err, "Error batch inserting transaction rows") } return nil } -func (p *TransactionProcessor) Commit() error { - if err := p.batch.Exec(); err != nil { +func (p *TransactionProcessor) Commit(ctx context.Context) error { + if err := p.batch.Exec(ctx); err != nil { return errors.Wrap(err, "Error flushing transaction batch") } diff --git a/services/horizon/internal/ingest/processors/transactions_processor_test.go b/services/horizon/internal/ingest/processors/transactions_processor_test.go index d04aaec44d..ec1cf105e5 100644 --- a/services/horizon/internal/ingest/processors/transactions_processor_test.go +++ b/services/horizon/internal/ingest/processors/transactions_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stellar/go/services/horizon/internal/db2/history" @@ -12,6 +13,7 @@ import ( type TransactionsProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *TransactionProcessor mockQ *history.MockQTransactions mockBatchInsertBuilder *history.MockTransactionsBatchInsertBuilder @@ -22,6 +24,7 @@ func TestTransactionsProcessorTestSuiteLedger(t *testing.T) { } func (s *TransactionsProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQTransactions{} s.mockBatchInsertBuilder = &history.MockTransactionsBatchInsertBuilder{} @@ -44,29 +47,29 @@ func (s *TransactionsProcessorTestSuiteLedger) TestAddTransactionsSucceeds() { secondTx := createTransaction(false, 3) thirdTx := createTransaction(true, 4) - s.mockBatchInsertBuilder.On("Add", firstTx, sequence).Return(nil).Once() - s.mockBatchInsertBuilder.On("Add", secondTx, sequence).Return(nil).Once() - s.mockBatchInsertBuilder.On("Add", thirdTx, sequence).Return(nil).Once() - s.mockBatchInsertBuilder.On("Exec").Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.mockBatchInsertBuilder.On("Add", s.ctx, firstTx, sequence).Return(nil).Once() + s.mockBatchInsertBuilder.On("Add", s.ctx, secondTx, sequence).Return(nil).Once() + s.mockBatchInsertBuilder.On("Add", s.ctx, thirdTx, sequence).Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(nil).Once() + s.Assert().NoError(s.processor.Commit(s.ctx)) - err := s.processor.ProcessTransaction(firstTx) + err := s.processor.ProcessTransaction(s.ctx, firstTx) s.Assert().NoError(err) - err = s.processor.ProcessTransaction(secondTx) + err = s.processor.ProcessTransaction(s.ctx, secondTx) s.Assert().NoError(err) - err = s.processor.ProcessTransaction(thirdTx) + err = s.processor.ProcessTransaction(s.ctx, thirdTx) s.Assert().NoError(err) } func (s *TransactionsProcessorTestSuiteLedger) TestAddTransactionsFails() { sequence := uint32(20) firstTx := createTransaction(true, 1) - s.mockBatchInsertBuilder.On("Add", firstTx, sequence). + s.mockBatchInsertBuilder.On("Add", s.ctx, firstTx, sequence). Return(errors.New("transient error")).Once() - err := s.processor.ProcessTransaction(firstTx) + err := s.processor.ProcessTransaction(s.ctx, firstTx) s.Assert().Error(err) s.Assert().EqualError(err, "Error batch inserting transaction rows: transient error") } @@ -75,13 +78,13 @@ func (s *TransactionsProcessorTestSuiteLedger) TestExecFails() { sequence := uint32(20) firstTx := createTransaction(true, 1) - s.mockBatchInsertBuilder.On("Add", firstTx, sequence).Return(nil).Once() - s.mockBatchInsertBuilder.On("Exec").Return(errors.New("transient error")).Once() + s.mockBatchInsertBuilder.On("Add", s.ctx, firstTx, sequence).Return(nil).Once() + s.mockBatchInsertBuilder.On("Exec", s.ctx).Return(errors.New("transient error")).Once() - err := s.processor.ProcessTransaction(firstTx) + err := s.processor.ProcessTransaction(s.ctx, firstTx) s.Assert().NoError(err) - err = s.processor.Commit() + err = s.processor.Commit(s.ctx) s.Assert().Error(err) s.Assert().EqualError(err, "Error flushing transaction batch: transient error") } diff --git a/services/horizon/internal/ingest/processors/trust_lines_processor.go b/services/horizon/internal/ingest/processors/trust_lines_processor.go index ac1a6b7e45..c97e47e709 100644 --- a/services/horizon/internal/ingest/processors/trust_lines_processor.go +++ b/services/horizon/internal/ingest/processors/trust_lines_processor.go @@ -1,6 +1,8 @@ package processors import ( + "context" + "github.com/stellar/go/ingest" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/errors" @@ -23,7 +25,7 @@ func (p *TrustLinesProcessor) reset() { p.cache = ingest.NewChangeCompactor() } -func (p *TrustLinesProcessor) ProcessChange(change ingest.Change) error { +func (p *TrustLinesProcessor) ProcessChange(ctx context.Context, change ingest.Change) error { if change.Type != xdr.LedgerEntryTypeTrustline { return nil } @@ -34,7 +36,7 @@ func (p *TrustLinesProcessor) ProcessChange(change ingest.Change) error { } if p.cache.Size() > maxBatchSize { - err = p.Commit() + err = p.Commit(ctx) if err != nil { return errors.Wrap(err, "error in Commit") } @@ -44,7 +46,7 @@ func (p *TrustLinesProcessor) ProcessChange(change ingest.Change) error { return nil } -func (p *TrustLinesProcessor) Commit() error { +func (p *TrustLinesProcessor) Commit(ctx context.Context) error { batchUpsertTrustLines := []xdr.LedgerEntry{} changes := p.cache.GetChanges() @@ -66,7 +68,7 @@ func (p *TrustLinesProcessor) Commit() error { if err != nil { return errors.Wrap(err, "Error creating ledger key") } - rowsAffected, err = p.trustLinesQ.RemoveTrustLine(*ledgerKey.TrustLine) + rowsAffected, err = p.trustLinesQ.RemoveTrustLine(ctx, *ledgerKey.TrustLine) if err != nil { return err } @@ -87,7 +89,7 @@ func (p *TrustLinesProcessor) Commit() error { // Upsert accounts if len(batchUpsertTrustLines) > 0 { - err := p.trustLinesQ.UpsertTrustLines(batchUpsertTrustLines) + err := p.trustLinesQ.UpsertTrustLines(ctx, batchUpsertTrustLines) if err != nil { return errors.Wrap(err, "errors in UpsertTrustLines") } diff --git a/services/horizon/internal/ingest/processors/trust_lines_processor_test.go b/services/horizon/internal/ingest/processors/trust_lines_processor_test.go index 98b3f6b5ed..2ca13189d2 100644 --- a/services/horizon/internal/ingest/processors/trust_lines_processor_test.go +++ b/services/horizon/internal/ingest/processors/trust_lines_processor_test.go @@ -3,6 +3,7 @@ package processors import ( + "context" "testing" "github.com/stretchr/testify/mock" @@ -22,17 +23,19 @@ func TestTrustLinesProcessorTestSuiteState(t *testing.T) { type TrustLinesProcessorTestSuiteState struct { suite.Suite + ctx context.Context processor *TrustLinesProcessor mockQ *history.MockQTrustLines } func (s *TrustLinesProcessorTestSuiteState) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQTrustLines{} s.processor = NewTrustLinesProcessor(s.mockQ) } func (s *TrustLinesProcessorTestSuiteState) TearDownTest() { - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) s.mockQ.AssertExpectations(s.T()) } @@ -44,7 +47,7 @@ func (s *TrustLinesProcessorTestSuiteState) TestCreateTrustLine() { } lastModifiedLedgerSeq := xdr.Uint32(123) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -59,6 +62,7 @@ func (s *TrustLinesProcessorTestSuiteState) TestCreateTrustLine() { s.mockQ.On( "UpsertTrustLines", + s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -77,7 +81,7 @@ func (s *TrustLinesProcessorTestSuiteState) TestCreateTrustLineUnauthorized() { Asset: xdr.MustNewCreditAsset("EUR", trustLineIssuer.Address()), } lastModifiedLedgerSeq := xdr.Uint32(123) - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -92,6 +96,7 @@ func (s *TrustLinesProcessorTestSuiteState) TestCreateTrustLineUnauthorized() { s.mockQ.On( "UpsertTrustLines", + s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -110,11 +115,13 @@ func TestTrustLinesProcessorTestSuiteLedger(t *testing.T) { type TrustLinesProcessorTestSuiteLedger struct { suite.Suite + ctx context.Context processor *TrustLinesProcessor mockQ *history.MockQTrustLines } func (s *TrustLinesProcessorTestSuiteLedger) SetupTest() { + s.ctx = context.Background() s.mockQ = &history.MockQTrustLines{} s.processor = NewTrustLinesProcessor(s.mockQ) } @@ -125,12 +132,12 @@ func (s *TrustLinesProcessorTestSuiteLedger) TearDownTest() { func (s *TrustLinesProcessorTestSuiteLedger) TestNoIngestUpdateState() { // Nothing processed, assertions in TearDownTest. - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *TrustLinesProcessorTestSuiteLedger) TestInsertTrustLine() { // should be ignored because it's not an trust line type - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeAccount, Pre: nil, Post: &xdr.LedgerEntry{ @@ -159,7 +166,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestInsertTrustLine() { } lastModifiedLedgerSeq := xdr.Uint32(1234) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -172,7 +179,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestInsertTrustLine() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: nil, Post: &xdr.LedgerEntry{ @@ -197,7 +204,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestInsertTrustLine() { Balance: 10, } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -216,7 +223,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestInsertTrustLine() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -237,9 +244,10 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestInsertTrustLine() { s.mockQ.On( "UpsertTrustLines", + s.ctx, mock.AnythingOfType("[]xdr.LedgerEntry"), ).Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.LedgerEntry) + arg := args.Get(1).([]xdr.LedgerEntry) s.Assert().ElementsMatch( []xdr.LedgerEntry{ { @@ -260,7 +268,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestInsertTrustLine() { arg, ) }).Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLine() { @@ -279,7 +287,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLine() { Flags: xdr.Uint32(xdr.TrustLineFlagsAuthorizedFlag), } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -300,6 +308,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLine() { s.mockQ.On( "UpsertTrustLines", + s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -310,7 +319,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLine() { }, }, ).Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() { @@ -340,7 +349,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() Balance: 10, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -359,7 +368,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq - 1, @@ -380,9 +389,10 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() s.mockQ.On( "UpsertTrustLines", + s.ctx, mock.AnythingOfType("[]xdr.LedgerEntry"), ).Run(func(args mock.Arguments) { - arg := args.Get(0).([]xdr.LedgerEntry) + arg := args.Get(1).([]xdr.LedgerEntry) s.Assert().ElementsMatch( []xdr.LedgerEntry{ { @@ -403,7 +413,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestUpdateTrustLineAuthorization() arg, ) }).Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *TrustLinesProcessorTestSuiteLedger) TestRemoveTrustLine() { @@ -413,7 +423,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestRemoveTrustLine() { Balance: 0, } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -430,7 +440,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestRemoveTrustLine() { }) s.Assert().NoError(err) - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -443,20 +453,20 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestRemoveTrustLine() { s.Assert().NoError(err) s.mockQ.On( - "RemoveTrustLine", + "RemoveTrustLine", s.ctx, xdr.LedgerKeyTrustLine{ AccountId: xdr.MustAddress("GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB"), Asset: xdr.MustNewCreditAsset("EUR", trustLineIssuer.Address()), }, ).Return(int64(1), nil).Once() s.mockQ.On( - "RemoveTrustLine", + "RemoveTrustLine", s.ctx, xdr.LedgerKeyTrustLine{ AccountId: xdr.MustAddress("GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB"), Asset: xdr.MustNewCreditAsset("USD", trustLineIssuer.Address()), }, ).Return(int64(1), nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *TrustLinesProcessorTestSuiteLedger) TestProcessUpgradeChange() { @@ -469,7 +479,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestProcessUpgradeChange() { Flags: xdr.Uint32(xdr.TrustLineFlagsAuthorizedFlag), } - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Post: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -488,7 +498,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestProcessUpgradeChange() { Flags: xdr.Uint32(xdr.TrustLineFlagsAuthorizedFlag), } - err = s.processor.ProcessChange(ingest.Change{ + err = s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -508,7 +518,7 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestProcessUpgradeChange() { s.Assert().NoError(err) s.mockQ.On( - "UpsertTrustLines", + "UpsertTrustLines", s.ctx, []xdr.LedgerEntry{ { LastModifiedLedgerSeq: lastModifiedLedgerSeq, @@ -519,11 +529,11 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestProcessUpgradeChange() { }, }, ).Return(nil).Once() - s.Assert().NoError(s.processor.Commit()) + s.Assert().NoError(s.processor.Commit(s.ctx)) } func (s *TrustLinesProcessorTestSuiteLedger) TestRemoveTrustlineNoRowsAffected() { - err := s.processor.ProcessChange(ingest.Change{ + err := s.processor.ProcessChange(s.ctx, ingest.Change{ Type: xdr.LedgerEntryTypeTrustline, Pre: &xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ @@ -541,14 +551,14 @@ func (s *TrustLinesProcessorTestSuiteLedger) TestRemoveTrustlineNoRowsAffected() s.Assert().NoError(err) s.mockQ.On( - "RemoveTrustLine", + "RemoveTrustLine", s.ctx, xdr.LedgerKeyTrustLine{ AccountId: xdr.MustAddress("GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB"), Asset: xdr.MustNewCreditAsset("EUR", trustLineIssuer.Address()), }, ).Return(int64(0), nil).Once() - err = s.processor.Commit() + err = s.processor.Commit(s.ctx) s.Assert().Error(err) s.Assert().IsType(ingest.StateError{}, errors.Cause(err)) s.Assert().EqualError(err, "0 rows affected when removing trustline: GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB credit_alphanum4/EUR/GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H") diff --git a/services/horizon/internal/ingest/resume_state_test.go b/services/horizon/internal/ingest/resume_state_test.go index 2647f4a6e9..92c95a675d 100644 --- a/services/horizon/internal/ingest/resume_state_test.go +++ b/services/horizon/internal/ingest/resume_state_test.go @@ -23,6 +23,7 @@ func TestResumeTestTestSuite(t *testing.T) { type ResumeTestTestSuite struct { suite.Suite + ctx context.Context ledgerBackend *ledgerbackend.MockDatabaseBackend historyQ *mockDBQ historyAdapter *mockHistoryArchiveAdapter @@ -32,13 +33,14 @@ type ResumeTestTestSuite struct { } func (s *ResumeTestTestSuite) SetupTest() { + s.ctx = context.Background() s.ledgerBackend = &ledgerbackend.MockDatabaseBackend{} s.historyQ = &mockDBQ{} s.historyAdapter = &mockHistoryArchiveAdapter{} s.runner = &mockProcessorsRunner{} s.stellarCoreClient = &mockStellarCoreClient{} s.system = &system{ - ctx: context.Background(), + ctx: s.ctx, historyQ: s.historyQ, historyAdapter: s.historyAdapter, runner: s.runner, @@ -48,7 +50,7 @@ func (s *ResumeTestTestSuite) SetupTest() { } s.system.initMetrics() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() s.ledgerBackend.On("IsPrepared", ledgerbackend.UnboundedRange(101)).Return(false, nil).Once() s.ledgerBackend.On("PrepareRange", ledgerbackend.UnboundedRange(101)).Return(nil).Once() @@ -124,7 +126,7 @@ func (s *ResumeTestTestSuite) TestBeginReturnsError() { // Recreate mock in this single test to remove Rollback assertion. *s.historyQ = mockDBQ{} - s.historyQ.On("Begin").Return(errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(errors.New("my error")).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().Error(err) @@ -139,8 +141,8 @@ func (s *ResumeTestTestSuite) TestBeginReturnsError() { } func (s *ResumeTestTestSuite) TestGetLastLedgerIngestReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), errors.New("my error")).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().Error(err) @@ -155,8 +157,8 @@ func (s *ResumeTestTestSuite) TestGetLastLedgerIngestReturnsError() { } func (s *ResumeTestTestSuite) TestGetLatestLedgerLessThanCurrent() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(99), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(99), nil).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().Error(err) @@ -168,9 +170,9 @@ func (s *ResumeTestTestSuite) TestGetLatestLedgerLessThanCurrent() { } func (s *ResumeTestTestSuite) TestGetIngestionVersionError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(0, errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(0, errors.New("my error")).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().Error(err) @@ -185,9 +187,9 @@ func (s *ResumeTestTestSuite) TestGetIngestionVersionError() { } func (s *ResumeTestTestSuite) TestIngestionVersionLessThanCurrentVersion() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion-1, nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion-1, nil).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().NoError(err) @@ -198,9 +200,9 @@ func (s *ResumeTestTestSuite) TestIngestionVersionLessThanCurrentVersion() { } func (s *ResumeTestTestSuite) TestIngestionVersionGreaterThanCurrentVersion() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion+1, nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion+1, nil).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().NoError(err) @@ -211,10 +213,10 @@ func (s *ResumeTestTestSuite) TestIngestionVersionGreaterThanCurrentVersion() { } func (s *ResumeTestTestSuite) TestGetLatestLedgerError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(0), errors.New("my error")) + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(0), errors.New("my error")) next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().Error(err) @@ -229,10 +231,10 @@ func (s *ResumeTestTestSuite) TestGetLatestLedgerError() { } func (s *ResumeTestTestSuite) TestLatestHistoryLedgerLessThanIngestLedger() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(99), nil) + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(99), nil) next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().NoError(err) @@ -243,10 +245,10 @@ func (s *ResumeTestTestSuite) TestLatestHistoryLedgerLessThanIngestLedger() { } func (s *ResumeTestTestSuite) TestLatestHistoryLedgerGreaterThanIngestLedger() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(101), nil) + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(101), nil) next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().NoError(err) @@ -257,10 +259,10 @@ func (s *ResumeTestTestSuite) TestLatestHistoryLedgerGreaterThanIngestLedger() { } func (s *ResumeTestTestSuite) mockSuccessfulIngestion() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(100), nil) + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(100), nil) s.runner.On("RunAllProcessorsOnLedger", mock.AnythingOfType("xdr.LedgerCloseMeta")). Run(func(args mock.Arguments) { @@ -274,8 +276,8 @@ func (s *ResumeTestTestSuite) mockSuccessfulIngestion() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(101)).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(101)).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() s.stellarCoreClient.On( "SetCursor", @@ -284,7 +286,7 @@ func (s *ResumeTestTestSuite) mockSuccessfulIngestion() { int32(101), ).Return(nil).Once() - s.historyQ.On("GetExpStateInvalid").Return(false, nil).Once() + s.historyQ.On("GetExpStateInvalid", s.ctx).Return(false, nil).Once() } func (s *ResumeTestTestSuite) TestBumpIngestLedger() { *s.ledgerBackend = ledgerbackend.MockDatabaseBackend{} @@ -303,8 +305,8 @@ func (s *ResumeTestTestSuite) TestBumpIngestLedger() { }, }, nil).Once() - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(101), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(101), nil).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 99}.run(s.system) s.Assert().NoError(err) @@ -332,10 +334,10 @@ func (s *ResumeTestTestSuite) TestIngestAllMasterNode() { } func (s *ResumeTestTestSuite) TestErrorSettingCursorIgnored() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() - s.historyQ.On("GetIngestVersion").Return(CurrentVersion, nil).Once() - s.historyQ.On("GetLatestHistoryLedger").Return(uint32(100), nil) + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() + s.historyQ.On("GetIngestVersion", s.ctx).Return(CurrentVersion, nil).Once() + s.historyQ.On("GetLatestHistoryLedger", s.ctx).Return(uint32(100), nil) s.runner.On("RunAllProcessorsOnLedger", mock.AnythingOfType("xdr.LedgerCloseMeta")). Run(func(args mock.Arguments) { @@ -349,8 +351,8 @@ func (s *ResumeTestTestSuite) TestErrorSettingCursorIgnored() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(101)).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(101)).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() s.stellarCoreClient.On( "SetCursor", @@ -359,7 +361,7 @@ func (s *ResumeTestTestSuite) TestErrorSettingCursorIgnored() { int32(101), ).Return(errors.New("my error")).Once() - s.historyQ.On("GetExpStateInvalid").Return(false, nil).Once() + s.historyQ.On("GetExpStateInvalid", s.ctx).Return(false, nil).Once() next, err := resumeState{latestSuccessfullyProcessedLedger: 100}.run(s.system) s.Assert().NoError(err) diff --git a/services/horizon/internal/ingest/stress_test.go b/services/horizon/internal/ingest/stress_test.go index b3d2d9dd56..852ad8ed57 100644 --- a/services/horizon/internal/ingest/stress_test.go +++ b/services/horizon/internal/ingest/stress_test.go @@ -3,6 +3,7 @@ package ingest import ( + "context" "testing" "github.com/stretchr/testify/mock" @@ -19,6 +20,7 @@ func TestStressTestStateTestSuite(t *testing.T) { type StressTestStateTestSuite struct { suite.Suite + ctx context.Context historyQ *mockDBQ historyAdapter *mockHistoryArchiveAdapter runner *mockProcessorsRunner @@ -26,10 +28,12 @@ type StressTestStateTestSuite struct { } func (s *StressTestStateTestSuite) SetupTest() { + s.ctx = context.Background() s.historyQ = &mockDBQ{} s.historyAdapter = &mockHistoryArchiveAdapter{} s.runner = &mockProcessorsRunner{} s.system = &system{ + ctx: s.ctx, historyQ: s.historyQ, historyAdapter: s.historyAdapter, runner: s.runner, @@ -37,7 +41,7 @@ func (s *StressTestStateTestSuite) SetupTest() { s.system.initMetrics() s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() s.runner.On("EnableMemoryStatsLogging").Return() } @@ -65,31 +69,31 @@ func (s *StressTestStateTestSuite) TestBounds() { func (s *StressTestStateTestSuite) TestBeginReturnsError() { *s.historyQ = mockDBQ{} s.historyQ.On("GetTx").Return(nil).Once() - s.historyQ.On("Begin").Return(errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(errors.New("my error")).Once() err := s.system.StressTest(10, 4) s.Assert().EqualError(err, "Error starting a transaction: my error") } func (s *StressTestStateTestSuite) TestGetLastLedgerIngestReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), errors.New("my error")).Once() err := s.system.StressTest(10, 4) s.Assert().EqualError(err, "Error getting last ingested ledger: my error") } func (s *StressTestStateTestSuite) TestGetLastLedgerIngestNonEmpty() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() err := s.system.StressTest(10, 4) s.Assert().EqualError(err, "Database not empty") } func (s *StressTestStateTestSuite) TestRunAllProcessorsOnLedgerReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() s.runner.On("RunAllProcessorsOnLedger", mock.AnythingOfType("xdr.LedgerCloseMeta")).Return( ingest.StatsChangeProcessorResults{}, @@ -104,8 +108,8 @@ func (s *StressTestStateTestSuite) TestRunAllProcessorsOnLedgerReturnsError() { } func (s *StressTestStateTestSuite) TestUpdateLastLedgerIngestReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() s.runner.On("RunAllProcessorsOnLedger", mock.AnythingOfType("xdr.LedgerCloseMeta")).Return( ingest.StatsChangeProcessorResults{}, processorsRunDurations{}, @@ -113,15 +117,15 @@ func (s *StressTestStateTestSuite) TestUpdateLastLedgerIngestReturnsError() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(1)).Return(errors.New("my error")).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(1)).Return(errors.New("my error")).Once() err := s.system.StressTest(10, 4) s.Assert().EqualError(err, "Error updating last ingested ledger: my error") } func (s *StressTestStateTestSuite) TestCommitReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() s.runner.On("RunAllProcessorsOnLedger", mock.AnythingOfType("xdr.LedgerCloseMeta")).Return( ingest.StatsChangeProcessorResults{}, processorsRunDurations{}, @@ -129,16 +133,16 @@ func (s *StressTestStateTestSuite) TestCommitReturnsError() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(1)).Return(nil).Once() - s.historyQ.On("Commit").Return(errors.New("my error")).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(1)).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(errors.New("my error")).Once() err := s.system.StressTest(10, 4) s.Assert().EqualError(err, "Error committing db transaction: my error") } func (s *StressTestStateTestSuite) TestSucceeds() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() s.runner.On("RunAllProcessorsOnLedger", mock.AnythingOfType("xdr.LedgerCloseMeta")).Return( ingest.StatsChangeProcessorResults{}, processorsRunDurations{}, @@ -146,8 +150,8 @@ func (s *StressTestStateTestSuite) TestSucceeds() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(1)).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(1)).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() err := s.system.StressTest(10, 4) s.Assert().NoError(err) diff --git a/services/horizon/internal/ingest/verify.go b/services/horizon/internal/ingest/verify.go index 7d239aa0cd..f7c47dfaea 100644 --- a/services/horizon/internal/ingest/verify.go +++ b/services/horizon/internal/ingest/verify.go @@ -59,8 +59,8 @@ func (s *system) verifyState(verifyAgainstLatestCheckpoint bool) error { } historyQ := s.historyQ.CloneIngestionQ() - defer historyQ.Rollback() - err := historyQ.BeginTx(&sql.TxOptions{ + defer historyQ.Rollback(s.ctx) + err := historyQ.BeginTx(s.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }) @@ -69,7 +69,7 @@ func (s *system) verifyState(verifyAgainstLatestCheckpoint bool) error { } // Ensure the ledger is a checkpoint ledger - ledgerSequence, err := historyQ.GetLastLedgerIngestNonBlocking() + ledgerSequence, err := historyQ.GetLastLedgerIngestNonBlocking(s.ctx) if err != nil { return errors.Wrap(err, "Error running historyQ.GetLastLedgerIngestNonBlocking") } @@ -183,27 +183,27 @@ func (s *system) verifyState(verifyAgainstLatestCheckpoint bool) error { } } - err = addAccountsToStateVerifier(verifier, historyQ, accounts) + err = addAccountsToStateVerifier(s.ctx, verifier, historyQ, accounts) if err != nil { return errors.Wrap(err, "addAccountsToStateVerifier failed") } - err = addDataToStateVerifier(verifier, historyQ, data) + err = addDataToStateVerifier(s.ctx, verifier, historyQ, data) if err != nil { return errors.Wrap(err, "addDataToStateVerifier failed") } - err = addOffersToStateVerifier(verifier, historyQ, offers) + err = addOffersToStateVerifier(s.ctx, verifier, historyQ, offers) if err != nil { return errors.Wrap(err, "addOffersToStateVerifier failed") } - err = addTrustLinesToStateVerifier(verifier, assetStats, historyQ, trustLines) + err = addTrustLinesToStateVerifier(s.ctx, verifier, assetStats, historyQ, trustLines) if err != nil { return errors.Wrap(err, "addTrustLinesToStateVerifier failed") } - err = addClaimableBalanceToStateVerifier(verifier, assetStats, historyQ, cBalances) + err = addClaimableBalanceToStateVerifier(s.ctx, verifier, assetStats, historyQ, cBalances) if err != nil { return errors.Wrap(err, "addClaimableBalanceToStateVerifier failed") } @@ -214,27 +214,27 @@ func (s *system) verifyState(verifyAgainstLatestCheckpoint bool) error { localLog.WithField("total", total).Info("Finished writing to StateVerifier") - countAccounts, err := historyQ.CountAccounts() + countAccounts, err := historyQ.CountAccounts(s.ctx) if err != nil { return errors.Wrap(err, "Error running historyQ.CountAccounts") } - countData, err := historyQ.CountAccountsData() + countData, err := historyQ.CountAccountsData(s.ctx) if err != nil { return errors.Wrap(err, "Error running historyQ.CountData") } - countOffers, err := historyQ.CountOffers() + countOffers, err := historyQ.CountOffers(s.ctx) if err != nil { return errors.Wrap(err, "Error running historyQ.CountOffers") } - countTrustLines, err := historyQ.CountTrustLines() + countTrustLines, err := historyQ.CountTrustLines(s.ctx) if err != nil { return errors.Wrap(err, "Error running historyQ.CountTrustLines") } - countClaimableBalances, err := historyQ.CountClaimableBalances() + countClaimableBalances, err := historyQ.CountClaimableBalances(s.ctx) if err != nil { return errors.Wrap(err, "Error running historyQ.CountClaimableBalances") } @@ -244,7 +244,7 @@ func (s *system) verifyState(verifyAgainstLatestCheckpoint bool) error { return errors.Wrap(err, "verifier.Verify failed") } - err = checkAssetStats(assetStats, historyQ) + err = checkAssetStats(s.ctx, assetStats, historyQ) if err != nil { return errors.Wrap(err, "checkAssetStats failed") } @@ -254,14 +254,14 @@ func (s *system) verifyState(verifyAgainstLatestCheckpoint bool) error { return nil } -func checkAssetStats(set processors.AssetStatSet, q history.IngestionQ) error { +func checkAssetStats(ctx context.Context, set processors.AssetStatSet, q history.IngestionQ) error { page := db2.PageQuery{ Order: "asc", Limit: assetStatsBatchSize, } for { - assetStats, err := q.GetAssetStats("", "", page) + assetStats, err := q.GetAssetStats(ctx, "", "", page) if err != nil { return errors.Wrap(err, "could not fetch asset stats from db") } @@ -304,17 +304,17 @@ func checkAssetStats(set processors.AssetStatSet, q history.IngestionQ) error { return nil } -func addAccountsToStateVerifier(verifier *verify.StateVerifier, q history.IngestionQ, ids []string) error { +func addAccountsToStateVerifier(ctx context.Context, verifier *verify.StateVerifier, q history.IngestionQ, ids []string) error { if len(ids) == 0 { return nil } - accounts, err := q.GetAccountsByIDs(ids) + accounts, err := q.GetAccountsByIDs(ctx, ids) if err != nil { return errors.Wrap(err, "Error running history.Q.GetAccountsByIDs") } - signers, err := q.SignersForAccounts(ids) + signers, err := q.SignersForAccounts(ctx, ids) if err != nil { return errors.Wrap(err, "Error running history.Q.SignersForAccounts") } @@ -420,12 +420,12 @@ func addAccountsToStateVerifier(verifier *verify.StateVerifier, q history.Ingest return nil } -func addDataToStateVerifier(verifier *verify.StateVerifier, q history.IngestionQ, keys []xdr.LedgerKeyData) error { +func addDataToStateVerifier(ctx context.Context, verifier *verify.StateVerifier, q history.IngestionQ, keys []xdr.LedgerKeyData) error { if len(keys) == 0 { return nil } - data, err := q.GetAccountDataByKeys(keys) + data, err := q.GetAccountDataByKeys(ctx, keys) if err != nil { return errors.Wrap(err, "Error running history.Q.GetAccountDataByKeys") } @@ -453,6 +453,7 @@ func addDataToStateVerifier(verifier *verify.StateVerifier, q history.IngestionQ } func addOffersToStateVerifier( + ctx context.Context, verifier *verify.StateVerifier, q history.IngestionQ, ids []int64, @@ -461,7 +462,7 @@ func addOffersToStateVerifier( return nil } - offers, err := q.GetOffersByIDs(ids) + offers, err := q.GetOffersByIDs(ctx, ids) if err != nil { return errors.Wrap(err, "Error running history.Q.GetOfferByIDs") } @@ -496,6 +497,7 @@ func addOffersToStateVerifier( } func addTrustLinesToStateVerifier( + ctx context.Context, verifier *verify.StateVerifier, assetStats processors.AssetStatSet, q history.IngestionQ, @@ -505,7 +507,7 @@ func addTrustLinesToStateVerifier( return nil } - trustLines, err := q.GetTrustLinesByKeys(keys) + trustLines, err := q.GetTrustLinesByKeys(ctx, keys) if err != nil { return errors.Wrap(err, "Error running history.Q.GetTrustLinesByKeys") } @@ -558,6 +560,7 @@ func addTrustLinesToStateVerifier( } func addClaimableBalanceToStateVerifier( + ctx context.Context, verifier *verify.StateVerifier, assetStats processors.AssetStatSet, q history.IngestionQ, @@ -567,7 +570,7 @@ func addClaimableBalanceToStateVerifier( return nil } - cBalances, err := q.GetClaimableBalancesByID(ids) + cBalances, err := q.GetClaimableBalancesByID(ctx, ids) if err != nil { return errors.Wrap(err, "Error running history.Q.GetClaimableBalancesByID") } diff --git a/services/horizon/internal/ingest/verify_range_state_test.go b/services/horizon/internal/ingest/verify_range_state_test.go index 55c90fae86..5eb763e992 100644 --- a/services/horizon/internal/ingest/verify_range_state_test.go +++ b/services/horizon/internal/ingest/verify_range_state_test.go @@ -30,6 +30,7 @@ func TestVerifyRangeStateTestSuite(t *testing.T) { type VerifyRangeStateTestSuite struct { suite.Suite + ctx context.Context ledgerBackend *ledgerbackend.MockDatabaseBackend historyQ *mockDBQ historyAdapter *mockHistoryArchiveAdapter @@ -38,12 +39,13 @@ type VerifyRangeStateTestSuite struct { } func (s *VerifyRangeStateTestSuite) SetupTest() { + s.ctx = context.Background() s.ledgerBackend = &ledgerbackend.MockDatabaseBackend{} s.historyQ = &mockDBQ{} s.historyAdapter = &mockHistoryArchiveAdapter{} s.runner = &mockProcessorsRunner{} s.system = &system{ - ctx: context.Background(), + ctx: s.ctx, historyQ: s.historyQ, historyAdapter: s.historyAdapter, ledgerBackend: s.ledgerBackend, @@ -52,7 +54,7 @@ func (s *VerifyRangeStateTestSuite) SetupTest() { } s.system.initMetrics() - s.historyQ.On("Rollback").Return(nil).Once() + s.historyQ.On("Rollback", s.ctx).Return(nil).Once() } func (s *VerifyRangeStateTestSuite) TearDownTest() { @@ -102,7 +104,7 @@ func (s *VerifyRangeStateTestSuite) TestInvalidRange() { func (s *VerifyRangeStateTestSuite) TestBeginReturnsError() { // Recreate mock in this single test to remove Rollback assertion. *s.historyQ = mockDBQ{} - s.historyQ.On("Begin").Return(errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(errors.New("my error")).Once() next, err := verifyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().Error(err) @@ -114,8 +116,8 @@ func (s *VerifyRangeStateTestSuite) TestBeginReturnsError() { } func (s *VerifyRangeStateTestSuite) TestGetLastLedgerIngestReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), errors.New("my error")).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), errors.New("my error")).Once() next, err := verifyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().Error(err) @@ -127,8 +129,8 @@ func (s *VerifyRangeStateTestSuite) TestGetLastLedgerIngestReturnsError() { } func (s *VerifyRangeStateTestSuite) TestGetLastLedgerIngestNonEmpty() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(100), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(100), nil).Once() next, err := verifyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) s.Assert().Error(err) @@ -140,8 +142,8 @@ func (s *VerifyRangeStateTestSuite) TestGetLastLedgerIngestNonEmpty() { } func (s *VerifyRangeStateTestSuite) TestRunHistoryArchiveIngestionReturnsError() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() s.ledgerBackend.On("PrepareRange", ledgerbackend.BoundedRange(100, 200)).Return(nil).Once() meta := xdr.LedgerCloseMeta{ @@ -168,8 +170,8 @@ func (s *VerifyRangeStateTestSuite) TestRunHistoryArchiveIngestionReturnsError() } func (s *VerifyRangeStateTestSuite) TestSuccess() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() s.ledgerBackend.On("PrepareRange", ledgerbackend.BoundedRange(100, 200)).Return(nil).Once() meta := xdr.LedgerCloseMeta{ @@ -186,11 +188,11 @@ func (s *VerifyRangeStateTestSuite) TestSuccess() { s.ledgerBackend.On("GetLedger", uint32(100)).Return(true, meta, nil).Once() s.runner.On("RunHistoryArchiveIngestion", uint32(100), MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}).Return(ingest.StatsChangeProcessorResults{}, nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(100)).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(100)).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() for i := uint32(101); i <= 200; i++ { - s.historyQ.On("Begin").Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() meta := xdr.LedgerCloseMeta{ V0: &xdr.LedgerCloseMetaV0{ @@ -210,8 +212,8 @@ func (s *VerifyRangeStateTestSuite) TestSuccess() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("UpdateLastLedgerIngest", i).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, i).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() } next, err := verifyRangeState{fromLedger: 100, toLedger: 200}.run(s.system) @@ -223,8 +225,8 @@ func (s *VerifyRangeStateTestSuite) TestSuccess() { } func (s *VerifyRangeStateTestSuite) TestSuccessWithVerify() { - s.historyQ.On("Begin").Return(nil).Once() - s.historyQ.On("GetLastLedgerIngest").Return(uint32(0), nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() + s.historyQ.On("GetLastLedgerIngest", s.ctx).Return(uint32(0), nil).Once() s.ledgerBackend.On("PrepareRange", ledgerbackend.BoundedRange(100, 110)).Return(nil).Once() meta := xdr.LedgerCloseMeta{ @@ -241,11 +243,11 @@ func (s *VerifyRangeStateTestSuite) TestSuccessWithVerify() { s.ledgerBackend.On("GetLedger", uint32(100)).Return(true, meta, nil).Once() s.runner.On("RunHistoryArchiveIngestion", uint32(100), MaxSupportedProtocolVersion, xdr.Hash{1, 2, 3}).Return(ingest.StatsChangeProcessorResults{}, nil).Once() - s.historyQ.On("UpdateLastLedgerIngest", uint32(100)).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, uint32(100)).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() for i := uint32(101); i <= 110; i++ { - s.historyQ.On("Begin").Return(nil).Once() + s.historyQ.On("Begin", s.ctx).Return(nil).Once() meta := xdr.LedgerCloseMeta{ V0: &xdr.LedgerCloseMetaV0{ @@ -265,20 +267,20 @@ func (s *VerifyRangeStateTestSuite) TestSuccessWithVerify() { processorsRunDurations{}, nil, ).Once() - s.historyQ.On("UpdateLastLedgerIngest", i).Return(nil).Once() - s.historyQ.On("Commit").Return(nil).Once() + s.historyQ.On("UpdateLastLedgerIngest", s.ctx, i).Return(nil).Once() + s.historyQ.On("Commit", s.ctx).Return(nil).Once() } clonedQ := &mockDBQ{} s.historyQ.On("CloneIngestionQ").Return(clonedQ).Once() - clonedQ.On("BeginTx", mock.Anything).Run(func(args mock.Arguments) { - arg := args.Get(0).(*sql.TxOptions) + clonedQ.On("BeginTx", s.ctx, mock.AnythingOfType("*sql.TxOptions")).Run(func(args mock.Arguments) { + arg := args.Get(1).(*sql.TxOptions) s.Assert().Equal(sql.LevelRepeatableRead, arg.Isolation) s.Assert().True(arg.ReadOnly) }).Return(nil).Once() - clonedQ.On("Rollback").Return(nil).Once() - clonedQ.On("GetLastLedgerIngestNonBlocking").Return(uint32(63), nil).Once() + clonedQ.On("Rollback", s.ctx).Return(nil).Once() + clonedQ.On("GetLastLedgerIngestNonBlocking", s.ctx).Return(uint32(63), nil).Once() mockChangeReader := &ingest.MockChangeReader{} mockChangeReader.On("Close").Return(nil).Once() mockAccountID := "GACMZD5VJXTRLKVET72CETCYKELPNCOTTBDC6DHFEUPLG5DHEK534JQX" @@ -422,7 +424,7 @@ func (s *VerifyRangeStateTestSuite) TestSuccessWithVerify() { mockChangeReader.On("Read").Return(claimableBalanceChange, nil).Once() mockChangeReader.On("Read").Return(ingest.Change{}, io.EOF).Once() mockChangeReader.On("Read").Return(ingest.Change{}, io.EOF).Once() - s.historyAdapter.On("GetState", mock.AnythingOfType("*context.emptyCtx"), uint32(63)).Return(mockChangeReader, nil).Once() + s.historyAdapter.On("GetState", s.ctx, uint32(63)).Return(mockChangeReader, nil).Once() mockAccount := history.AccountEntry{ AccountID: mockAccountID, Balance: 600, @@ -435,8 +437,8 @@ func (s *VerifyRangeStateTestSuite) TestSuccessWithVerify() { Sponsor: null.StringFrom("GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML"), } - clonedQ.MockQAccounts.On("GetAccountsByIDs", []string{mockAccountID}).Return([]history.AccountEntry{mockAccount}, nil).Once() - clonedQ.MockQSigners.On("SignersForAccounts", []string{mockAccountID}).Return([]history.AccountSigner{ + clonedQ.MockQAccounts.On("GetAccountsByIDs", s.ctx, []string{mockAccountID}).Return([]history.AccountEntry{mockAccount}, nil).Once() + clonedQ.MockQSigners.On("SignersForAccounts", s.ctx, []string{mockAccountID}).Return([]history.AccountSigner{ { Account: mockAccountID, Signer: mockAccountID, @@ -460,7 +462,7 @@ func (s *VerifyRangeStateTestSuite) TestSuccessWithVerify() { Sponsor: null.StringFrom(mockAccountID), }, }, nil).Once() - clonedQ.MockQSigners.On("CountAccounts").Return(1, nil).Once() + clonedQ.MockQSigners.On("CountAccounts", s.ctx).Return(1, nil).Once() mockOffer := history.Offer{ SellerID: eurOffer.SellerId.Address(), OfferID: int64(eurOffer.OfferId), @@ -474,19 +476,19 @@ func (s *VerifyRangeStateTestSuite) TestSuccessWithVerify() { LastModifiedLedger: 62, Sponsor: null.StringFrom("GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML"), } - clonedQ.MockQOffers.On("GetOffersByIDs", []int64{int64(eurOffer.OfferId)}).Return([]history.Offer{mockOffer}, nil).Once() - clonedQ.MockQOffers.On("CountOffers").Return(1, nil).Once() + clonedQ.MockQOffers.On("GetOffersByIDs", s.ctx, []int64{int64(eurOffer.OfferId)}).Return([]history.Offer{mockOffer}, nil).Once() + clonedQ.MockQOffers.On("CountOffers", s.ctx).Return(1, nil).Once() // TODO: add accounts data, trustlines and asset stats - clonedQ.MockQData.On("CountAccountsData").Return(0, nil).Once() - clonedQ.MockQAssetStats.On("CountTrustLines").Return(0, nil).Once() - clonedQ.MockQAssetStats.On("GetAssetStats", "", "", db2.PageQuery{ + clonedQ.MockQData.On("CountAccountsData", s.ctx).Return(0, nil).Once() + clonedQ.MockQAssetStats.On("CountTrustLines", s.ctx).Return(0, nil).Once() + clonedQ.MockQAssetStats.On("GetAssetStats", s.ctx, "", "", db2.PageQuery{ Order: "asc", Limit: assetStatsBatchSize, }).Return([]history.ExpAssetStat{}, nil).Once() - clonedQ.MockQClaimableBalances.On("CountClaimableBalances").Return(1, nil).Once() + clonedQ.MockQClaimableBalances.On("CountClaimableBalances", s.ctx).Return(1, nil).Once() clonedQ.MockQClaimableBalances. - On("GetClaimableBalancesByID", []xdr.ClaimableBalanceId{claimableBalanceChange.Post.Data.ClaimableBalance.BalanceId}). + On("GetClaimableBalancesByID", s.ctx, []xdr.ClaimableBalanceId{claimableBalanceChange.Post.Data.ClaimableBalance.BalanceId}). Return([]history.ClaimableBalance{claimableBalance}, nil).Once() next, err := verifyRangeState{ @@ -535,19 +537,19 @@ func (s *VerifyRangeStateTestSuite) TestVerifyFailsWhenAssetStatsMismatch() { NumAccounts: 0, } - s.historyQ.MockQAssetStats.On("GetAssetStats", "", "", db2.PageQuery{ + s.historyQ.MockQAssetStats.On("GetAssetStats", s.ctx, "", "", db2.PageQuery{ Order: "asc", Limit: assetStatsBatchSize, }).Return([]history.ExpAssetStat{stat}, nil).Once() - s.historyQ.MockQAssetStats.On("GetAssetStats", "", "", db2.PageQuery{ + s.historyQ.MockQAssetStats.On("GetAssetStats", s.ctx, "", "", db2.PageQuery{ Cursor: stat.PagingToken(), Order: "asc", Limit: assetStatsBatchSize, }).Return([]history.ExpAssetStat{}, nil).Once() - err := checkAssetStats(set, s.historyQ) + err := checkAssetStats(s.ctx, set, s.historyQ) s.Assert().EqualError(err, fmt.Sprintf("db asset stat with code EUR issuer %s does not match asset stat from HAS", trustLineIssuer.Address())) // Satisfy the mock - s.historyQ.Rollback() + s.historyQ.Rollback(s.ctx) } diff --git a/services/horizon/internal/init.go b/services/horizon/internal/init.go index db6a87573b..bc9a5056bd 100644 --- a/services/horizon/internal/init.go +++ b/services/horizon/internal/init.go @@ -88,7 +88,7 @@ func initIngester(app *App) { func initPathFinder(app *App) { orderBookGraph := orderbook.NewOrderBookGraph() app.orderBookStream = ingest.NewOrderBookStream( - &history.Q{app.HorizonSession(app.ctx)}, + &history.Q{app.HorizonSession()}, orderBookGraph, ) @@ -304,7 +304,7 @@ func initSubmissionSystem(app *App) { Submitter: txsub.NewDefaultSubmitter(http.DefaultClient, app.config.StellarCoreURL), SubmissionQueue: sequence.NewManager(), DB: func(ctx context.Context) txsub.HorizonDB { - return &history.Q{Session: app.HorizonSession(ctx)} + return &history.Q{Session: app.HorizonSession()} }, } } diff --git a/services/horizon/internal/middleware_test.go b/services/horizon/internal/middleware_test.go index ecae31a138..c7c1e92142 100644 --- a/services/horizon/internal/middleware_test.go +++ b/services/horizon/internal/middleware_test.go @@ -3,6 +3,7 @@ package horizon import ( + "context" "net/http" "net/http/httptest" "strconv" @@ -270,8 +271,8 @@ func TestStateMiddleware(t *testing.T) { } { t.Run(testCase.name, func(t *testing.T) { stateMiddleware.NoStateVerification = testCase.noStateVerification - tt.Assert.NoError(q.UpdateExpStateInvalid(testCase.stateInvalid)) - _, err = q.InsertLedger(xdr.LedgerHeaderHistoryEntry{ + tt.Assert.NoError(q.UpdateExpStateInvalid(context.Background(), testCase.stateInvalid)) + _, err = q.InsertLedger(context.Background(), xdr.LedgerHeaderHistoryEntry{ Hash: xdr.Hash{byte(i)}, Header: xdr.LedgerHeader{ LedgerSeq: testCase.latestHistoryLedger, @@ -279,8 +280,8 @@ func TestStateMiddleware(t *testing.T) { }, }, 0, 0, 0, 0, 0) tt.Assert.NoError(err) - tt.Assert.NoError(q.UpdateLastLedgerIngest(testCase.lastIngestedLedger)) - tt.Assert.NoError(q.UpdateIngestVersion(testCase.ingestionVersion)) + tt.Assert.NoError(q.UpdateLastLedgerIngest(context.Background(), testCase.lastIngestedLedger)) + tt.Assert.NoError(q.UpdateIngestVersion(context.Background(), testCase.ingestionVersion)) if testCase.sseRequest { request.Header.Set("Accept", "text/event-stream") diff --git a/services/horizon/internal/reap/system.go b/services/horizon/internal/reap/system.go index 25127bdea3..66c695ddf2 100644 --- a/services/horizon/internal/reap/system.go +++ b/services/horizon/internal/reap/system.go @@ -1,6 +1,7 @@ package reap import ( + "context" "time" "github.com/stellar/go/services/horizon/internal/errors" @@ -9,7 +10,7 @@ import ( ) // DeleteUnretainedHistory removes all data associated with unretained ledgers. -func (r *System) DeleteUnretainedHistory() error { +func (r *System) DeleteUnretainedHistory(ctx context.Context) error { // RetentionCount of 0 indicates "keep all history" if r.RetentionCount == 0 { return nil @@ -24,7 +25,7 @@ func (r *System) DeleteUnretainedHistory() error { return nil } - err := r.clearBefore(targetElder) + err := r.clearBefore(ctx, targetElder) if err != nil { return err } @@ -38,16 +39,16 @@ func (r *System) DeleteUnretainedHistory() error { // Tick triggers the reaper system to update itself, deleted unretained history // if it is the appropriate time. -func (r *System) Tick() { +func (r *System) Tick(ctx context.Context) { if time.Now().Before(r.nextRun) { return } - r.runOnce() + r.runOnce(ctx) r.nextRun = time.Now().Add(1 * time.Hour) } -func (r *System) runOnce() { +func (r *System) runOnce(ctx context.Context) { defer func() { if rec := recover(); rec != nil { err := errors.FromPanic(rec) @@ -56,13 +57,13 @@ func (r *System) runOnce() { } }() - err := r.DeleteUnretainedHistory() + err := r.DeleteUnretainedHistory(ctx) if err != nil { log.Errorf("reaper failed: %s", err) } } -func (r *System) clearBefore(seq int32) error { +func (r *System) clearBefore(ctx context.Context, seq int32) error { log.WithField("new_elder", seq).Info("reaper: clearing") start, end, err := toid.LedgerRangeInclusive(1, seq-1) @@ -70,7 +71,7 @@ func (r *System) clearBefore(seq int32) error { return err } - err = r.HistoryQ.DeleteRangeAll(start, end) + err = r.HistoryQ.DeleteRangeAll(ctx, start, end) if err != nil { return err } diff --git a/services/horizon/internal/reap/system_test.go b/services/horizon/internal/reap/system_test.go index c5a081d719..695a5ea3dc 100644 --- a/services/horizon/internal/reap/system_test.go +++ b/services/horizon/internal/reap/system_test.go @@ -21,30 +21,30 @@ func TestDeleteUnretainedHistory(t *testing.T) { prev int cur int ) - err := db.GetRaw(&prev, `SELECT COUNT(*) FROM history_ledgers`) + err := db.GetRaw(tt.Ctx, &prev, `SELECT COUNT(*) FROM history_ledgers`) tt.Require.NoError(err) - err = sys.DeleteUnretainedHistory() + err = sys.DeleteUnretainedHistory(tt.Ctx) if tt.Assert.NoError(err) { - err = db.GetRaw(&cur, `SELECT COUNT(*) FROM history_ledgers`) + err = db.GetRaw(tt.Ctx, &cur, `SELECT COUNT(*) FROM history_ledgers`) tt.Require.NoError(err) tt.Assert.Equal(prev, cur, "Ledgers deleted when RetentionCount == 0") } ledgerState.SetStatus(tt.LoadLedgerStatus()) sys.RetentionCount = 10 - err = sys.DeleteUnretainedHistory() + err = sys.DeleteUnretainedHistory(tt.Ctx) if tt.Assert.NoError(err) { - err = db.GetRaw(&cur, `SELECT COUNT(*) FROM history_ledgers`) + err = db.GetRaw(tt.Ctx, &cur, `SELECT COUNT(*) FROM history_ledgers`) tt.Require.NoError(err) tt.Assert.Equal(10, cur) } ledgerState.SetStatus(tt.LoadLedgerStatus()) sys.RetentionCount = 1 - err = sys.DeleteUnretainedHistory() + err = sys.DeleteUnretainedHistory(tt.Ctx) if tt.Assert.NoError(err) { - err = db.GetRaw(&cur, `SELECT COUNT(*) FROM history_ledgers`) + err = db.GetRaw(tt.Ctx, &cur, `SELECT COUNT(*) FROM history_ledgers`) tt.Require.NoError(err) tt.Assert.Equal(1, cur) } diff --git a/services/horizon/internal/test/t.go b/services/horizon/internal/test/t.go index 1c80c85ab0..d1992bd142 100644 --- a/services/horizon/internal/test/t.go +++ b/services/horizon/internal/test/t.go @@ -18,8 +18,7 @@ import ( // CoreSession returns a db.Session instance pointing at the stellar core test database func (t *T) CoreSession() *db.Session { return &db.Session{ - DB: t.CoreDB, - Ctx: t.Ctx, + DB: t.CoreDB, } } @@ -38,8 +37,7 @@ func (t *T) Finish() { // database func (t *T) HorizonSession() *db.Session { return &db.Session{ - DB: t.HorizonDB, - Ctx: t.Ctx, + DB: t.HorizonDB, } } @@ -137,7 +135,7 @@ func (t *T) UnmarshalExtras(r io.Reader) map[string]string { func (t *T) LoadLedgerStatus() ledger.Status { var next ledger.Status - err := t.CoreSession().GetRaw(&next, ` + err := t.CoreSession().GetRaw(t.Ctx, &next, ` SELECT COALESCE(MAX(ledgerseq), 0) as core_latest FROM ledgerheaders @@ -147,7 +145,7 @@ func (t *T) LoadLedgerStatus() ledger.Status { panic(err) } - err = t.HorizonSession().GetRaw(&next, ` + err = t.HorizonSession().GetRaw(t.Ctx, &next, ` SELECT COALESCE(MIN(sequence), 0) as history_elder, COALESCE(MAX(sequence), 0) as history_latest diff --git a/services/horizon/internal/test/trades/main.go b/services/horizon/internal/test/trades/main.go index 5a07624024..111ad0414c 100644 --- a/services/horizon/internal/test/trades/main.go +++ b/services/horizon/internal/test/trades/main.go @@ -2,6 +2,8 @@ package trades import ( + "context" + "github.com/stellar/go/keypair" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/support/time" @@ -49,17 +51,18 @@ func IngestTestTrade( D: xdr.Int32(amountSold), } - accounts, err := q.CreateAccounts([]string{seller.Address(), buyer.Address()}, 2) + ctx := context.Background() + accounts, err := q.CreateAccounts(ctx, []string{seller.Address(), buyer.Address()}, 2) if err != nil { return err } - assets, err := q.CreateAssets([]xdr.Asset{assetBought, assetSold}, 2) + assets, err := q.CreateAssets(ctx, []xdr.Asset{assetBought, assetSold}, 2) if err != nil { return err } batch := q.NewTradeBatchInsertBuilder(0) - batch.Add(history.InsertTrade{ + batch.Add(ctx, history.InsertTrade{ HistoryOperationID: opCounter, Order: 0, BuyOfferExists: false, @@ -72,7 +75,7 @@ func IngestTestTrade( BuyerAccountID: accounts[buyer.Address()], SellerAccountID: accounts[seller.Address()], }) - return batch.Exec() + return batch.Exec(ctx) } //PopulateTestTrades generates and ingests trades between two assets according to given parameters diff --git a/services/horizon/internal/txsub/helpers_test.go b/services/horizon/internal/txsub/helpers_test.go index 3483ca28cb..e73ed4be1d 100644 --- a/services/horizon/internal/txsub/helpers_test.go +++ b/services/horizon/internal/txsub/helpers_test.go @@ -28,13 +28,13 @@ type mockDBQ struct { mock.Mock } -func (m *mockDBQ) BeginTx(txOpts *sql.TxOptions) error { - args := m.Called(txOpts) +func (m *mockDBQ) BeginTx(ctx context.Context, txOpts *sql.TxOptions) error { + args := m.Called(ctx, txOpts) return args.Error(0) } -func (m *mockDBQ) Rollback() error { - args := m.Called() +func (m *mockDBQ) Rollback(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } @@ -43,12 +43,12 @@ func (m *mockDBQ) NoRows(err error) bool { return args.Bool(0) } -func (m *mockDBQ) GetSequenceNumbers(addresses []string) (map[string]uint64, error) { - args := m.Called(addresses) +func (m *mockDBQ) GetSequenceNumbers(ctx context.Context, addresses []string) (map[string]uint64, error) { + args := m.Called(ctx, addresses) return args.Get(0).(map[string]uint64), args.Error(1) } -func (m *mockDBQ) TransactionByHash(dest interface{}, hash string) error { - args := m.Called(dest, hash) +func (m *mockDBQ) TransactionByHash(ctx context.Context, dest interface{}, hash string) error { + args := m.Called(ctx, dest, hash) return args.Error(0) } diff --git a/services/horizon/internal/txsub/results.go b/services/horizon/internal/txsub/results.go index f8cb0099e0..844816700b 100644 --- a/services/horizon/internal/txsub/results.go +++ b/services/horizon/internal/txsub/results.go @@ -1,6 +1,7 @@ package txsub import ( + "context" "database/sql" "github.com/stellar/go/services/horizon/internal/db2/history" @@ -8,10 +9,10 @@ import ( "github.com/stellar/go/xdr" ) -func txResultByHash(db HorizonDB, hash string) (history.Transaction, error) { +func txResultByHash(ctx context.Context, db HorizonDB, hash string) (history.Transaction, error) { // query history database var hr history.Transaction - err := db.TransactionByHash(&hr, hash) + err := db.TransactionByHash(ctx, &hr, hash) if err == nil { return txResultFromHistory(hr) } @@ -45,20 +46,20 @@ func txResultFromHistory(tx history.Transaction) (history.Transaction, error) { // queries execute on different ledgers. In this case, txsub can mistakenly respond with a bad_seq error // because the first query occurs when the tx is not yet ingested and the second query occurs when the tx // is ingested. -func checkTxAlreadyExists(db HorizonDB, hash, sourceAddress string) (history.Transaction, uint64, error) { - err := db.BeginTx(&sql.TxOptions{ +func checkTxAlreadyExists(ctx context.Context, db HorizonDB, hash, sourceAddress string) (history.Transaction, uint64, error) { + err := db.BeginTx(ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }) if err != nil { return history.Transaction{}, 0, errors.Wrap(err, "cannot start repeatable read tx") } - defer db.Rollback() + defer db.Rollback(ctx) - tx, err := txResultByHash(db, hash) + tx, err := txResultByHash(ctx, db, hash) if err == ErrNoResults { var sequenceNumbers map[string]uint64 - sequenceNumbers, err = db.GetSequenceNumbers([]string{sourceAddress}) + sequenceNumbers, err = db.GetSequenceNumbers(ctx, []string{sourceAddress}) if err != nil { return tx, 0, errors.Wrapf(err, "cannot fetch sequence number for %v", sourceAddress) } diff --git a/services/horizon/internal/txsub/results_test.go b/services/horizon/internal/txsub/results_test.go index 2277245879..09e1ea5b18 100644 --- a/services/horizon/internal/txsub/results_test.go +++ b/services/horizon/internal/txsub/results_test.go @@ -13,7 +13,7 @@ func TestGetIngestedTx(t *testing.T) { defer tt.Finish() q := &history.Q{Session: tt.HorizonSession()} hash := "2374e99349b9ef7dba9a5db3339b78fda8f34777b1af33ba468ad5c0df946d4d" - tx, err := txResultByHash(q, hash) + tx, err := txResultByHash(tt.Ctx, q, hash) tt.Assert.NoError(err) tt.Assert.Equal(hash, tx.TransactionHash) } @@ -25,7 +25,7 @@ func TestGetMissingTx(t *testing.T) { q := &history.Q{Session: tt.HorizonSession()} hash := "adf1efb9fd253f53cbbe6230c131d2af19830328e52b610464652d67d2fb7195" - _, err := txResultByHash(q, hash) + _, err := txResultByHash(tt.Ctx, q, hash) tt.Assert.Equal(ErrNoResults, err) } @@ -36,6 +36,6 @@ func TestGetFailedTx(t *testing.T) { q := &history.Q{Session: tt.HorizonSession()} hash := "aa168f12124b7c196c0adaee7c73a64d37f99428cacb59a91ff389626845e7cf" - _, err := txResultByHash(q, hash) + _, err := txResultByHash(tt.Ctx, q, hash) tt.Assert.Equal("AAAAAAAAAGT/////AAAAAQAAAAAAAAAB/////gAAAAA=", err.(*FailedTransactionError).ResultXDR) } diff --git a/services/horizon/internal/txsub/system.go b/services/horizon/internal/txsub/system.go index 903931b47c..86b5fe3fc4 100644 --- a/services/horizon/internal/txsub/system.go +++ b/services/horizon/internal/txsub/system.go @@ -14,10 +14,10 @@ import ( ) type HorizonDB interface { - TransactionByHash(dest interface{}, hash string) error - GetSequenceNumbers(addresses []string) (map[string]uint64, error) - BeginTx(*sql.TxOptions) error - Rollback() error + TransactionByHash(ctx context.Context, dest interface{}, hash string) error + GetSequenceNumbers(ctx context.Context, addresses []string) (map[string]uint64, error) + BeginTx(context.Context, *sql.TxOptions) error + Rollback(context.Context) error NoRows(error) bool } @@ -98,7 +98,7 @@ func (sys *System) Submit( "tx": rawTx, }).Info("Processing transaction") - tx, sequenceNumber, err := checkTxAlreadyExists(db, hash, sourceAddress) + tx, sequenceNumber, err := checkTxAlreadyExists(ctx, db, hash, sourceAddress) if err == nil { sys.Log.Ctx(ctx).WithField("hash", hash).Info("Found submission result in a DB") sys.finish(ctx, hash, response, Result{Transaction: tx}) @@ -164,7 +164,7 @@ func (sys *System) Submit( } // If error is txBAD_SEQ, check for the result again - tx, err = txResultByHash(db, hash) + tx, err = txResultByHash(ctx, db, hash) if err == nil { // If the found use it as the result sys.finish(ctx, hash, response, Result{Transaction: tx}) @@ -187,7 +187,7 @@ func (sys *System) waitUntilAccountSequence(ctx context.Context, db HorizonDB, s defer timer.Stop() for { - sequenceNumbers, err := db.GetSequenceNumbers([]string{sourceAddress}) + sequenceNumbers, err := db.GetSequenceNumbers(ctx, []string{sourceAddress}) if err != nil { sys.Log.Ctx(ctx). WithError(err). @@ -287,15 +287,15 @@ func (sys *System) Tick(ctx context.Context) { Isolation: sql.LevelRepeatableRead, ReadOnly: true, } - if err := db.BeginTx(options); err != nil { + if err := db.BeginTx(ctx, options); err != nil { logger.WithError(err).Error("could not start repeatable read transaction for txsub tick") return } - defer db.Rollback() + defer db.Rollback(ctx) addys := sys.SubmissionQueue.Addresses() if len(addys) > 0 { - curSeq, err := db.GetSequenceNumbers(addys) + curSeq, err := db.GetSequenceNumbers(ctx, addys) if err != nil { logger.WithStack(err).Error(err) return @@ -305,7 +305,7 @@ func (sys *System) Tick(ctx context.Context) { } for _, hash := range sys.Pending.Pending(ctx) { - tx, err := txResultByHash(db, hash) + tx, err := txResultByHash(ctx, db, hash) if err == nil { logger.WithField("hash", hash).Debug("finishing open submission") diff --git a/services/horizon/internal/txsub/system_test.go b/services/horizon/internal/txsub/system_test.go index 96d0ed3b1a..145b5a4bf1 100644 --- a/services/horizon/internal/txsub/system_test.go +++ b/services/horizon/internal/txsub/system_test.go @@ -122,14 +122,14 @@ func (suite *SystemTestSuite) TearDownTest() { // Returns the result provided by the ResultProvider. func (suite *SystemTestSuite) TestSubmit_Basic() { - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Run(func(args mock.Arguments) { - ptr := args.Get(0).(*history.Transaction) + ptr := args.Get(1).(*history.Transaction) *ptr = suite.successTx.Transaction }). Return(nil).Once() @@ -157,15 +157,15 @@ func getMetricValue(metric prometheus.Metric) *dto.Metric { // Returns the error from submission if no result is found by hash and the suite.submitter returns an error. func (suite *SystemTestSuite) TestSubmit_NotFoundError() { - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Return(sql.ErrNoRows).Once() suite.db.On("NoRows", sql.ErrNoRows).Return(true).Once() - suite.db.On("GetSequenceNumbers", []string{suite.unmuxedSource.Address()}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{suite.unmuxedSource.Address()}). Return(map[string]uint64{suite.unmuxedSource.Address(): 0}, nil). Once() @@ -187,23 +187,23 @@ func (suite *SystemTestSuite) TestSubmit_NotFoundError() { // If the error is bad_seq and the result at the transaction's sequence number is for the same hash, return result. func (suite *SystemTestSuite) TestSubmit_BadSeq() { suite.submitter.R = suite.badSeq - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Return(sql.ErrNoRows).Once() suite.db.On("NoRows", sql.ErrNoRows).Return(true).Once() - suite.db.On("GetSequenceNumbers", []string{suite.unmuxedSource.Address()}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{suite.unmuxedSource.Address()}). Return(map[string]uint64{suite.unmuxedSource.Address(): 0}, nil). Once() - suite.db.On("GetSequenceNumbers", []string{suite.unmuxedSource.Address()}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{suite.unmuxedSource.Address()}). Return(map[string]uint64{suite.unmuxedSource.Address(): 1}, nil). Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Run(func(args mock.Arguments) { - ptr := args.Get(0).(*history.Transaction) + ptr := args.Get(1).(*history.Transaction) *ptr = suite.successTx.Transaction }). Return(nil).Once() @@ -223,18 +223,18 @@ func (suite *SystemTestSuite) TestSubmit_BadSeq() { // If error is bad_seq and no result is found, return error. func (suite *SystemTestSuite) TestSubmit_BadSeqNotFound() { suite.submitter.R = suite.badSeq - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Return(sql.ErrNoRows).Twice() suite.db.On("NoRows", sql.ErrNoRows).Return(true).Twice() - suite.db.On("GetSequenceNumbers", []string{suite.unmuxedSource.Address()}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{suite.unmuxedSource.Address()}). Return(map[string]uint64{suite.unmuxedSource.Address(): 0}, nil). Times(3) - suite.db.On("GetSequenceNumbers", []string{suite.unmuxedSource.Address()}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{suite.unmuxedSource.Address()}). Return(map[string]uint64{suite.unmuxedSource.Address(): 1}, nil). Once() @@ -255,15 +255,15 @@ func (suite *SystemTestSuite) TestSubmit_BadSeqNotFound() { // If no result found and no error submitting, add to open transaction list. func (suite *SystemTestSuite) TestSubmit_OpenTransactionList() { - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Return(sql.ErrNoRows).Once() suite.db.On("NoRows", sql.ErrNoRows).Return(true).Once() - suite.db.On("GetSequenceNumbers", []string{suite.unmuxedSource.Address()}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{suite.unmuxedSource.Address()}). Return(map[string]uint64{suite.unmuxedSource.Address(): 0}, nil). Once() @@ -283,11 +283,11 @@ func (suite *SystemTestSuite) TestSubmit_OpenTransactionList() { // Tick should be a no-op if there are no open submissions. func (suite *SystemTestSuite) TestTick_Noop() { - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() + suite.db.On("Rollback", suite.ctx).Return(nil).Once() suite.system.Tick(suite.ctx) } @@ -298,15 +298,15 @@ func (suite *SystemTestSuite) TestTick_Noop() { // `sys.Sequences.Get(addys)` is delayed by 1 second. It allows to simulate two // calls to `Tick()` executed at the same time. func (suite *SystemTestSuite) TestTick_Deadlock() { - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() + suite.db.On("Rollback", suite.ctx).Return(nil).Once() // Start first Tick suite.system.SubmissionQueue.Push("address", 0) - suite.db.On("GetSequenceNumbers", []string{"address"}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{"address"}). Return(map[string]uint64{}, nil). Run(func(args mock.Arguments) { // Start second tick @@ -322,12 +322,12 @@ func (suite *SystemTestSuite) TestTick_FinishesTransactions() { l := make(chan Result, 1) suite.system.Pending.Add(suite.ctx, suite.successTx.Transaction.TransactionHash, l) - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Return(sql.ErrNoRows).Once() suite.db.On("NoRows", sql.ErrNoRows).Return(true).Once() @@ -336,14 +336,14 @@ func (suite *SystemTestSuite) TestTick_FinishesTransactions() { assert.Equal(suite.T(), 0, len(l)) assert.Equal(suite.T(), 1, len(suite.system.Pending.Pending(suite.ctx))) - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Run(func(args mock.Arguments) { - ptr := args.Get(0).(*history.Transaction) + ptr := args.Get(1).(*history.Transaction) *ptr = suite.successTx.Transaction }). Return(nil).Once() @@ -374,15 +374,15 @@ func (suite *SystemTestSuite) TestTickFinishFeeBumpTransaction() { }, } - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, innerHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, innerHash). Return(sql.ErrNoRows).Once() suite.db.On("NoRows", sql.ErrNoRows).Return(true).Once() - suite.db.On("GetSequenceNumbers", []string{"GABQGAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2MX"}). + suite.db.On("GetSequenceNumbers", suite.ctx, []string{"GABQGAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2MX"}). Return(map[string]uint64{"GABQGAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2MX": 96}, nil). Once() @@ -390,14 +390,14 @@ func (suite *SystemTestSuite) TestTickFinishFeeBumpTransaction() { assert.Equal(suite.T(), 0, len(l)) assert.Equal(suite.T(), 1, len(suite.system.Pending.Pending(suite.ctx))) - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, innerHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, innerHash). Run(func(args mock.Arguments) { - ptr := args.Get(0).(*history.Transaction) + ptr := args.Get(1).(*history.Transaction) *ptr = feeBumpTx.Transaction }). Return(nil).Once() @@ -418,12 +418,12 @@ func (suite *SystemTestSuite) TestTick_RemovesStaleSubmissions() { suite.system.Pending.Add(suite.ctx, suite.successTx.Transaction.TransactionHash, l) <-time.After(101 * time.Millisecond) - suite.db.On("BeginTx", &sql.TxOptions{ + suite.db.On("BeginTx", suite.ctx, &sql.TxOptions{ Isolation: sql.LevelRepeatableRead, ReadOnly: true, }).Return(nil).Once() - suite.db.On("Rollback").Return(nil).Once() - suite.db.On("TransactionByHash", mock.Anything, suite.successTx.Transaction.TransactionHash). + suite.db.On("Rollback", suite.ctx).Return(nil).Once() + suite.db.On("TransactionByHash", suite.ctx, mock.Anything, suite.successTx.Transaction.TransactionHash). Return(sql.ErrNoRows).Once() suite.db.On("NoRows", sql.ErrNoRows).Return(true).Once() diff --git a/services/ticker/cmd/clean.go b/services/ticker/cmd/clean.go index 08bbbffd87..5582029bcb 100644 --- a/services/ticker/cmd/clean.go +++ b/services/ticker/cmd/clean.go @@ -1,6 +1,7 @@ package cmd import ( + "context" "time" "github.com/lib/pq" @@ -45,7 +46,7 @@ var cmdCleanTrades = &cobra.Command{ now := time.Now() minDate := now.AddDate(0, 0, -DaysToKeep) Logger.Infof("Deleting trade entries older than %d days", DaysToKeep) - err = session.DeleteOldTrades(minDate) + err = session.DeleteOldTrades(context.Background(), minDate) if err != nil { Logger.Fatal("could not delete trade entries:", err) } diff --git a/services/ticker/cmd/generate.go b/services/ticker/cmd/generate.go index b726d78f54..75c8dfb49b 100644 --- a/services/ticker/cmd/generate.go +++ b/services/ticker/cmd/generate.go @@ -1,6 +1,7 @@ package cmd import ( + "context" "github.com/lib/pq" "github.com/spf13/cobra" ticker "github.com/stellar/go/services/ticker/internal" @@ -74,7 +75,7 @@ var cmdGenerateAssetData = &cobra.Command{ } Logger.Infof("Starting asset data generation, outputting to: %s\n", AssetsOutFile) - err = ticker.GenerateAssetsFile(&session, Logger, AssetsOutFile) + err = ticker.GenerateAssetsFile(context.Background(), &session, Logger, AssetsOutFile) if err != nil { Logger.Fatal("could not generate asset data:", err) } diff --git a/services/ticker/cmd/ingest.go b/services/ticker/cmd/ingest.go index 17869319d3..4068a8d7f5 100644 --- a/services/ticker/cmd/ingest.go +++ b/services/ticker/cmd/ingest.go @@ -54,7 +54,8 @@ var cmdIngestAssets = &cobra.Command{ } defer session.DB.Close() - err = ticker.RefreshAssets(&session, Client, Logger) + ctx := context.Background() + err = ticker.RefreshAssets(ctx, &session, Client, Logger) if err != nil { Logger.Fatal("could not refresh asset database:", err) } @@ -76,20 +77,20 @@ var cmdIngestTrades = &cobra.Command{ } defer session.DB.Close() + ctx := context.Background() numDays := float32(BackfillHours) / 24.0 Logger.Infof( "Backfilling Trade data for the past %d hour(s) [%.2f days]\n", BackfillHours, numDays, ) - err = ticker.BackfillTrades(&session, Client, Logger, BackfillHours, 0) + err = ticker.BackfillTrades(ctx, &session, Client, Logger, BackfillHours, 0) if err != nil { Logger.Fatal("could not refresh trade database:", err) } if ShouldStream { Logger.Info("Streaming new data (this is a continuous process)") - ctx := context.Background() err = ticker.StreamTrades(ctx, &session, Client, Logger) if err != nil { Logger.Fatal("could not refresh trade database:", err) diff --git a/services/ticker/internal/actions_asset.go b/services/ticker/internal/actions_asset.go index 3106d8ab57..c34f8ad182 100644 --- a/services/ticker/internal/actions_asset.go +++ b/services/ticker/internal/actions_asset.go @@ -1,6 +1,7 @@ package ticker import ( + "context" "encoding/json" "strings" "time" @@ -13,7 +14,7 @@ import ( ) // RefreshAssets scrapes the most recent asset list and ingests then into the db. -func RefreshAssets(s *tickerdb.TickerSession, c *horizonclient.Client, l *hlog.Entry) (err error) { +func RefreshAssets(ctx context.Context, s *tickerdb.TickerSession, c *horizonclient.Client, l *hlog.Entry) (err error) { sc := scraper.ScraperConfig{ Client: c, Logger: l, @@ -28,14 +29,14 @@ func RefreshAssets(s *tickerdb.TickerSession, c *horizonclient.Client, l *hlog.E if dbIssuer.PublicKey == "" { dbIssuer.PublicKey = finalAsset.Issuer } - issuerID, err := s.InsertOrUpdateIssuer(&dbIssuer, []string{"public_key"}) + issuerID, err := s.InsertOrUpdateIssuer(ctx, &dbIssuer, []string{"public_key"}) if err != nil { l.Error("Error inserting issuer:", dbIssuer, err) continue } dbAsset := finalAssetToDBAsset(finalAsset, issuerID) - err = s.InsertOrUpdateAsset(&dbAsset, []string{"code", "issuer_account", "issuer_id"}) + err = s.InsertOrUpdateAsset(ctx, &dbAsset, []string{"code", "issuer_account", "issuer_id"}) if err != nil { l.Error("Error inserting asset:", dbAsset, err) } @@ -45,10 +46,10 @@ func RefreshAssets(s *tickerdb.TickerSession, c *horizonclient.Client, l *hlog.E } // GenerateAssetsFile generates a file with the info about all valid scraped Assets -func GenerateAssetsFile(s *tickerdb.TickerSession, l *hlog.Entry, filename string) error { +func GenerateAssetsFile(ctx context.Context, s *tickerdb.TickerSession, l *hlog.Entry, filename string) error { l.Infoln("Retrieving asset data from db...") var assets []Asset - validAssets, err := s.GetAssetsWithNestedIssuer() + validAssets, err := s.GetAssetsWithNestedIssuer(ctx) if err != nil { return err } diff --git a/services/ticker/internal/actions_market.go b/services/ticker/internal/actions_market.go index 933a1b4f94..c60f57be8a 100644 --- a/services/ticker/internal/actions_market.go +++ b/services/ticker/internal/actions_market.go @@ -1,6 +1,7 @@ package ticker import ( + "context" "encoding/json" "time" @@ -40,8 +41,9 @@ func GenerateMarketSummary(s *tickerdb.TickerSession) (ms MarketSummary, err err now := time.Now() nowMillis := utils.TimeToUnixEpoch(now) nowRFC339 := utils.TimeToRFC3339(now) + ctx := context.Background() - dbMarkets, err := s.RetrieveMarketData() + dbMarkets, err := s.RetrieveMarketData(ctx) if err != nil { return } diff --git a/services/ticker/internal/actions_orderbook.go b/services/ticker/internal/actions_orderbook.go index e68b6db88c..ab39d10a2e 100644 --- a/services/ticker/internal/actions_orderbook.go +++ b/services/ticker/internal/actions_orderbook.go @@ -1,6 +1,7 @@ package ticker import ( + "context" "time" horizonclient "github.com/stellar/go/clients/horizonclient" @@ -17,9 +18,10 @@ func RefreshOrderbookEntries(s *tickerdb.TickerSession, c *horizonclient.Client, Client: c, Logger: l, } + ctx := context.Background() // Retrieve relevant markets for the past 7 days (168 hours): - mkts, err := s.Retrieve7DRelevantMarkets() + mkts, err := s.Retrieve7DRelevantMarkets(ctx) if err != nil { return errors.Wrap(err, "could not retrieve partial markets") } @@ -39,7 +41,7 @@ func RefreshOrderbookEntries(s *tickerdb.TickerSession, c *horizonclient.Client, } dbOS := orderbookStatsToDBOrderbookStats(ob, mkt.BaseAssetID, mkt.CounterAssetID) - err = s.InsertOrUpdateOrderbookStats(&dbOS, []string{"base_asset_id", "counter_asset_id"}) + err = s.InsertOrUpdateOrderbookStats(ctx, &dbOS, []string{"base_asset_id", "counter_asset_id"}) if err != nil { l.Error(errors.Wrap(err, "could not insert orderbook stats into db")) continue @@ -60,7 +62,7 @@ func RefreshOrderbookEntries(s *tickerdb.TickerSession, c *horizonclient.Client, } dbIOS := orderbookStatsToDBOrderbookStats(iob, mkt.CounterAssetID, mkt.BaseAssetID) - err = s.InsertOrUpdateOrderbookStats(&dbIOS, []string{"base_asset_id", "counter_asset_id"}) + err = s.InsertOrUpdateOrderbookStats(ctx, &dbIOS, []string{"base_asset_id", "counter_asset_id"}) if err != nil { l.Error(errors.Wrap(err, "could not insert reverse orderbook stats into db")) } diff --git a/services/ticker/internal/actions_trade.go b/services/ticker/internal/actions_trade.go index 1e2ab885ad..abfefc3034 100644 --- a/services/ticker/internal/actions_trade.go +++ b/services/ticker/internal/actions_trade.go @@ -29,7 +29,7 @@ func StreamTrades( handler := func(trade hProtocol.Trade) { l.Infof("New trade arrived. ID: %v; Close Time: %v\n", trade.ID, trade.LedgerCloseTime) scraper.NormalizeTradeAssets(&trade) - bID, cID, err := findBaseAndCounter(s, trade) + bID, cID, err := findBaseAndCounter(ctx, s, trade) if err != nil { l.Errorln(err) return @@ -40,14 +40,14 @@ func StreamTrades( return } - err = s.BulkInsertTrades([]tickerdb.Trade{dbTrade}) + err = s.BulkInsertTrades(ctx, []tickerdb.Trade{dbTrade}) if err != nil { l.Errorln("Could not insert trade in database: ", trade.ID) } } // Ensure we start streaming from the last stored trade - lastTrade, err := s.GetLastTrade() + lastTrade, err := s.GetLastTrade(ctx) if err != nil { return err } @@ -59,6 +59,7 @@ func StreamTrades( // BackfillTrades ingest the most recent trades (limited to numDays) directly from Horizon // into the database. func BackfillTrades( + ctx context.Context, s *tickerdb.TickerSession, c *horizonclient.Client, l *hlog.Entry, @@ -80,7 +81,7 @@ func BackfillTrades( for _, trade := range trades { var bID, cID int32 - bID, cID, err = findBaseAndCounter(s, trade) + bID, cID, err = findBaseAndCounter(ctx, s, trade) if err != nil { continue } @@ -95,7 +96,7 @@ func BackfillTrades( } l.Infof("Inserting %d entries in the database.\n", len(dbTrades)) - err = s.BulkInsertTrades(dbTrades) + err = s.BulkInsertTrades(ctx, dbTrades) if err != nil { fmt.Println(err) } @@ -105,8 +106,9 @@ func BackfillTrades( // findBaseAndCounter tries to find the Base and Counter assets IDs in the database, // and returns an error if it doesn't find any. -func findBaseAndCounter(s *tickerdb.TickerSession, trade hProtocol.Trade) (bID int32, cID int32, err error) { +func findBaseAndCounter(ctx context.Context, s *tickerdb.TickerSession, trade hProtocol.Trade) (bID int32, cID int32, err error) { bFound, bID, err := s.GetAssetByCodeAndIssuerAccount( + ctx, trade.BaseAssetCode, trade.BaseAssetIssuer, ) @@ -115,6 +117,7 @@ func findBaseAndCounter(s *tickerdb.TickerSession, trade hProtocol.Trade) (bID i } cFound, cID, err := s.GetAssetByCodeAndIssuerAccount( + ctx, trade.CounterAssetCode, trade.CounterAssetIssuer, ) diff --git a/services/ticker/internal/gql/resolvers_asset.go b/services/ticker/internal/gql/resolvers_asset.go index 3428403747..a385220105 100644 --- a/services/ticker/internal/gql/resolvers_asset.go +++ b/services/ticker/internal/gql/resolvers_asset.go @@ -1,14 +1,15 @@ package gql import ( + "context" "errors" "github.com/stellar/go/services/ticker/internal/tickerdb" ) // Assets resolves the assets() GraphQL query. -func (r *resolver) Assets() (assets []*asset, err error) { - dbAssets, err := r.db.GetAllValidAssets() +func (r *resolver) Assets(ctx context.Context) (assets []*asset, err error) { + dbAssets, err := r.db.GetAllValidAssets(ctx) if err != nil { // obfuscating sql errors to avoid exposing underlying // implementation diff --git a/services/ticker/internal/gql/resolvers_issuer.go b/services/ticker/internal/gql/resolvers_issuer.go index 02f66dc6c2..15bca92e5d 100644 --- a/services/ticker/internal/gql/resolvers_issuer.go +++ b/services/ticker/internal/gql/resolvers_issuer.go @@ -1,14 +1,15 @@ package gql import ( + "context" "errors" "github.com/stellar/go/services/ticker/internal/tickerdb" ) // Issuers resolves the issuers() GraphQL query. -func (r *resolver) Issuers() (issuers []*tickerdb.Issuer, err error) { - dbIssuers, err := r.db.GetAllIssuers() +func (r *resolver) Issuers(ctx context.Context) (issuers []*tickerdb.Issuer, err error) { + dbIssuers, err := r.db.GetAllIssuers(ctx) if err != nil { // obfuscating sql errors to avoid exposing underlying // implementation diff --git a/services/ticker/internal/gql/resolvers_market.go b/services/ticker/internal/gql/resolvers_market.go index 6efcba3822..5712da9df2 100644 --- a/services/ticker/internal/gql/resolvers_market.go +++ b/services/ticker/internal/gql/resolvers_market.go @@ -1,6 +1,7 @@ package gql import ( + "context" "errors" "fmt" "strings" @@ -11,7 +12,7 @@ import ( ) // Markets resolves the markets() GraphQL query. -func (r *resolver) Markets(args struct { +func (r *resolver) Markets(ctx context.Context, args struct { BaseAssetCode *string BaseAssetIssuer *string CounterAssetCode *string @@ -28,7 +29,7 @@ func (r *resolver) Markets(args struct { pairName = fmt.Sprintf("%s:%s / %s:%s", *args.BaseAssetCode, *args.BaseAssetIssuer, *args.CounterAssetCode, *args.CounterAssetIssuer) } - dbMarkets, err := r.db.RetrievePartialMarkets( + dbMarkets, err := r.db.RetrievePartialMarkets(ctx, args.BaseAssetCode, args.BaseAssetIssuer, args.CounterAssetCode, @@ -57,7 +58,7 @@ func (r *resolver) Markets(args struct { } // Ticker resolves the ticker() GraphQL query (TODO) -func (r *resolver) Ticker( +func (r *resolver) Ticker(ctx context.Context, args struct { Code *string PairNames *[]*string @@ -74,7 +75,7 @@ func (r *resolver) Ticker( return } - dbMarkets, err := r.db.RetrievePartialAggMarkets(args.Code, args.PairNames, numHours) + dbMarkets, err := r.db.RetrievePartialAggMarkets(ctx, args.Code, args.PairNames, numHours) if err != nil { // obfuscating sql errors to avoid exposing underlying // implementation diff --git a/services/ticker/internal/tickerdb/helpers.go b/services/ticker/internal/tickerdb/helpers.go index ace6cf1b09..deebdc245a 100644 --- a/services/ticker/internal/tickerdb/helpers.go +++ b/services/ticker/internal/tickerdb/helpers.go @@ -1,6 +1,7 @@ package tickerdb import ( + "context" "errors" "fmt" "reflect" @@ -172,7 +173,7 @@ func orderBaseAndCounter( // performUpsertQuery introspects a dbStruct interface{} and performs an insert query // (if the conflictConstraint isn't broken), otherwise it updates the instance on the // db, preserving the old values for the fields in preserveFields -func (s *TickerSession) performUpsertQuery(dbStruct interface{}, tableName string, conflictConstraint string, preserveFields []string) error { +func (s *TickerSession) performUpsertQuery(ctx context.Context, dbStruct interface{}, tableName string, conflictConstraint string, preserveFields []string) error { dbFields := getDBFieldTags(dbStruct, true) dbFieldsString := strings.Join(dbFields, ", ") dbValues := getDBFieldValues(dbStruct, true) @@ -183,6 +184,6 @@ func (s *TickerSession) performUpsertQuery(dbStruct interface{}, tableName strin qs := fmt.Sprintf("INSERT INTO %s (", tableName) + dbFieldsString + ")" qs += " VALUES (" + generatePlaceholders(dbValues) + ")" qs += " " + createOnConflictFragment(conflictConstraint, toUpdateFields) + ";" - _, err := s.ExecRaw(qs, dbValues...) + _, err := s.ExecRaw(ctx, qs, dbValues...) return err } diff --git a/services/ticker/internal/tickerdb/main.go b/services/ticker/internal/tickerdb/main.go index 2f539a53de..369feec247 100644 --- a/services/ticker/internal/tickerdb/main.go +++ b/services/ticker/internal/tickerdb/main.go @@ -1,7 +1,6 @@ package tickerdb import ( - "context" "time" "github.com/jmoiron/sqlx" @@ -175,7 +174,6 @@ func CreateSession(driverName, dataSourceName string) (session TickerSession, er } session.DB = dbconn - session.Ctx = context.Background() return } diff --git a/services/ticker/internal/tickerdb/queries_asset.go b/services/ticker/internal/tickerdb/queries_asset.go index 5d4e636c32..a55e861ebb 100644 --- a/services/ticker/internal/tickerdb/queries_asset.go +++ b/services/ticker/internal/tickerdb/queries_asset.go @@ -1,14 +1,18 @@ package tickerdb +import ( + "context" +) + // InsertOrUpdateAsset inserts an Asset on the database (if new), // or updates an existing one -func (s *TickerSession) InsertOrUpdateAsset(a *Asset, preserveFields []string) (err error) { - return s.performUpsertQuery(*a, "assets", "assets_code_issuer_account", preserveFields) +func (s *TickerSession) InsertOrUpdateAsset(ctx context.Context, a *Asset, preserveFields []string) (err error) { + return s.performUpsertQuery(ctx, *a, "assets", "assets_code_issuer_account", preserveFields) } // GetAssetByCodeAndIssuerAccount searches for an Asset with the given code // and public key, and returns its ID in case it is found. -func (s *TickerSession) GetAssetByCodeAndIssuerAccount( +func (s *TickerSession) GetAssetByCodeAndIssuerAccount(ctx context.Context, code string, issuerAccount string, ) (found bool, id int32, err error) { @@ -20,7 +24,7 @@ func (s *TickerSession) GetAssetByCodeAndIssuerAccount( "assets.code = ? AND assets.issuer_account = ?", code, issuerAccount, - ).Exec() + ).Exec(ctx) if err != nil { return } @@ -34,20 +38,20 @@ func (s *TickerSession) GetAssetByCodeAndIssuerAccount( // GetAllValidAssets returns a slice with all assets in the database // with is_valid = true -func (s *TickerSession) GetAllValidAssets() (assets []Asset, err error) { +func (s *TickerSession) GetAllValidAssets(ctx context.Context) (assets []Asset, err error) { tbl := s.GetTable("assets") err = tbl.Select( &assets, "assets.is_valid = TRUE", - ).Exec() + ).Exec(ctx) return } // GetAssetsWithNestedIssuer returns a slice with all assets in the database // with is_valid = true, also adding the nested Issuer attribute -func (s *TickerSession) GetAssetsWithNestedIssuer() (assets []Asset, err error) { +func (s *TickerSession) GetAssetsWithNestedIssuer(ctx context.Context) (assets []Asset, err error) { const q = ` SELECT a.code, a.issuer_account, a.type, a.num_accounts, a.auth_required, a.auth_revocable, @@ -62,7 +66,7 @@ func (s *TickerSession) GetAssetsWithNestedIssuer() (assets []Asset, err error) WHERE a.is_valid = TRUE ` - rows, err := s.DB.Query(q) + rows, err := s.DB.QueryContext(ctx, q) if err != nil { return } diff --git a/services/ticker/internal/tickerdb/queries_issuer.go b/services/ticker/internal/tickerdb/queries_issuer.go index 072edb40d8..1b0d0f2d2c 100644 --- a/services/ticker/internal/tickerdb/queries_issuer.go +++ b/services/ticker/internal/tickerdb/queries_issuer.go @@ -1,6 +1,7 @@ package tickerdb import ( + "context" "strings" "github.com/stellar/go/services/ticker/internal/utils" @@ -8,7 +9,7 @@ import ( // InsertOrUpdateIssuer inserts an Issuer on the database (if new), // or updates an existing one -func (s *TickerSession) InsertOrUpdateIssuer(issuer *Issuer, preserveFields []string) (id int32, err error) { +func (s *TickerSession) InsertOrUpdateIssuer(ctx context.Context, issuer *Issuer, preserveFields []string) (id int32, err error) { dbFields := getDBFieldTags(*issuer, true) dbFieldsString := strings.Join(dbFields, ", ") dbValues := getDBFieldValues(*issuer, true) @@ -21,7 +22,7 @@ func (s *TickerSession) InsertOrUpdateIssuer(issuer *Issuer, preserveFields []st qs += " " + createOnConflictFragment("public_key_unique", toUpdateFields) qs += " RETURNING id;" - rows, err := s.QueryRaw(qs, dbValues...) + rows, err := s.QueryRaw(ctx, qs, dbValues...) if err != nil { return } @@ -33,7 +34,7 @@ func (s *TickerSession) InsertOrUpdateIssuer(issuer *Issuer, preserveFields []st } // GetAllIssuers returns a slice with all issuers in the database -func (s *TickerSession) GetAllIssuers() (issuers []Issuer, err error) { - err = s.SelectRaw(&issuers, "SELECT * FROM issuers") +func (s *TickerSession) GetAllIssuers(ctx context.Context) (issuers []Issuer, err error) { + err = s.SelectRaw(ctx, &issuers, "SELECT * FROM issuers") return } diff --git a/services/ticker/internal/tickerdb/queries_market.go b/services/ticker/internal/tickerdb/queries_market.go index 10d7b91142..7765ea59d5 100644 --- a/services/ticker/internal/tickerdb/queries_market.go +++ b/services/ticker/internal/tickerdb/queries_market.go @@ -1,6 +1,7 @@ package tickerdb import ( + "context" "errors" "fmt" "strings" @@ -8,14 +9,14 @@ import ( // RetrieveMarketData retrieves the 24h- and 7d aggregated market data for all // markets that were active during this period. -func (s *TickerSession) RetrieveMarketData() (markets []Market, err error) { - err = s.SelectRaw(&markets, marketQuery) +func (s *TickerSession) RetrieveMarketData(ctx context.Context) (markets []Market, err error) { + err = s.SelectRaw(ctx, &markets, marketQuery) return } // RetrievePartialAggMarkets retrieves the aggregated market data for all // markets (or for a specific one if PairNames != nil) for a given period. -func (s *TickerSession) RetrievePartialAggMarkets( +func (s *TickerSession) RetrievePartialAggMarkets(ctx context.Context, code *string, pairNames *[]*string, numHoursAgo int, @@ -56,7 +57,7 @@ func (s *TickerSession) RetrievePartialAggMarkets( argsInterface[i] = v } - err = s.SelectRaw(&partialMkts, q, argsInterface...) + err = s.SelectRaw(ctx, &partialMkts, q, argsInterface...) return } @@ -97,7 +98,7 @@ func (s *TickerSession) constructPartialAggMarketsWhere( // RetrievePartialMarkets retrieves data in the PartialMarket format from the database. // It optionally filters the data according to the provided base and counter asset params // provided, as well as the numHoursAgo time offset. -func (s *TickerSession) RetrievePartialMarkets( +func (s *TickerSession) RetrievePartialMarkets(ctx context.Context, baseAssetCode *string, baseAssetIssuer *string, counterAssetCode *string, @@ -133,13 +134,13 @@ func (s *TickerSession) RetrievePartialMarkets( for i, v := range args { argsInterface[i] = v } - err = s.SelectRaw(&partialMkts, q, argsInterface...) + err = s.SelectRaw(ctx, &partialMkts, q, argsInterface...) return } // Retrieve7DRelevantMarkets retrieves the base and counter asset data of the markets // that were relevant in the last 7-day period. -func (s *TickerSession) Retrieve7DRelevantMarkets() (partialMkts []PartialMarket, err error) { +func (s *TickerSession) Retrieve7DRelevantMarkets(ctx context.Context) (partialMkts []PartialMarket, err error) { q := ` SELECT ba.id as base_asset_id, ba.type AS base_asset_type, ba.code AS base_asset_code, ba.issuer_account AS base_asset_issuer, @@ -150,7 +151,7 @@ func (s *TickerSession) Retrieve7DRelevantMarkets() (partialMkts []PartialMarket WHERE ba.is_valid = TRUE AND ca.is_valid = TRUE AND t.ledger_close_time > now() - interval '7 days' GROUP BY ba.id, ba.type, ba.code, ba.issuer_account, ca.id, ca.type, ca.code, ca.issuer_account ` - err = s.SelectRaw(&partialMkts, q) + err = s.SelectRaw(ctx, &partialMkts, q) return } diff --git a/services/ticker/internal/tickerdb/queries_orderbook.go b/services/ticker/internal/tickerdb/queries_orderbook.go index e31dfee1c9..9b8bc5c855 100644 --- a/services/ticker/internal/tickerdb/queries_orderbook.go +++ b/services/ticker/internal/tickerdb/queries_orderbook.go @@ -1,7 +1,11 @@ package tickerdb +import ( + "context" +) + // InsertOrUpdateOrderbookStats inserts an OrdebookStats entry on the database (if new), // or updates an existing one -func (s *TickerSession) InsertOrUpdateOrderbookStats(o *OrderbookStats, preserveFields []string) (err error) { - return s.performUpsertQuery(*o, "orderbook_stats", "orderbook_stats_base_counter_asset_key", preserveFields) +func (s *TickerSession) InsertOrUpdateOrderbookStats(ctx context.Context, o *OrderbookStats, preserveFields []string) (err error) { + return s.performUpsertQuery(ctx, *o, "orderbook_stats", "orderbook_stats_base_counter_asset_key", preserveFields) } diff --git a/services/ticker/internal/tickerdb/queries_trade.go b/services/ticker/internal/tickerdb/queries_trade.go index d3cb5e2be8..8a5cc5db70 100644 --- a/services/ticker/internal/tickerdb/queries_trade.go +++ b/services/ticker/internal/tickerdb/queries_trade.go @@ -1,6 +1,7 @@ package tickerdb import ( + "context" "math" "strings" "time" @@ -9,14 +10,14 @@ import ( // BulkInsertTrades inserts a slice of trades in the database. Trades // that are already in the database (i.e. horizon_id already exists) // are ignored. -func (s *TickerSession) BulkInsertTrades(trades []Trade) (err error) { +func (s *TickerSession) BulkInsertTrades(ctx context.Context, trades []Trade) (err error) { if len(trades) <= 50 { - return performInsertTrades(s, trades) + return performInsertTrades(ctx, s, trades) } chunks := chunkifyDBTrades(trades, 50) for _, chunk := range chunks { - err = performInsertTrades(s, chunk) + err = performInsertTrades(ctx, s, chunk) if err != nil { return } @@ -26,14 +27,14 @@ func (s *TickerSession) BulkInsertTrades(trades []Trade) (err error) { } // GetLastTrade returns the newest Trade object in the database. -func (s *TickerSession) GetLastTrade() (trade Trade, err error) { - err = s.GetRaw(&trade, "SELECT * FROM trades ORDER BY ledger_close_time DESC LIMIT 1") +func (s *TickerSession) GetLastTrade(ctx context.Context) (trade Trade, err error) { + err = s.GetRaw(ctx, &trade, "SELECT * FROM trades ORDER BY ledger_close_time DESC LIMIT 1") return } // DeleteOldTrades deletes trades in the database older than minDate. -func (s *TickerSession) DeleteOldTrades(minDate time.Time) error { - _, err := s.ExecRaw("DELETE FROM trades WHERE ledger_close_time < ?", minDate) +func (s *TickerSession) DeleteOldTrades(ctx context.Context, minDate time.Time) error { + _, err := s.ExecRaw(ctx, "DELETE FROM trades WHERE ledger_close_time < ?", minDate) return err } @@ -61,7 +62,7 @@ func chunkifyDBTrades(sl []Trade, chunkSize int) [][]Trade { return chunkedSlice } -func performInsertTrades(s *TickerSession, trades []Trade) (err error) { +func performInsertTrades(ctx context.Context, s *TickerSession, trades []Trade) (err error) { var t Trade var placeholders string var dbValues []interface{} @@ -83,6 +84,6 @@ func performInsertTrades(s *TickerSession, trades []Trade) (err error) { qs += " VALUES " + placeholders qs += " ON CONFLICT ON CONSTRAINT trades_horizon_id_key DO NOTHING;" - _, err = s.ExecRaw(qs, dbValues...) + _, err = s.ExecRaw(ctx, qs, dbValues...) return } diff --git a/services/ticker/internal/tickerdb/tickerdb_test/queries_asset_test.go b/services/ticker/internal/tickerdb/tickerdb_test/queries_asset_test.go index 7888890a8b..323e9b1e59 100644 --- a/services/ticker/internal/tickerdb/tickerdb_test/queries_asset_test.go +++ b/services/ticker/internal/tickerdb/tickerdb_test/queries_asset_test.go @@ -19,8 +19,8 @@ func TestInsertOrUpdateAsset(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -41,10 +41,10 @@ func TestInsertOrUpdateAsset(t *testing.T) { Name: name, } tbl := session.GetTable("issuers") - _, err = tbl.Insert(issuer).IgnoreCols("id").Exec() + _, err = tbl.Insert(issuer).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var dbIssuer tickerdb.Issuer - err = session.GetRaw(&dbIssuer, ` + err = session.GetRaw(ctx, &dbIssuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -62,11 +62,11 @@ func TestInsertOrUpdateAsset(t *testing.T) { LastValid: firstTime, LastChecked: firstTime, } - err = session.InsertOrUpdateAsset(&a, []string{"code", "issuer_account", "issuer_id"}) + err = session.InsertOrUpdateAsset(ctx, &a, []string{"code", "issuer_account", "issuer_id"}) require.NoError(t, err) var dbAsset1 tickerdb.Asset - err = session.GetRaw(&dbAsset1, ` + err = session.GetRaw(ctx, &dbAsset1, ` SELECT * FROM assets ORDER BY id DESC @@ -93,11 +93,11 @@ func TestInsertOrUpdateAsset(t *testing.T) { t.Log("secondTime:", secondTime) a.LastValid = secondTime a.LastChecked = secondTime - err = session.InsertOrUpdateAsset(&a, []string{"code", "issuer_account", "issuer_id"}) + err = session.InsertOrUpdateAsset(ctx, &a, []string{"code", "issuer_account", "issuer_id"}) require.NoError(t, err) var dbAsset2 tickerdb.Asset - err = session.GetRaw(&dbAsset2, ` + err = session.GetRaw(ctx, &dbAsset2, ` SELECT * FROM assets ORDER BY id DESC @@ -128,10 +128,10 @@ func TestInsertOrUpdateAsset(t *testing.T) { t.Log("thirdTime:", thirdTime) a.LastValid = thirdTime a.LastChecked = thirdTime - err = session.InsertOrUpdateAsset(&a, []string{"code", "issuer_id", "last_valid", "last_checked", "issuer_account"}) + err = session.InsertOrUpdateAsset(ctx, &a, []string{"code", "issuer_id", "last_valid", "last_checked", "issuer_account"}) require.NoError(t, err) var dbAsset3 tickerdb.Asset - err = session.GetRaw(&dbAsset3, ` + err = session.GetRaw(ctx, &dbAsset3, ` SELECT * FROM assets ORDER BY id DESC @@ -163,8 +163,8 @@ func TestGetAssetByCodeAndIssuerAccount(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -185,10 +185,10 @@ func TestGetAssetByCodeAndIssuerAccount(t *testing.T) { Name: name, } tbl := session.GetTable("issuers") - _, err = tbl.Insert(issuer).IgnoreCols("id").Exec() + _, err = tbl.Insert(issuer).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var dbIssuer tickerdb.Issuer - err = session.GetRaw(&dbIssuer, ` + err = session.GetRaw(ctx, &dbIssuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -205,11 +205,11 @@ func TestGetAssetByCodeAndIssuerAccount(t *testing.T) { LastValid: firstTime, LastChecked: firstTime, } - err = session.InsertOrUpdateAsset(&a, []string{"code", "issuer_account", "issuer_id"}) + err = session.InsertOrUpdateAsset(ctx, &a, []string{"code", "issuer_account", "issuer_id"}) require.NoError(t, err) var dbAsset tickerdb.Asset - err = session.GetRaw(&dbAsset, ` + err = session.GetRaw(ctx, &dbAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -218,13 +218,13 @@ func TestGetAssetByCodeAndIssuerAccount(t *testing.T) { require.NoError(t, err) // Searching for an asset that exists: - found, id, err := session.GetAssetByCodeAndIssuerAccount(code, issuerAccount) + found, id, err := session.GetAssetByCodeAndIssuerAccount(ctx, code, issuerAccount) require.NoError(t, err) assert.Equal(t, dbAsset.ID, id) assert.True(t, found) // Now searching for an asset that does not exist: - found, _, err = session.GetAssetByCodeAndIssuerAccount( + found, _, err = session.GetAssetByCodeAndIssuerAccount(ctx, "NONEXISTENT CODE", issuerAccount, ) diff --git a/services/ticker/internal/tickerdb/tickerdb_test/queries_issuer_test.go b/services/ticker/internal/tickerdb/tickerdb_test/queries_issuer_test.go index 7c6a939ef4..66f88fbd35 100644 --- a/services/ticker/internal/tickerdb/tickerdb_test/queries_issuer_test.go +++ b/services/ticker/internal/tickerdb/tickerdb_test/queries_issuer_test.go @@ -18,8 +18,8 @@ func TestInsertOrUpdateIssuer(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -37,11 +37,11 @@ func TestInsertOrUpdateIssuer(t *testing.T) { PublicKey: publicKey, Name: name, } - id, err := session.InsertOrUpdateIssuer(&issuer, []string{"public_key"}) + id, err := session.InsertOrUpdateIssuer(ctx, &issuer, []string{"public_key"}) require.NoError(t, err) var dbIssuer tickerdb.Issuer - err = session.GetRaw(&dbIssuer, ` + err = session.GetRaw(ctx, &dbIssuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -57,11 +57,11 @@ func TestInsertOrUpdateIssuer(t *testing.T) { PublicKey: "ANOTHERKEY", Name: "Hello from the other side", } - id2, err := session.InsertOrUpdateIssuer(&issuer2, []string{"public_key"}) + id2, err := session.InsertOrUpdateIssuer(ctx, &issuer2, []string{"public_key"}) require.NoError(t, err) var dbIssuer2 tickerdb.Issuer - err = session.GetRaw(&dbIssuer2, ` + err = session.GetRaw(ctx, &dbIssuer2, ` SELECT * FROM issuers ORDER BY id DESC @@ -79,11 +79,11 @@ func TestInsertOrUpdateIssuer(t *testing.T) { PublicKey: publicKey, Name: name3, } - id, err = session.InsertOrUpdateIssuer(&issuer3, []string{"public_key"}) + id, err = session.InsertOrUpdateIssuer(ctx, &issuer3, []string{"public_key"}) require.NoError(t, err) var dbIssuer3 tickerdb.Issuer - err = session.GetRaw( + err = session.GetRaw(ctx, &dbIssuer3, "SELECT * FROM issuers WHERE id=?", id, diff --git a/services/ticker/internal/tickerdb/tickerdb_test/queries_market_test.go b/services/ticker/internal/tickerdb/tickerdb_test/queries_market_test.go index 7932ff08e3..599580f8aa 100644 --- a/services/ticker/internal/tickerdb/tickerdb_test/queries_market_test.go +++ b/services/ticker/internal/tickerdb/tickerdb_test/queries_market_test.go @@ -21,8 +21,8 @@ func TestRetrieveMarketData(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -37,10 +37,10 @@ func TestRetrieveMarketData(t *testing.T) { _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: "GCF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB", Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer tickerdb.Issuer - err = session.GetRaw(&issuer, ` + err = session.GetRaw(ctx, &issuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -49,14 +49,14 @@ func TestRetrieveMarketData(t *testing.T) { require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "XLM", IssuerID: issuer.ID, IsValid: true, }, []string{"code", "issuer_id"}) require.NoError(t, err) var xlmAsset tickerdb.Asset - err = session.GetRaw(&xlmAsset, ` + err = session.GetRaw(ctx, &xlmAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -65,14 +65,14 @@ func TestRetrieveMarketData(t *testing.T) { require.NoError(t, err) // Adding another asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "BTC", IssuerID: issuer.ID, IsValid: true, }, []string{"code", "issuer_id"}) require.NoError(t, err) var btcAsset tickerdb.Asset - err = session.GetRaw(&btcAsset, ` + err = session.GetRaw(ctx, &btcAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -81,14 +81,14 @@ func TestRetrieveMarketData(t *testing.T) { require.NoError(t, err) // Adding a third asset: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "ETH", IssuerID: issuer.ID, IsValid: true, }, []string{"code", "issuer_id"}) require.NoError(t, err) var ethAsset tickerdb.Asset - err = session.GetRaw(ðAsset, ` + err = session.GetRaw(ctx, ðAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -155,7 +155,7 @@ func TestRetrieveMarketData(t *testing.T) { LedgerCloseTime: oneMonthAgo, }, } - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) // Adding some orderbook stats: @@ -173,14 +173,14 @@ func TestRetrieveMarketData(t *testing.T) { SpreadMidPoint: 0.35, UpdatedAt: obTime, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats, []string{"base_asset_id", "counter_asset_id"}, ) require.NoError(t, err) var obBTCETH1 tickerdb.OrderbookStats - err = session.GetRaw(&obBTCETH1, ` + err = session.GetRaw(ctx, &obBTCETH1, ` SELECT * FROM orderbook_stats ORDER BY id DESC @@ -201,14 +201,14 @@ func TestRetrieveMarketData(t *testing.T) { SpreadMidPoint: 0.36, UpdatedAt: obTime, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats, []string{"base_asset_id", "counter_asset_id"}, ) require.NoError(t, err) var obBTCETH2 tickerdb.OrderbookStats - err = session.GetRaw(&obBTCETH2, ` + err = session.GetRaw(ctx, &obBTCETH2, ` SELECT * FROM orderbook_stats ORDER BY id DESC @@ -217,7 +217,7 @@ func TestRetrieveMarketData(t *testing.T) { require.NoError(t, err) assert.NotEqual(t, obBTCETH1.ID, obBTCETH2.ID) - markets, err := session.RetrieveMarketData() + markets, err := session.RetrieveMarketData(ctx) require.NoError(t, err) assert.Equal(t, 2, len(markets)) @@ -307,6 +307,7 @@ func TestRetrieveMarketData(t *testing.T) { func TestRetrievePartialMarkets(t *testing.T) { session := tickerdbtest.SetupTickerTestSession(t, "../migrations") defer session.DB.Close() + ctx := context.Background() issuer1PK := "GCF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB" issuer2PK := "ABF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB" @@ -314,7 +315,7 @@ func TestRetrievePartialMarkets(t *testing.T) { tenMinutesAgo := now.Add(-10 * time.Minute) oneHourAgo := now.Add(-1 * time.Hour) - partialMkts, err := session.RetrievePartialMarkets( + partialMkts, err := session.RetrievePartialMarkets(ctx, nil, nil, nil, nil, 12, ) require.NoError(t, err) @@ -385,7 +386,7 @@ func TestRetrievePartialMarkets(t *testing.T) { assert.Equal(t, 0.70, btceth2Mkt.LowestAskReverse) // Now let's use the same data, but aggregating by asset pair - partialAggMkts, err := session.RetrievePartialAggMarkets(nil, nil, 12) + partialAggMkts, err := session.RetrievePartialAggMarkets(ctx, nil, nil, 12) require.NoError(t, err) assert.Equal(t, 2, len(partialAggMkts)) @@ -411,7 +412,7 @@ func TestRetrievePartialMarkets(t *testing.T) { // Validate the pair name parsing: pairNames := []*string{&btcEthStr} - partialAggMkts, err = session.RetrievePartialAggMarkets(nil, &pairNames, 12) + partialAggMkts, err = session.RetrievePartialAggMarkets(ctx, nil, &pairNames, 12) require.NoError(t, err) assert.Equal(t, 1, len(partialAggMkts)) assert.Equal(t, int32(3), partialAggMkts[0].TradeCount) @@ -433,7 +434,7 @@ func TestRetrievePartialMarkets(t *testing.T) { // Validate that both markets are parsed. btcXlmStr := "BTC_XLM" pairNames = []*string{&btcEthStr, &btcXlmStr} - partialAggMkts, err = session.RetrievePartialAggMarkets(nil, &pairNames, 12) + partialAggMkts, err = session.RetrievePartialAggMarkets(ctx, nil, &pairNames, 12) require.NoError(t, err) assert.Equal(t, 2, len(partialAggMkts)) assert.Equal(t, int32(3), partialAggMkts[0].TradeCount) @@ -441,12 +442,12 @@ func TestRetrievePartialMarkets(t *testing.T) { // Validate that passing a code works. btcStr := "BTC" - partialAggMkts, err = session.RetrievePartialAggMarkets(&btcStr, nil, 12) + partialAggMkts, err = session.RetrievePartialAggMarkets(ctx, &btcStr, nil, 12) require.NoError(t, err) assert.Equal(t, 2, len(partialAggMkts)) // Make sure there's an error with a non-nil code and non-nil pair names. - partialAggMkts, err = session.RetrievePartialAggMarkets(&btcStr, &pairNames, 12) + partialAggMkts, err = session.RetrievePartialAggMarkets(ctx, &btcStr, &pairNames, 12) require.Error(t, err) } @@ -456,8 +457,8 @@ func Test24hStatsFallback(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -472,10 +473,10 @@ func Test24hStatsFallback(t *testing.T) { _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: "GCF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB", Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer tickerdb.Issuer - err = session.GetRaw(&issuer, ` + err = session.GetRaw(ctx, &issuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -484,14 +485,14 @@ func Test24hStatsFallback(t *testing.T) { require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "XLM", IssuerID: issuer.ID, IsValid: true, }, []string{"code", "issuer_id"}) require.NoError(t, err) var xlmAsset tickerdb.Asset - err = session.GetRaw(&xlmAsset, ` + err = session.GetRaw(ctx, &xlmAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -500,14 +501,14 @@ func Test24hStatsFallback(t *testing.T) { require.NoError(t, err) // Adding another asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "BTC", IssuerID: issuer.ID, IsValid: true, }, []string{"code", "issuer_id"}) require.NoError(t, err) var btcAsset tickerdb.Asset - err = session.GetRaw(&btcAsset, ` + err = session.GetRaw(ctx, &btcAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -541,10 +542,10 @@ func Test24hStatsFallback(t *testing.T) { LedgerCloseTime: threeDaysAgo, }, } - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) - markets, err := session.RetrieveMarketData() + markets, err := session.RetrieveMarketData(ctx) require.NoError(t, err) assert.Equal(t, 1, len(markets)) mkt := markets[0] @@ -562,8 +563,8 @@ func TestPreferAnchorAssetCode(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -578,10 +579,10 @@ func TestPreferAnchorAssetCode(t *testing.T) { _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: "GCF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB", Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer tickerdb.Issuer - err = session.GetRaw(&issuer, ` + err = session.GetRaw(ctx, &issuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -590,14 +591,14 @@ func TestPreferAnchorAssetCode(t *testing.T) { require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "XLM", IssuerID: issuer.ID, IsValid: true, }, []string{"code", "issuer_id"}) require.NoError(t, err) var xlmAsset tickerdb.Asset - err = session.GetRaw(&xlmAsset, ` + err = session.GetRaw(ctx, &xlmAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -606,7 +607,7 @@ func TestPreferAnchorAssetCode(t *testing.T) { require.NoError(t, err) // Adding another asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "EURT", IssuerID: issuer.ID, IsValid: true, @@ -614,7 +615,7 @@ func TestPreferAnchorAssetCode(t *testing.T) { }, []string{"code", "issuer_id"}) require.NoError(t, err) var btcAsset tickerdb.Asset - err = session.GetRaw(&btcAsset, ` + err = session.GetRaw(ctx, &btcAsset, ` SELECT * FROM assets ORDER BY id DESC @@ -648,17 +649,17 @@ func TestPreferAnchorAssetCode(t *testing.T) { LedgerCloseTime: threeDaysAgo, }, } - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) - markets, err := session.RetrieveMarketData() + markets, err := session.RetrieveMarketData(ctx) require.NoError(t, err) require.Equal(t, 1, len(markets)) for _, mkt := range markets { require.Equal(t, "XLM_EUR", mkt.TradePair) } - partialAggMkts, err := session.RetrievePartialAggMarkets(nil, nil, 168) + partialAggMkts, err := session.RetrievePartialAggMarkets(ctx, nil, nil, 168) require.NoError(t, err) assert.Equal(t, 1, len(partialAggMkts)) for _, aggMkt := range partialAggMkts { diff --git a/services/ticker/internal/tickerdb/tickerdb_test/queries_orderbook_test.go b/services/ticker/internal/tickerdb/tickerdb_test/queries_orderbook_test.go index aeb1a4fcfa..c3cc9a8884 100644 --- a/services/ticker/internal/tickerdb/tickerdb_test/queries_orderbook_test.go +++ b/services/ticker/internal/tickerdb/tickerdb_test/queries_orderbook_test.go @@ -18,8 +18,8 @@ func TestInsertOrUpdateOrderbokStats(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -40,10 +40,10 @@ func TestInsertOrUpdateOrderbokStats(t *testing.T) { Name: name, } tbl := session.GetTable("issuers") - _, err = tbl.Insert(issuer).IgnoreCols("id").Exec() + _, err = tbl.Insert(issuer).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var dbIssuer tickerdb.Issuer - err = session.GetRaw(&dbIssuer, ` + err = session.GetRaw(ctx, &dbIssuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -60,11 +60,11 @@ func TestInsertOrUpdateOrderbokStats(t *testing.T) { LastValid: firstTime, LastChecked: firstTime, } - err = session.InsertOrUpdateAsset(&a, []string{"code", "issuer_account", "issuer_id"}) + err = session.InsertOrUpdateAsset(ctx, &a, []string{"code", "issuer_account", "issuer_id"}) require.NoError(t, err) var dbAsset1 tickerdb.Asset - err = session.GetRaw(&dbAsset1, ` + err = session.GetRaw(ctx, &dbAsset1, ` SELECT * FROM assets ORDER BY id DESC @@ -82,11 +82,11 @@ func TestInsertOrUpdateOrderbokStats(t *testing.T) { secondTime := time.Now() a.LastValid = secondTime a.LastChecked = secondTime - err = session.InsertOrUpdateAsset(&a, []string{"code", "issuer_account", "issuer_id"}) + err = session.InsertOrUpdateAsset(ctx, &a, []string{"code", "issuer_account", "issuer_id"}) require.NoError(t, err) var dbAsset2 tickerdb.Asset - err = session.GetRaw(&dbAsset2, ` + err = session.GetRaw(ctx, &dbAsset2, ` SELECT * FROM assets ORDER BY id DESC @@ -109,14 +109,14 @@ func TestInsertOrUpdateOrderbokStats(t *testing.T) { SpreadMidPoint: 0.35, UpdatedAt: obTime, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats, []string{"base_asset_id", "counter_asset_id"}, ) require.NoError(t, err) var dbOS tickerdb.OrderbookStats - err = session.GetRaw(&dbOS, ` + err = session.GetRaw(ctx, &dbOS, ` SELECT * FROM orderbook_stats ORDER BY id DESC @@ -151,14 +151,14 @@ func TestInsertOrUpdateOrderbokStats(t *testing.T) { SpreadMidPoint: 0.7, UpdatedAt: obTime2, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats2, []string{"base_asset_id", "counter_asset_id", "lowest_ask"}, ) require.NoError(t, err) var dbOS2 tickerdb.OrderbookStats - err = session.GetRaw(&dbOS2, ` + err = session.GetRaw(ctx, &dbOS2, ` SELECT * FROM orderbook_stats ORDER BY id DESC diff --git a/services/ticker/internal/tickerdb/tickerdb_test/queries_trade_test.go b/services/ticker/internal/tickerdb/tickerdb_test/queries_trade_test.go index dffd03364d..9e404252a7 100644 --- a/services/ticker/internal/tickerdb/tickerdb_test/queries_trade_test.go +++ b/services/ticker/internal/tickerdb/tickerdb_test/queries_trade_test.go @@ -20,8 +20,8 @@ func TestBulkInsertTrades(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -36,10 +36,10 @@ func TestBulkInsertTrades(t *testing.T) { _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: "GCF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB", Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer tickerdb.Issuer - err = session.GetRaw(&issuer, ` + err = session.GetRaw(ctx, &issuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -48,13 +48,13 @@ func TestBulkInsertTrades(t *testing.T) { require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "XLM", IssuerID: issuer.ID, }, []string{"code", "issuer_id"}) require.NoError(t, err) var asset1 tickerdb.Asset - err = session.GetRaw(&asset1, ` + err = session.GetRaw(ctx, &asset1, ` SELECT * FROM assets ORDER BY id DESC @@ -63,13 +63,13 @@ func TestBulkInsertTrades(t *testing.T) { require.NoError(t, err) // Adding another asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "BTC", IssuerID: issuer.ID, }, []string{"code", "issuer_id"}) require.NoError(t, err) var asset2 tickerdb.Asset - err = session.GetRaw(&asset2, ` + err = session.GetRaw(ctx, &asset2, ` SELECT * FROM assets ORDER BY id DESC @@ -95,11 +95,11 @@ func TestBulkInsertTrades(t *testing.T) { LedgerCloseTime: time.Now(), }, } - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) // Ensure only two were created: - rows, err := session.QueryRaw("SELECT * FROM trades") + rows, err := session.QueryRaw(ctx, "SELECT * FROM trades") require.NoError(t, err) rowsCount := 0 for rows.Next() { @@ -108,10 +108,10 @@ func TestBulkInsertTrades(t *testing.T) { assert.Equal(t, 2, rowsCount) // Re-insert the same trades and check if count remains = 2: - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) - rows, err = session.QueryRaw("SELECT * FROM trades") + rows, err = session.QueryRaw(ctx, "SELECT * FROM trades") require.NoError(t, err) rowsCount2 := 0 for rows.Next() { @@ -126,8 +126,8 @@ func TestGetLastTrade(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -138,7 +138,7 @@ func TestGetLastTrade(t *testing.T) { require.NoError(t, err) // Sanity Check (there are no trades in the database) - _, err = session.GetLastTrade() + _, err = session.GetLastTrade(ctx) require.Error(t, err) // Adding a seed issuer to be used later: @@ -146,10 +146,10 @@ func TestGetLastTrade(t *testing.T) { _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: "GCF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB", Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer tickerdb.Issuer - err = session.GetRaw(&issuer, ` + err = session.GetRaw(ctx, &issuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -158,13 +158,13 @@ func TestGetLastTrade(t *testing.T) { require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "XLM", IssuerID: issuer.ID, }, []string{"code", "issuer_id"}) require.NoError(t, err) var asset1 tickerdb.Asset - err = session.GetRaw(&asset1, ` + err = session.GetRaw(ctx, &asset1, ` SELECT * FROM assets ORDER BY id DESC @@ -173,13 +173,13 @@ func TestGetLastTrade(t *testing.T) { require.NoError(t, err) // Adding another asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "BTC", IssuerID: issuer.ID, }, []string{"code", "issuer_id"}) require.NoError(t, err) var asset2 tickerdb.Asset - err = session.GetRaw(&asset2, ` + err = session.GetRaw(ctx, &asset2, ` SELECT * FROM assets ORDER BY id DESC @@ -216,10 +216,10 @@ func TestGetLastTrade(t *testing.T) { } // Re-insert the same trades and check if count remains = 2: - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) - lastTrade, err := session.GetLastTrade() + lastTrade, err := session.GetLastTrade(ctx) require.NoError(t, err) assert.WithinDuration(t, now.Local(), lastTrade.LedgerCloseTime.Local(), 10*time.Millisecond) } @@ -230,8 +230,8 @@ func TestDeleteOldTrades(t *testing.T) { var session tickerdb.TickerSession session.DB = db.Open() - session.Ctx = context.Background() defer session.DB.Close() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -246,10 +246,10 @@ func TestDeleteOldTrades(t *testing.T) { _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: "GCF3TQXKZJNFJK7HCMNE2O2CUNKCJH2Y2ROISTBPLC7C5EIA5NNG2XZB", Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer tickerdb.Issuer - err = session.GetRaw(&issuer, ` + err = session.GetRaw(ctx, &issuer, ` SELECT * FROM issuers ORDER BY id DESC @@ -258,13 +258,13 @@ func TestDeleteOldTrades(t *testing.T) { require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "XLM", IssuerID: issuer.ID, }, []string{"code", "issuer_id"}) require.NoError(t, err) var asset1 tickerdb.Asset - err = session.GetRaw(&asset1, ` + err = session.GetRaw(ctx, &asset1, ` SELECT * FROM assets ORDER BY id DESC @@ -273,13 +273,13 @@ func TestDeleteOldTrades(t *testing.T) { require.NoError(t, err) // Adding another asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "BTC", IssuerID: issuer.ID, }, []string{"code", "issuer_id"}) require.NoError(t, err) var asset2 tickerdb.Asset - err = session.GetRaw(&asset2, ` + err = session.GetRaw(ctx, &asset2, ` SELECT * FROM assets ORDER BY id DESC @@ -323,16 +323,16 @@ func TestDeleteOldTrades(t *testing.T) { LedgerCloseTime: oneYearAgo, }, } - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) // Deleting trades older than 1 day ago: - err = session.DeleteOldTrades(oneDayAgo) + err = session.DeleteOldTrades(ctx, oneDayAgo) require.NoError(t, err) var dbTrades []tickerdb.Trade var trade1, trade2 tickerdb.Trade - err = session.SelectRaw(&dbTrades, "SELECT * FROM trades") + err = session.SelectRaw(ctx, &dbTrades, "SELECT * FROM trades") require.NoError(t, err) assert.Equal(t, 2, len(dbTrades)) diff --git a/services/ticker/internal/tickerdb/tickerdbtest/tickerdbtest.go b/services/ticker/internal/tickerdb/tickerdbtest/tickerdbtest.go index b01998c521..34bebb6602 100644 --- a/services/ticker/internal/tickerdb/tickerdbtest/tickerdbtest.go +++ b/services/ticker/internal/tickerdb/tickerdbtest/tickerdbtest.go @@ -17,7 +17,7 @@ import ( func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerdb.TickerSession) { db := dbtest.Postgres(t) session.DB = db.Open() - session.Ctx = context.Background() + ctx := context.Background() // Run migrations to make sure the tests are run // on the most updated schema version @@ -33,11 +33,11 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: issuer1PK, Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer1 tickerdb.Issuer - err = session.GetRaw(&issuer1, ` + err = session.GetRaw(ctx, &issuer1, ` SELECT * FROM issuers WHERE public_key = ?`, @@ -50,11 +50,11 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd _, err = tbl.Insert(tickerdb.Issuer{ PublicKey: issuer2PK, Name: "FOO BAR", - }).IgnoreCols("id").Exec() + }).IgnoreCols("id").Exec(ctx) require.NoError(t, err) var issuer2 tickerdb.Issuer - err = session.GetRaw(&issuer2, ` + err = session.GetRaw(ctx, &issuer2, ` SELECT * FROM issuers WHERE public_key = ?`, @@ -63,7 +63,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "ETH", IssuerAccount: issuer1PK, IssuerID: issuer1.ID, @@ -71,7 +71,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd }, []string{"code", "issuer_id"}) require.NoError(t, err) var ethAsset1 tickerdb.Asset - err = session.GetRaw(ðAsset1, ` + err = session.GetRaw(ctx, ðAsset1, ` SELECT * FROM assets WHERE code = ? @@ -82,7 +82,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd require.NoError(t, err) // Adding a seed asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "ETH", IssuerAccount: issuer2PK, IssuerID: issuer2.ID, @@ -91,7 +91,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd require.NoError(t, err) var ethAsset2 tickerdb.Asset - err = session.GetRaw(ðAsset2, ` + err = session.GetRaw(ctx, ðAsset2, ` SELECT * FROM assets WHERE code = ? @@ -102,7 +102,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd require.NoError(t, err) // Adding another asset to be used later: - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "BTC", IssuerAccount: issuer1PK, IssuerID: issuer1.ID, @@ -111,7 +111,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd require.NoError(t, err) var btcAsset tickerdb.Asset - err = session.GetRaw(&btcAsset, ` + err = session.GetRaw(ctx, &btcAsset, ` SELECT * FROM assets WHERE code = ? @@ -166,7 +166,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd LedgerCloseTime: threeDaysAgo, }, } - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) // Adding some orderbook stats: @@ -184,14 +184,14 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd SpreadMidPoint: 0.35, UpdatedAt: obTime, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats, []string{"base_asset_id", "counter_asset_id"}, ) require.NoError(t, err) var obBTCETH1 tickerdb.OrderbookStats - err = session.GetRaw(&obBTCETH1, ` + err = session.GetRaw(ctx, &obBTCETH1, ` SELECT * FROM orderbook_stats ORDER BY id DESC @@ -211,14 +211,14 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd Spread: 0.55, SpreadMidPoint: 0.85, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats, []string{"base_asset_id", "counter_asset_id"}, ) require.NoError(t, err) var obETH1BTC tickerdb.OrderbookStats - err = session.GetRaw(&obETH1BTC, ` + err = session.GetRaw(ctx, &obETH1BTC, ` SELECT * FROM orderbook_stats ORDER BY id DESC @@ -239,14 +239,14 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd SpreadMidPoint: 0.36, UpdatedAt: obTime, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats, []string{"base_asset_id", "counter_asset_id"}, ) require.NoError(t, err) var obBTCETH2 tickerdb.OrderbookStats - err = session.GetRaw(&obBTCETH2, ` + err = session.GetRaw(ctx, &obBTCETH2, ` SELECT * FROM orderbook_stats ORDER BY id DESC @@ -267,14 +267,14 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd Spread: 150.0, SpreadMidPoint: 200.0, } - err = session.InsertOrUpdateOrderbookStats( + err = session.InsertOrUpdateOrderbookStats(ctx, &orderbookStats, []string{"base_asset_id", "counter_asset_id"}, ) require.NoError(t, err) var obETH2BTC tickerdb.OrderbookStats - err = session.GetRaw(&obETH2BTC, ` + err = session.GetRaw(ctx, &obETH2BTC, ` SELECT * FROM orderbook_stats ORDER BY id DESC @@ -283,7 +283,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd require.NoError(t, err) // Add an XLM asset. - err = session.InsertOrUpdateAsset(&tickerdb.Asset{ + err = session.InsertOrUpdateAsset(ctx, &tickerdb.Asset{ Code: "XLM", IssuerAccount: issuer1PK, IssuerID: issuer1.ID, @@ -292,7 +292,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd require.NoError(t, err) var xlmAsset tickerdb.Asset - err = session.GetRaw(&xlmAsset, ` + err = session.GetRaw(ctx, &xlmAsset, ` SELECT * FROM assets WHERE code = ? @@ -323,7 +323,7 @@ func SetupTickerTestSession(t *testing.T, migrationsDir string) (session tickerd LedgerCloseTime: now, }, } - err = session.BulkInsertTrades(trades) + err = session.BulkInsertTrades(ctx, trades) require.NoError(t, err) return diff --git a/support/db/batch_insert_builder.go b/support/db/batch_insert_builder.go index baa009ac8b..2bcc94beeb 100644 --- a/support/db/batch_insert_builder.go +++ b/support/db/batch_insert_builder.go @@ -1,6 +1,7 @@ package db import ( + "context" "fmt" "reflect" "sort" @@ -32,7 +33,7 @@ type BatchInsertBuilder struct { // (map keys). Otherwise, error will be returned. Please note that rows are not // added one by one but in batches when `Exec` is called (or `MaxBatchSize` is // reached). -func (b *BatchInsertBuilder) Row(row map[string]interface{}) error { +func (b *BatchInsertBuilder) Row(ctx context.Context, row map[string]interface{}) error { if b.columns == nil { b.columns = make([]string, 0, len(row)) b.rows = make([][]interface{}, 0) @@ -61,13 +62,13 @@ func (b *BatchInsertBuilder) Row(row map[string]interface{}) error { // Call Exec when MaxBatchSize is reached. if len(b.rows) == b.MaxBatchSize { - return b.Exec() + return b.Exec(ctx) } return nil } -func (b *BatchInsertBuilder) RowStruct(row interface{}) error { +func (b *BatchInsertBuilder) RowStruct(ctx context.Context, row interface{}) error { if b.columns == nil { b.columns = columnsForStruct(row) b.rows = make([][]interface{}, 0) @@ -93,7 +94,7 @@ func (b *BatchInsertBuilder) RowStruct(row interface{}) error { // Call Exec when MaxBatchSize is reached. if len(b.rows) == b.MaxBatchSize { - return b.Exec() + return b.Exec(ctx) } return nil @@ -109,7 +110,7 @@ func (b *BatchInsertBuilder) insertSQL() sq.InsertBuilder { // Exec inserts rows in batches. In case of errors it's possible that some batches // were added so this should be run in a DB transaction for easy rollbacks. -func (b *BatchInsertBuilder) Exec() error { +func (b *BatchInsertBuilder) Exec(ctx context.Context) error { sql := b.insertSQL() paramsCount := 0 @@ -118,7 +119,7 @@ func (b *BatchInsertBuilder) Exec() error { paramsCount += len(row) if paramsCount > postgresQueryMaxParams-2*len(b.columns) { - _, err := b.Table.Session.Exec(sql) + _, err := b.Table.Session.Exec(ctx, sql) if err != nil { return errors.Wrap(err, fmt.Sprintf("error adding values while inserting to %s", b.Table.Name)) } @@ -129,7 +130,7 @@ func (b *BatchInsertBuilder) Exec() error { // Insert last batch if paramsCount > 0 { - _, err := b.Table.Session.Exec(sql) + _, err := b.Table.Session.Exec(ctx, sql) if err != nil { return errors.Wrap(err, fmt.Sprintf("error adding values while inserting to %s", b.Table.Name)) } diff --git a/support/db/batch_insert_builder_test.go b/support/db/batch_insert_builder_test.go index 0463a1aefc..10077b0f51 100644 --- a/support/db/batch_insert_builder_test.go +++ b/support/db/batch_insert_builder_test.go @@ -23,32 +23,33 @@ type invalidHungerRow struct { func TestBatchInsertBuilder(t *testing.T) { db := dbtest.Postgres(t).Load(testSchema) defer db.Close() - sess := &Session{DB: db.Open(), Ctx: context.Background()} + sess := &Session{DB: db.Open()} defer sess.DB.Close() + ctx := context.Background() insertBuilder := &BatchInsertBuilder{ Table: sess.GetTable("people"), } // exec on the empty set should produce no errors - assert.NoError(t, insertBuilder.Exec()) + assert.NoError(t, insertBuilder.Exec(ctx)) var err error - err = insertBuilder.Row(map[string]interface{}{ + err = insertBuilder.Row(ctx, map[string]interface{}{ "name": "bubba", "hunger_level": "120", }) assert.NoError(t, err) - err = insertBuilder.RowStruct(hungerRow{ + err = insertBuilder.RowStruct(ctx, hungerRow{ Name: "bubba2", HungerLevel: "1202", }) assert.NoError(t, err) // Extra column - err = insertBuilder.Row(map[string]interface{}{ + err = insertBuilder.Row(ctx, map[string]interface{}{ "name": "bubba", "hunger_level": "120", "abc": "def", @@ -56,30 +57,30 @@ func TestBatchInsertBuilder(t *testing.T) { assert.EqualError(t, err, "invalid number of columns (expected=2, actual=3)") // Not enough columns - err = insertBuilder.Row(map[string]interface{}{ + err = insertBuilder.Row(ctx, map[string]interface{}{ "name": "bubba", }) assert.EqualError(t, err, "invalid number of columns (expected=2, actual=1)") // Invalid column - err = insertBuilder.Row(map[string]interface{}{ + err = insertBuilder.Row(ctx, map[string]interface{}{ "name": "bubba", "hello": "120", }) assert.EqualError(t, err, `column "hunger_level" does not exist`) - err = insertBuilder.RowStruct(invalidHungerRow{ + err = insertBuilder.RowStruct(ctx, invalidHungerRow{ Name: "Max", HungerLevel: "500", }) assert.EqualError(t, err, `expected value of type "db.hungerRow" but got "db.invalidHungerRow" value`) - err = insertBuilder.Exec() + err = insertBuilder.Exec(ctx) assert.NoError(t, err) // Check rows var found []person - err = sess.SelectRaw(&found, `SELECT * FROM people WHERE name like 'bubba%'`) + err = sess.SelectRaw(ctx, &found, `SELECT * FROM people WHERE name like 'bubba%'`) require.NoError(t, err) assert.Equal( @@ -91,13 +92,13 @@ func TestBatchInsertBuilder(t *testing.T) { }, ) - err = insertBuilder.Row(map[string]interface{}{ + err = insertBuilder.Row(ctx, map[string]interface{}{ "name": "bubba", "hunger_level": "1", }) assert.NoError(t, err) - err = insertBuilder.Exec() + err = insertBuilder.Exec(ctx) assert.EqualError( t, err, "error adding values while inserting to people: exec failed: pq:"+ " duplicate key value violates unique constraint \"people_pkey\"", @@ -105,16 +106,16 @@ func TestBatchInsertBuilder(t *testing.T) { insertBuilder.Suffix = "ON CONFLICT (name) DO NOTHING" - err = insertBuilder.Row(map[string]interface{}{ + err = insertBuilder.Row(ctx, map[string]interface{}{ "name": "bubba", "hunger_level": "1", }) assert.NoError(t, err) - err = insertBuilder.Exec() + err = insertBuilder.Exec(ctx) assert.NoError(t, err) - err = sess.SelectRaw(&found, `SELECT * FROM people WHERE name like 'bubba%'`) + err = sess.SelectRaw(ctx, &found, `SELECT * FROM people WHERE name like 'bubba%'`) require.NoError(t, err) assert.Equal( @@ -128,16 +129,16 @@ func TestBatchInsertBuilder(t *testing.T) { insertBuilder.Suffix = "ON CONFLICT (name) DO UPDATE SET hunger_level = EXCLUDED.hunger_level" - err = insertBuilder.Row(map[string]interface{}{ + err = insertBuilder.Row(ctx, map[string]interface{}{ "name": "bubba", "hunger_level": "1", }) assert.NoError(t, err) - err = insertBuilder.Exec() + err = insertBuilder.Exec(ctx) assert.NoError(t, err) - err = sess.SelectRaw(&found, `SELECT * FROM people WHERE name like 'bubba%'`) + err = sess.SelectRaw(ctx, &found, `SELECT * FROM people WHERE name like 'bubba%'`) require.NoError(t, err) assert.Equal( diff --git a/support/db/delete_builder.go b/support/db/delete_builder.go index 4ed699abfe..e467f6da91 100644 --- a/support/db/delete_builder.go +++ b/support/db/delete_builder.go @@ -1,6 +1,7 @@ package db import ( + "context" "database/sql" "github.com/pkg/errors" @@ -8,8 +9,8 @@ import ( // Exec executes the query represented by the builder, deleting any rows that // match the queries where clauses. -func (delb *DeleteBuilder) Exec() (sql.Result, error) { - r, err := delb.Table.Session.Exec(delb.sql) +func (delb *DeleteBuilder) Exec(ctx context.Context) (sql.Result, error) { + r, err := delb.Table.Session.Exec(ctx, delb.sql) if err != nil { return nil, errors.Wrap(err, "delete failed") } diff --git a/support/db/delete_builder_test.go b/support/db/delete_builder_test.go index 481eeea2ce..cf0eb40594 100644 --- a/support/db/delete_builder_test.go +++ b/support/db/delete_builder_test.go @@ -12,11 +12,12 @@ import ( func TestDeleteBuilder_Exec(t *testing.T) { db := dbtest.Postgres(t).Load(testSchema) defer db.Close() - sess := &Session{DB: db.Open(), Ctx: context.Background()} + sess := &Session{DB: db.Open()} defer sess.DB.Close() + ctx := context.Background() tbl := sess.GetTable("people") - r, err := tbl.Delete("name = ?", "scott").Exec() + r, err := tbl.Delete("name = ?", "scott").Exec(ctx) if assert.NoError(t, err, "query error") { actual, err := r.RowsAffected() @@ -24,7 +25,7 @@ func TestDeleteBuilder_Exec(t *testing.T) { assert.Equal(t, int64(1), actual) var found int - err = sess.GetRaw(&found, "SELECT COUNT(*) FROM people WHERE name = ?", "scott") + err = sess.GetRaw(ctx, &found, "SELECT COUNT(*) FROM people WHERE name = ?", "scott") require.NoError(t, err) assert.Equal(t, 0, found) } diff --git a/support/db/get_builder.go b/support/db/get_builder.go index 11b252cb94..6d5ef64134 100644 --- a/support/db/get_builder.go +++ b/support/db/get_builder.go @@ -1,14 +1,15 @@ package db import ( + "context" "github.com/stellar/go/support/errors" ) // Exec executes the query represented by the builder, populating the // destination with the results returned by running the query against the // current database session. -func (gb *GetBuilder) Exec() error { - err := gb.Table.Session.Get(gb.dest, gb.sql) +func (gb *GetBuilder) Exec(ctx context.Context) error { + err := gb.Table.Session.Get(ctx, gb.dest, gb.sql) if err != nil { return errors.Wrap(err, "get failed") } diff --git a/support/db/get_builder_test.go b/support/db/get_builder_test.go index b982f93b6a..7af3d47372 100644 --- a/support/db/get_builder_test.go +++ b/support/db/get_builder_test.go @@ -11,13 +11,13 @@ import ( func TestGetBuilder_Exec(t *testing.T) { db := dbtest.Postgres(t).Load(testSchema) defer db.Close() - sess := &Session{DB: db.Open(), Ctx: context.Background()} + sess := &Session{DB: db.Open()} defer sess.DB.Close() var found person tbl := sess.GetTable("people") - err := tbl.Get(&found, "name = ?", "scott").Exec() + err := tbl.Get(&found, "name = ?", "scott").Exec(context.Background()) if assert.NoError(t, err, "query error") { assert.Equal(t, "scott", found.Name) diff --git a/support/db/insert_builder.go b/support/db/insert_builder.go index 8085abc3f9..5cfe13297a 100644 --- a/support/db/insert_builder.go +++ b/support/db/insert_builder.go @@ -1,6 +1,7 @@ package db import ( + "context" "database/sql" "reflect" @@ -9,7 +10,7 @@ import ( // Exec executes the query represented by the builder, inserting each val // provided to the builder into the database. -func (ib *InsertBuilder) Exec() (sql.Result, error) { +func (ib *InsertBuilder) Exec(ctx context.Context) (sql.Result, error) { if len(ib.rows) == 0 { return nil, &NoRowsError{} } @@ -49,7 +50,7 @@ func (ib *InsertBuilder) Exec() (sql.Result, error) { // TODO: support return inserted id - r, err := ib.Table.Session.Exec(sql) + r, err := ib.Table.Session.Exec(ctx, sql) if err != nil { return nil, errors.Wrap(err, "insert failed") } diff --git a/support/db/insert_builder_test.go b/support/db/insert_builder_test.go index 3ea3bc0331..85c2465640 100644 --- a/support/db/insert_builder_test.go +++ b/support/db/insert_builder_test.go @@ -10,9 +10,10 @@ import ( ) func TestInsertBuilder_Exec(t *testing.T) { + ctx := context.Background() db := dbtest.Postgres(t).Load(testSchema) defer db.Close() - sess := &Session{DB: db.Open(), Ctx: context.Background()} + sess := &Session{DB: db.Open()} defer sess.DB.Close() tbl := sess.GetTable("people") @@ -20,11 +21,11 @@ func TestInsertBuilder_Exec(t *testing.T) { _, err := tbl.Insert(person{ Name: "bubba", HungerLevel: "120", - }).Exec() + }).Exec(ctx) if assert.NoError(t, err) { var found []person - err = sess.SelectRaw( + err = sess.SelectRaw(ctx, &found, "SELECT * FROM people WHERE name = ?", "bubba", @@ -39,7 +40,7 @@ func TestInsertBuilder_Exec(t *testing.T) { } // no rows - _, err = tbl.Insert().Exec() + _, err = tbl.Insert().Exec(ctx) if assert.Error(t, err) { assert.IsType(t, &NoRowsError{}, err) assert.EqualError(t, err, "no rows provided to insert") @@ -52,7 +53,7 @@ func TestInsertBuilder_Exec(t *testing.T) { }, person{ Name: "bubba3", HungerLevel: "120", - }).Exec() + }).Exec(ctx) if assert.NoError(t, err) { count, err2 := r.RowsAffected() @@ -69,7 +70,7 @@ func TestInsertBuilder_Exec(t *testing.T) { Name: "bubba2", HungerLevel: "120", NotAColumn: 3, - }).Exec() + }).Exec(ctx) assert.Error(t, err) } diff --git a/support/db/main.go b/support/db/main.go index d467bd4a5c..49d7d9216d 100644 --- a/support/db/main.go +++ b/support/db/main.go @@ -92,38 +92,33 @@ type UpdateBuilder struct { } // Session provides helper methods for making queries against `DB` and provides -// utilities such as automatic query logging and transaction management. NOTE: -// A Session is designed to be lightweight and temporarily lived (usually -// request scoped) which is one reason it is acceptable for it to store a -// context. It is not presently intended to cross goroutine boundaries and is -// not concurrency safe. +// utilities such as automatic query logging and transaction management. NOTE: +// Because transaction-handling is stateful, it is not presently intended to +// cross goroutine boundaries and is not concurrency safe. type Session struct { // DB is the database connection that queries should be executed against. DB *sqlx.DB - // Ctx is the context in which the repo is operating under. - Ctx context.Context - tx *sqlx.Tx txOptions *sql.TxOptions } type SessionInterface interface { - BeginTx(opts *sql.TxOptions) error - Begin() error - Rollback() error - TruncateTables(tables []string) error + BeginTx(ctx context.Context, opts *sql.TxOptions) error + Begin(ctx context.Context) error + Rollback(ctx context.Context) error + TruncateTables(ctx context.Context, tables []string) error Clone() *Session Close() error - Get(dest interface{}, query squirrel.Sqlizer) error - GetRaw(dest interface{}, query string, args ...interface{}) error - Select(dest interface{}, query squirrel.Sqlizer) error - SelectRaw(dest interface{}, query string, args ...interface{}) error + Get(ctx context.Context, dest interface{}, query squirrel.Sqlizer) error + GetRaw(ctx context.Context, dest interface{}, query string, args ...interface{}) error + Select(ctx context.Context, dest interface{}, query squirrel.Sqlizer) error + SelectRaw(ctx context.Context, dest interface{}, query string, args ...interface{}) error GetTable(name string) *Table - Exec(query squirrel.Sqlizer) (sql.Result, error) - ExecRaw(query string, args ...interface{}) (sql.Result, error) + Exec(ctx context.Context, query squirrel.Sqlizer) (sql.Result, error) + ExecRaw(ctx context.Context, query string, args ...interface{}) (sql.Result, error) NoRows(err error) bool - Ping(timeout time.Duration) error + Ping(ctx context.Context, timeout time.Duration) error } // Table helps to build sql queries against a given table. It logically @@ -157,7 +152,7 @@ func Open(dialect, dsn string) (*Session, error) { return nil, errors.Wrap(err, "ping failed") } - return &Session{DB: db, Ctx: context.Background()}, nil + return &Session{DB: db}, nil } // Wrap wraps a bare *sql.DB (from the database/sql stdlib package) in a @@ -165,7 +160,7 @@ func Open(dialect, dsn string) (*Session, error) { // control the instantiation of the database connection, but would still like to // leverage the facilities provided in Session. func Wrap(base *sql.DB, dialect string) *Session { - return &Session{DB: sqlx.NewDb(base, dialect), Ctx: context.Background()} + return &Session{DB: sqlx.NewDb(base, dialect)} } // ensure various types conform to Conn interface diff --git a/support/db/main_test.go b/support/db/main_test.go index 237e01578c..8ca94f1e3b 100644 --- a/support/db/main_test.go +++ b/support/db/main_test.go @@ -1,7 +1,6 @@ package db import ( - "context" "testing" "github.com/stellar/go/support/db/dbtest" @@ -18,7 +17,7 @@ type person struct { func TestGetTable(t *testing.T) { db := dbtest.Postgres(t).Load(testSchema) defer db.Close() - sess := &Session{DB: db.Open(), Ctx: context.Background()} + sess := &Session{DB: db.Open()} defer sess.DB.Close() tbl := sess.GetTable("users") diff --git a/support/db/mock_session.go b/support/db/mock_session.go index 90d66d0bcb..18898de94c 100644 --- a/support/db/mock_session.go +++ b/support/db/mock_session.go @@ -1,6 +1,7 @@ package db import ( + "context" "database/sql" "time" @@ -15,23 +16,23 @@ type MockSession struct { mock.Mock } -func (m *MockSession) Begin() error { - args := m.Called() +func (m *MockSession) Begin(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } -func (m *MockSession) BeginTx(opts *sql.TxOptions) error { - args := m.Called(opts) +func (m *MockSession) BeginTx(ctx context.Context, opts *sql.TxOptions) error { + args := m.Called(ctx, opts) return args.Error(0) } -func (m *MockSession) Rollback() error { - args := m.Called() +func (m *MockSession) Rollback(ctx context.Context) error { + args := m.Called(ctx) return args.Error(0) } -func (m *MockSession) TruncateTables(tables []string) error { - args := m.Called(tables) +func (m *MockSession) TruncateTables(ctx context.Context, tables []string) error { + args := m.Called(ctx, tables) return args.Error(0) } @@ -45,27 +46,27 @@ func (m *MockSession) Close() error { return args.Error(0) } -func (m *MockSession) Get(dest interface{}, query sq.Sqlizer) error { - args := m.Called(dest, query) +func (m *MockSession) Get(ctx context.Context, dest interface{}, query sq.Sqlizer) error { + args := m.Called(ctx, dest, query) return args.Error(0) } -func (m *MockSession) GetRaw(dest interface{}, query string, args ...interface{}) error { - argss := m.Called(dest, query, args) +func (m *MockSession) GetRaw(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + argss := m.Called(ctx, dest, query, args) return argss.Error(0) } -func (m *MockSession) Select(dest interface{}, query squirrel.Sqlizer) error { - argss := m.Called(dest, query) +func (m *MockSession) Select(ctx context.Context, dest interface{}, query squirrel.Sqlizer) error { + argss := m.Called(ctx, dest, query) return argss.Error(0) } -func (m *MockSession) SelectRaw( +func (m *MockSession) SelectRaw(ctx context.Context, dest interface{}, query string, args ...interface{}, ) error { - argss := m.Called(dest, query, args) + argss := m.Called(ctx, dest, query, args) return argss.Error(0) } @@ -74,13 +75,13 @@ func (m *MockSession) GetTable(name string) *Table { return args.Get(0).(*Table) } -func (m *MockSession) Exec(query squirrel.Sqlizer) (sql.Result, error) { - args := m.Called(query) +func (m *MockSession) Exec(ctx context.Context, query squirrel.Sqlizer) (sql.Result, error) { + args := m.Called(ctx, query) return args.Get(0).(sql.Result), args.Error(1) } -func (m *MockSession) ExecRaw(query string, args ...interface{}) (sql.Result, error) { - argss := m.Called(query, args) +func (m *MockSession) ExecRaw(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { + argss := m.Called(ctx, query, args) return argss.Get(0).(sql.Result), argss.Error(1) } @@ -89,6 +90,6 @@ func (m *MockSession) NoRows(err error) bool { return args.Get(0).(bool) } -func (m *MockSession) Ping(timeout time.Duration) error { - return m.Called(timeout).Error(0) +func (m *MockSession) Ping(ctx context.Context, timeout time.Duration) error { + return m.Called(ctx, timeout).Error(0) } diff --git a/support/db/schema/main.go b/support/db/schema/main.go index b541b949cb..8eff0ff8f4 100644 --- a/support/db/schema/main.go +++ b/support/db/schema/main.go @@ -1,6 +1,7 @@ package schema import ( + "context" "database/sql" "errors" @@ -21,8 +22,8 @@ const ( ) // Init installs the latest schema into db after clearing it first -func Init(db *db.Session, latest []byte) error { - return db.ExecAll(string(latest)) +func Init(ctx context.Context, db *db.Session, latest []byte) error { + return db.ExecAll(ctx, string(latest)) } // Migrate performs schema migration. Migrations can occur in one of three diff --git a/support/db/select_builder.go b/support/db/select_builder.go index 540d34b3c0..968c4b58c2 100644 --- a/support/db/select_builder.go +++ b/support/db/select_builder.go @@ -1,14 +1,15 @@ package db import ( + "context" "github.com/stellar/go/support/errors" ) // Exec executes the query represented by the builder, populating the // destination with the results returned by running the query against the // current database session. -func (sb *SelectBuilder) Exec() error { - err := sb.Table.Session.Select(sb.dest, sb.sql) +func (sb *SelectBuilder) Exec(ctx context.Context) error { + err := sb.Table.Session.Select(ctx, sb.dest, sb.sql) if err != nil { return errors.Wrap(err, "select failed") } diff --git a/support/db/select_builder_test.go b/support/db/select_builder_test.go index 121b9a8eb7..93cc888aeb 100644 --- a/support/db/select_builder_test.go +++ b/support/db/select_builder_test.go @@ -12,7 +12,7 @@ import ( func TestSelectBuilder_Exec(t *testing.T) { db := dbtest.Postgres(t).Load(testSchema) defer db.Close() - sess := &Session{DB: db.Open(), Ctx: context.Background()} + sess := &Session{DB: db.Open()} defer sess.DB.Close() var results []person @@ -30,7 +30,7 @@ func TestSelectBuilder_Exec(t *testing.T) { assert.Equal(t, "scott", args[0]) } - err = sb.Exec() + err = sb.Exec(context.Background()) if assert.NoError(t, err, "query error") { if assert.Len(t, results, 1) { diff --git a/support/db/session.go b/support/db/session.go index d55e883436..f5cbc74ef8 100644 --- a/support/db/session.go +++ b/support/db/session.go @@ -16,12 +16,12 @@ import ( ) // Begin binds this session to a new transaction. -func (s *Session) Begin() error { +func (s *Session) Begin(ctx context.Context) error { if s.tx != nil { return errors.New("already in transaction") } - tx, err := s.DB.BeginTxx(s.Ctx, nil) + tx, err := s.DB.BeginTxx(ctx, nil) if err != nil { if s.cancelled(err) { return ErrCancelled @@ -29,8 +29,7 @@ func (s *Session) Begin() error { return errors.Wrap(err, "beginx failed") } - s.logBegin() - + log.Ctx(ctx).Debug("sql: begin") s.tx = tx s.txOptions = nil return nil @@ -38,12 +37,12 @@ func (s *Session) Begin() error { // BeginTx binds this session to a new transaction which is configured with the // given transaction options -func (s *Session) BeginTx(opts *sql.TxOptions) error { +func (s *Session) BeginTx(ctx context.Context, opts *sql.TxOptions) error { if s.tx != nil { return errors.New("already in transaction") } - tx, err := s.DB.BeginTxx(s.Ctx, opts) + tx, err := s.DB.BeginTxx(ctx, opts) if err != nil { if s.cancelled(err) { return ErrCancelled @@ -51,7 +50,7 @@ func (s *Session) BeginTx(opts *sql.TxOptions) error { return errors.Wrap(err, "beginTx failed") } - s.logBegin() + log.Ctx(ctx).Debug("sql: begin") s.tx = tx s.txOptions = opts @@ -71,8 +70,7 @@ func (s *Session) GetTxOptions() *sql.TxOptions { // source is currently within. func (s *Session) Clone() *Session { return &Session{ - DB: s.DB, - Ctx: s.Ctx, + DB: s.DB, } } @@ -84,13 +82,13 @@ func (s *Session) Close() error { } // Commit commits the current transaction -func (s *Session) Commit() error { +func (s *Session) Commit(ctx context.Context) error { if s.tx == nil { return errors.New("not in transaction") } err := s.tx.Commit() - s.logCommit() + log.Ctx(ctx).Debug("sql: commit") s.tx = nil s.txOptions = nil return err @@ -104,6 +102,7 @@ func (s *Session) Dialect() string { // DeleteRange deletes a range of rows from a sql table between `start` and // `end` (exclusive). func (s *Session) DeleteRange( + ctx context.Context, start, end int64, table string, idCol string, @@ -113,31 +112,31 @@ func (s *Session) DeleteRange( start, end, ) - _, err := s.Exec(del) + _, err := s.Exec(ctx, del) return err } // Get runs `query`, setting the first result found on `dest`, if // any. -func (s *Session) Get(dest interface{}, query sq.Sqlizer) error { +func (s *Session) Get(ctx context.Context, dest interface{}, query sq.Sqlizer) error { sql, args, err := s.build(query) if err != nil { return err } - return s.GetRaw(dest, sql, args...) + return s.GetRaw(ctx, dest, sql, args...) } // GetRaw runs `query` with `args`, setting the first result found on // `dest`, if any. -func (s *Session) GetRaw(dest interface{}, query string, args ...interface{}) error { +func (s *Session) GetRaw(ctx context.Context, dest interface{}, query string, args ...interface{}) error { query, err := s.ReplacePlaceholders(query) if err != nil { return errors.Wrap(err, "replace placeholders failed") } start := time.Now() - err = s.conn().GetContext(s.Ctx, dest, query, args...) - s.log("get", start, query, args) + err = s.conn().GetContext(ctx, dest, query, args...) + s.log(ctx, "get", start, query, args) if err == nil { return nil @@ -162,51 +161,51 @@ func (s *Session) GetTable(name string) *Table { } } -func (s *Session) TruncateTables(tables []string) error { +func (s *Session) TruncateTables(ctx context.Context, tables []string) error { truncateCmd := fmt.Sprintf("truncate %s restart identity cascade", strings.Join(tables[:], ",")) - _, err := s.ExecRaw(truncateCmd) + _, err := s.ExecRaw(ctx, truncateCmd) return err } // Exec runs `query` -func (s *Session) Exec(query sq.Sqlizer) (sql.Result, error) { +func (s *Session) Exec(ctx context.Context, query sq.Sqlizer) (sql.Result, error) { sql, args, err := s.build(query) if err != nil { return nil, err } - return s.ExecRaw(sql, args...) + return s.ExecRaw(ctx, sql, args...) } // ExecAll runs all sql commands in `script` against `r` within a single // transaction. -func (s *Session) ExecAll(script string) error { - err := s.Begin() +func (s *Session) ExecAll(ctx context.Context, script string) error { + err := s.Begin(ctx) if err != nil { return err } - defer s.Rollback() + defer s.Rollback(ctx) for _, cmd := range sqlutils.AllStatements(script) { - _, err = s.ExecRaw(cmd) + _, err = s.ExecRaw(ctx, cmd) if err != nil { return err } } - return s.Commit() + return s.Commit(ctx) } // ExecRaw runs `query` with `args` -func (s *Session) ExecRaw(query string, args ...interface{}) (sql.Result, error) { +func (s *Session) ExecRaw(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { query, err := s.ReplacePlaceholders(query) if err != nil { return nil, errors.Wrap(err, "replace placeholders failed") } start := time.Now() - result, err := s.conn().ExecContext(s.Ctx, query, args...) - s.log("exec", start, query, args) + result, err := s.conn().ExecContext(ctx, query, args...) + s.log(ctx, "exec", start, query, args) if err == nil { return result, nil @@ -235,24 +234,24 @@ func (s *Session) cancelled(err error) bool { } // Query runs `query`, returns a *sqlx.Rows instance -func (s *Session) Query(query sq.Sqlizer) (*sqlx.Rows, error) { +func (s *Session) Query(ctx context.Context, query sq.Sqlizer) (*sqlx.Rows, error) { sql, args, err := s.build(query) if err != nil { return nil, err } - return s.QueryRaw(sql, args...) + return s.QueryRaw(ctx, sql, args...) } // QueryRaw runs `query` with `args` -func (s *Session) QueryRaw(query string, args ...interface{}) (*sqlx.Rows, error) { +func (s *Session) QueryRaw(ctx context.Context, query string, args ...interface{}) (*sqlx.Rows, error) { query, err := s.ReplacePlaceholders(query) if err != nil { return nil, errors.Wrap(err, "replace placeholders failed") } start := time.Now() - result, err := s.conn().QueryxContext(s.Ctx, query, args...) - s.log("query", start, query, args) + result, err := s.conn().QueryxContext(ctx, query, args...) + s.log(ctx, "query", start, query, args) if err == nil { return result, nil @@ -282,13 +281,13 @@ func (s *Session) ReplacePlaceholders(query string) (string, error) { } // Rollback rolls back the current transaction -func (s *Session) Rollback() error { +func (s *Session) Rollback(ctx context.Context) error { if s.tx == nil { return errors.New("not in transaction") } err := s.tx.Rollback() - s.logRollback() + log.Ctx(ctx).Debug("sql: rollback") s.tx = nil s.txOptions = nil return err @@ -296,23 +295,24 @@ func (s *Session) Rollback() error { // Ping verifies a connection to the database is still alive, // establishing a connection if necessary. -func (s *Session) Ping(timeout time.Duration) error { - ctx, cancel := context.WithTimeout(s.Ctx, timeout) +func (s *Session) Ping(ctx context.Context, timeout time.Duration) error { + ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() return s.DB.PingContext(ctx) } // Select runs `query`, setting the results found on `dest`. -func (s *Session) Select(dest interface{}, query sq.Sqlizer) error { +func (s *Session) Select(ctx context.Context, dest interface{}, query sq.Sqlizer) error { sql, args, err := s.build(query) if err != nil { return err } - return s.SelectRaw(dest, sql, args...) + return s.SelectRaw(ctx, dest, sql, args...) } // SelectRaw runs `query` with `args`, setting the results found on `dest`. func (s *Session) SelectRaw( + ctx context.Context, dest interface{}, query string, args ...interface{}, @@ -324,8 +324,8 @@ func (s *Session) SelectRaw( } start := time.Now() - err = s.conn().SelectContext(s.Ctx, dest, query, args...) - s.log("select", start, query, args) + err = s.conn().SelectContext(ctx, dest, query, args...) + s.log(ctx, "select", start, query, args) if err == nil { return nil @@ -382,31 +382,10 @@ func (s *Session) conn() Conn { return s.DB } -func (s *Session) log(typ string, start time.Time, query string, args []interface{}) { +func (s *Session) log(ctx context.Context, typ string, start time.Time, query string, args []interface{}) { log. - Ctx(s.logCtx()). WithField("args", args). WithField("sql", query). WithField("dur", time.Since(start).String()). Debugf("sql: %s", typ) } - -func (s *Session) logBegin() { - log.Ctx(s.logCtx()).Debug("sql: begin") -} - -func (s *Session) logCommit() { - log.Ctx(s.logCtx()).Debug("sql: commit") -} - -func (s *Session) logRollback() { - log.Ctx(s.logCtx()).Debug("sql: rollback") -} - -func (s *Session) logCtx() context.Context { - if s.Ctx != nil { - return s.Ctx - } - - return context.Background() -} diff --git a/support/db/session_test.go b/support/db/session_test.go index 0219e4806e..624e66a143 100644 --- a/support/db/session_test.go +++ b/support/db/session_test.go @@ -13,24 +13,25 @@ func TestSession(t *testing.T) { db := dbtest.Postgres(t).Load(testSchema) defer db.Close() + ctx := context.Background() assert := assert.New(t) require := require.New(t) - sess := &Session{DB: db.Open(), Ctx: context.Background()} + sess := &Session{DB: db.Open()} defer sess.DB.Close() assert.Equal("postgres", sess.Dialect()) var count int - err := sess.GetRaw(&count, "SELECT COUNT(*) FROM people") + err := sess.GetRaw(ctx, &count, "SELECT COUNT(*) FROM people") assert.NoError(err) assert.Equal(3, count) var names []string - err = sess.SelectRaw(&names, "SELECT name FROM people") + err = sess.SelectRaw(ctx, &names, "SELECT name FROM people") assert.NoError(err) assert.Len(names, 3) - ret, err := sess.ExecRaw("DELETE FROM people") + ret, err := sess.ExecRaw(ctx, "DELETE FROM people") assert.NoError(err) deleted, err := ret.RowsAffected() assert.NoError(err) @@ -40,7 +41,7 @@ func TestSession(t *testing.T) { // during execution) db.Load(testSchema) var name string - err = sess.GetRaw( + err = sess.GetRaw(ctx, &name, "SELECT name FROM people WHERE hunger_level = ? AND name != '??'", 1000000, @@ -49,7 +50,7 @@ func TestSession(t *testing.T) { assert.Equal("scott", name) // Test NoRows - err = sess.GetRaw( + err = sess.GetRaw(ctx, &name, "SELECT name FROM people WHERE hunger_level = ?", 1234, @@ -58,29 +59,29 @@ func TestSession(t *testing.T) { // Test transactions db.Load(testSchema) - require.NoError(sess.Begin(), "begin failed") - err = sess.GetRaw(&count, "SELECT COUNT(*) FROM people") + require.NoError(sess.Begin(ctx), "begin failed") + err = sess.GetRaw(ctx, &count, "SELECT COUNT(*) FROM people") assert.NoError(err) assert.Equal(3, count) - _, err = sess.ExecRaw("DELETE FROM people") + _, err = sess.ExecRaw(ctx, "DELETE FROM people") assert.NoError(err) - err = sess.GetRaw(&count, "SELECT COUNT(*) FROM people") + err = sess.GetRaw(ctx, &count, "SELECT COUNT(*) FROM people") assert.NoError(err) assert.Equal(0, count, "people did not appear deleted inside transaction") - assert.NoError(sess.Rollback(), "rollback failed") + assert.NoError(sess.Rollback(ctx), "rollback failed") // Ensure commit works - require.NoError(sess.Begin(), "begin failed") - sess.ExecRaw("DELETE FROM people") - assert.NoError(sess.Commit(), "commit failed") - err = sess.GetRaw(&count, "SELECT COUNT(*) FROM people") + require.NoError(sess.Begin(ctx), "begin failed") + sess.ExecRaw(ctx, "DELETE FROM people") + assert.NoError(sess.Commit(ctx), "commit failed") + err = sess.GetRaw(ctx, &count, "SELECT COUNT(*) FROM people") assert.NoError(err) assert.Equal(0, count) // ensure that selecting into a populated slice clears the slice first db.Load(testSchema) require.Len(names, 3, "ids slice was not preloaded with data") - err = sess.SelectRaw(&names, "SELECT name FROM people limit 2") + err = sess.SelectRaw(ctx, &names, "SELECT name FROM people limit 2") assert.NoError(err) assert.Len(names, 2) diff --git a/support/db/update_builder.go b/support/db/update_builder.go index 6f862b345a..cd6e3373d5 100644 --- a/support/db/update_builder.go +++ b/support/db/update_builder.go @@ -1,6 +1,7 @@ package db import ( + "context" "database/sql" "reflect" @@ -9,8 +10,8 @@ import ( // Exec executes the query that has been previously configured on the // UpdateBuilder. -func (ub *UpdateBuilder) Exec() (sql.Result, error) { - r, err := ub.Table.Session.Exec(ub.sql) +func (ub *UpdateBuilder) Exec(ctx context.Context) (sql.Result, error) { + r, err := ub.Table.Session.Exec(ctx, ub.sql) if err != nil { return nil, errors.Wrap(err, "select failed") } From 15d341751476218a43076b78a1c626758edd4a35 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Tue, 20 Apr 2021 15:28:11 +0100 Subject: [PATCH 2/5] Avoid changing the LedgerBackend interface --- ingest/ledgerbackend/captive_core_backend.go | 13 +++---- .../captive_core_backend_test.go | 14 +++---- ingest/ledgerbackend/database_backend.go | 28 +++++++++----- ingest/ledgerbackend/remote_captive_core.go | 38 ++++++------------- 4 files changed, 43 insertions(+), 50 deletions(-) diff --git a/ingest/ledgerbackend/captive_core_backend.go b/ingest/ledgerbackend/captive_core_backend.go index 86fc26d259..3730e01d1d 100644 --- a/ingest/ledgerbackend/captive_core_backend.go +++ b/ingest/ledgerbackend/captive_core_backend.go @@ -241,7 +241,7 @@ func (c *CaptiveStellarCore) openOfflineReplaySubprocess(from, to uint32) error return nil } -func (c *CaptiveStellarCore) openOnlineReplaySubprocess(ctx context.Context, from uint32) error { +func (c *CaptiveStellarCore) openOnlineReplaySubprocess(from uint32) error { latestCheckpointSequence, err := c.getLatestCheckpointSequence() if err != nil { return errors.Wrap(err, "error getting latest checkpoint sequence") @@ -269,7 +269,7 @@ func (c *CaptiveStellarCore) openOnlineReplaySubprocess(ctx context.Context, fro c.stellarCoreRunner = runner } - runFrom, ledgerHash, nextLedger, err := c.runFromParams(ctx, from) + runFrom, ledgerHash, nextLedger, err := c.runFromParams(from) if err != nil { return errors.Wrap(err, "error calculating ledger and hash for stelar-core run") } @@ -300,7 +300,7 @@ func (c *CaptiveStellarCore) openOnlineReplaySubprocess(ctx context.Context, fro } // runFromParams receives a ledger sequence and calculates the required values to call stellar-core run with --start-ledger and --start-hash -func (c *CaptiveStellarCore) runFromParams(ctx context.Context, from uint32) (runFrom uint32, ledgerHash string, nextLedger uint32, err error) { +func (c *CaptiveStellarCore) runFromParams(from uint32) (runFrom uint32, ledgerHash string, nextLedger uint32, err error) { if from == 1 { // Trying to start-from 1 results in an error from Stellar-Core: // Target ledger 1 is not newer than last closed ledger 1 - nothing to do @@ -357,7 +357,7 @@ func (c *CaptiveStellarCore) runFromParams(ctx context.Context, from uint32) (ru return } -func (c *CaptiveStellarCore) startPreparingRange(ctx context.Context, ledgerRange Range) (bool, error) { +func (c *CaptiveStellarCore) startPreparingRange(ledgerRange Range) (bool, error) { c.stellarCoreLock.Lock() defer c.stellarCoreLock.Unlock() @@ -375,7 +375,7 @@ func (c *CaptiveStellarCore) startPreparingRange(ctx context.Context, ledgerRang if ledgerRange.bounded { err = c.openOfflineReplaySubprocess(ledgerRange.from, ledgerRange.to) } else { - err = c.openOnlineReplaySubprocess(ctx, ledgerRange.from) + err = c.openOnlineReplaySubprocess(ledgerRange.from) } if err != nil { return false, errors.Wrap(err, "opening subprocess") @@ -394,8 +394,7 @@ func (c *CaptiveStellarCore) startPreparingRange(ctx context.Context, ledgerRang // Please note that using a BoundedRange, currently, requires a full-trust on // history archive. This issue is being fixed in Stellar-Core. func (c *CaptiveStellarCore) PrepareRange(ledgerRange Range) error { - ctx := context.TODO() - if alreadyPrepared, err := c.startPreparingRange(ctx, ledgerRange); err != nil { + if alreadyPrepared, err := c.startPreparingRange(ledgerRange); err != nil { return errors.Wrap(err, "error starting prepare range") } else if alreadyPrepared { return nil diff --git a/ingest/ledgerbackend/captive_core_backend_test.go b/ingest/ledgerbackend/captive_core_backend_test.go index af4bcdc14b..a3aff7a9df 100644 --- a/ingest/ledgerbackend/captive_core_backend_test.go +++ b/ingest/ledgerbackend/captive_core_backend_test.go @@ -1083,7 +1083,6 @@ func TestCaptiveUseOfLedgerHashStore(t *testing.T) { }, }, nil) - ctx := context.Background() mockLedgerHashStore := &MockLedgerHashStore{} mockLedgerHashStore.On("GetLedgerHash", uint32(1022)). Return("", false, fmt.Errorf("transient error")).Once() @@ -1102,28 +1101,28 @@ func TestCaptiveUseOfLedgerHashStore(t *testing.T) { checkpointManager: historyarchive.NewCheckpointManager(64), } - runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(ctx, 24) + runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(24) assert.NoError(t, err) assert.Equal(t, uint32(2), runFrom) assert.Equal(t, "mnb", ledgerHash) assert.Equal(t, uint32(2), nextLedger) - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 86) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(86) assert.NoError(t, err) assert.Equal(t, uint32(62), runFrom) assert.Equal(t, "cde", ledgerHash) assert.Equal(t, uint32(2), nextLedger) - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 128) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(128) assert.NoError(t, err) assert.Equal(t, uint32(126), runFrom) assert.Equal(t, "ghi", ledgerHash) assert.Equal(t, uint32(64), nextLedger) - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 1050) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(1050) assert.EqualError(t, err, "error trying to read ledger hash 1022: transient error") - runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(ctx, 300) + runFrom, ledgerHash, nextLedger, err = captiveBackend.runFromParams(300) assert.NoError(t, err) assert.Equal(t, uint32(254), runFrom, "runFrom") assert.Equal(t, "0101010100000000000000000000000000000000000000000000000000000000", ledgerHash) @@ -1163,7 +1162,6 @@ func TestCaptiveRunFromParams(t *testing.T) { for _, tc := range tests { t.Run(fmt.Sprintf("from_%d", tc.from), func(t *testing.T) { tt := assert.New(t) - ctx := context.Background() mockArchive := &historyarchive.MockArchive{} mockArchive. On("GetLedgerHeader", uint32(tc.ledgerArchives)). @@ -1178,7 +1176,7 @@ func TestCaptiveRunFromParams(t *testing.T) { checkpointManager: historyarchive.NewCheckpointManager(64), } - runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(ctx, tc.from) + runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(tc.from) tt.NoError(err) tt.Equal(tc.runFrom, runFrom, "runFrom") tt.Equal("0101010100000000000000000000000000000000000000000000000000000000", ledgerHash) diff --git a/ingest/ledgerbackend/database_backend.go b/ingest/ledgerbackend/database_backend.go index f1a9166b18..0780da482a 100644 --- a/ingest/ledgerbackend/database_backend.go +++ b/ingest/ledgerbackend/database_backend.go @@ -27,6 +27,8 @@ var _ LedgerBackend = (*DatabaseBackend)(nil) // DatabaseBackend implements a database data store. type DatabaseBackend struct { + cancel context.CancelFunc + ctx context.Context networkPassphrase string session session } @@ -37,11 +39,20 @@ func NewDatabaseBackend(dataSourceName, networkPassphrase string) (*DatabaseBack return nil, err } - return &DatabaseBackend{session: session, networkPassphrase: networkPassphrase}, nil + return NewDatabaseBackendFromSession(session, networkPassphrase) } func NewDatabaseBackendFromSession(session *db.Session, networkPassphrase string) (*DatabaseBackend, error) { - return &DatabaseBackend{session: session, networkPassphrase: networkPassphrase}, nil + // TODO: To avoid changing the LedgerBackend interface in this call we create + // a context once for this, so that Close() can cancel any in-progress method-calls. + ctx, cancel := context.WithCancel(context.Background()) + + return &DatabaseBackend{ + cancel: cancel, + ctx: ctx, + session: session, + networkPassphrase: networkPassphrase, + }, nil } func (dbb *DatabaseBackend) PrepareRange(ledgerRange Range) error { @@ -75,9 +86,8 @@ func (*DatabaseBackend) IsPrepared(ledgerRange Range) (bool, error) { // GetLatestLedgerSequence returns the most recent ledger sequence number present in the database. func (dbb *DatabaseBackend) GetLatestLedgerSequence() (uint32, error) { - ctx := context.TODO() var ledger []ledgerHeader - err := dbb.session.SelectRaw(ctx, &ledger, latestLedgerSeqQuery) + err := dbb.session.SelectRaw(dbb.ctx, &ledger, latestLedgerSeqQuery) if err != nil { return 0, errors.Wrap(err, "couldn't select ledger sequence") } @@ -142,7 +152,6 @@ func (dbb *DatabaseBackend) GetLedgerBlocking(sequence uint32) (xdr.LedgerCloseM // GetLedger returns the LedgerCloseMeta for the given ledger sequence number. // The first returned value is false when the ledger does not exist in the database. func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMeta, error) { - ctx := context.TODO() lcm := xdr.LedgerCloseMeta{ V0: &xdr.LedgerCloseMetaV0{}, } @@ -150,7 +159,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - ledgerheader var lRow ledgerHeaderHistory - err := dbb.session.GetRaw(ctx, &lRow, ledgerHeaderQuery, sequence) + err := dbb.session.GetRaw(dbb.ctx, &lRow, ledgerHeaderQuery, sequence) // Return errors... if err != nil { switch err { @@ -171,7 +180,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - txhistory var txhRows []txHistory - err = dbb.session.SelectRaw(ctx, &txhRows, txHistoryQuery+orderBy, sequence) + err = dbb.session.SelectRaw(dbb.ctx, &txhRows, txHistoryQuery+orderBy, sequence) // Return errors... if err != nil { return false, lcm, errors.Wrap(err, "Error getting txHistory") @@ -197,7 +206,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - txfeehistory var txfhRows []txFeeHistory - err = dbb.session.SelectRaw(ctx, &txfhRows, txFeeHistoryQuery+orderBy, sequence) + err = dbb.session.SelectRaw(dbb.ctx, &txfhRows, txFeeHistoryQuery+orderBy, sequence) // Return errors... if err != nil { return false, lcm, errors.Wrap(err, "Error getting txFeeHistory") @@ -214,7 +223,7 @@ func (dbb *DatabaseBackend) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMet // Query - upgradehistory var upgradeHistoryRows []upgradeHistory - err = dbb.session.SelectRaw(ctx, &upgradeHistoryRows, upgradeHistoryQuery, sequence) + err = dbb.session.SelectRaw(dbb.ctx, &upgradeHistoryRows, upgradeHistoryQuery, sequence) // Return errors... if err != nil { return false, lcm, errors.Wrap(err, "Error getting upgradeHistoryRows") @@ -243,5 +252,6 @@ func createSession(dataSourceName string) (*db.Session, error) { // Close disconnects an active database session. func (dbb *DatabaseBackend) Close() error { + dbb.cancel() return dbb.session.Close() } diff --git a/ingest/ledgerbackend/remote_captive_core.go b/ingest/ledgerbackend/remote_captive_core.go index 5e25a187ef..feb44463b8 100644 --- a/ingest/ledgerbackend/remote_captive_core.go +++ b/ingest/ledgerbackend/remote_captive_core.go @@ -128,17 +128,12 @@ func decodeResponse(response *http.Response, payload interface{}) error { // the latest sequence closed by the network. It's always the last value available // in the backend. func (c RemoteCaptiveStellarCore) GetLatestLedgerSequence() (sequence uint32, err error) { - // TODO: Should we use c.createContext here? - ctx := context.TODO() + // TODO: Have a context on this request so we can cancel all outstanding + // requests, not just PrepareRange. u := *c.url u.Path = path.Join(u.Path, "latest-sequence") - request, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) - if err != nil { - return 0, errors.Wrap(err, "failed to build request") - } - - response, err := c.client.Do(request) + response, err := c.client.Get(u.String()) if err != nil { return 0, errors.Wrap(err, "failed to execute request") } @@ -161,7 +156,7 @@ func (c RemoteCaptiveStellarCore) Close() error { return nil } -func (c RemoteCaptiveStellarCore) createContext(background context.Context) context.Context { +func (c RemoteCaptiveStellarCore) createContext() context.Context { c.lock.Lock() defer c.lock.Unlock() @@ -169,7 +164,7 @@ func (c RemoteCaptiveStellarCore) createContext(background context.Context) cont c.cancel() } - ctx, cancel := context.WithCancel(background) + ctx, cancel := context.WithCancel(context.Background()) c.cancel = cancel return ctx } @@ -184,7 +179,7 @@ func (c RemoteCaptiveStellarCore) createContext(background context.Context) cont // Please note that using a BoundedRange, currently, requires a full-trust on // history archive. This issue is being fixed in Stellar-Core. func (c RemoteCaptiveStellarCore) PrepareRange(ledgerRange Range) error { - ctx := c.createContext(context.TODO()) + ctx := c.createContext() u := *c.url u.Path = path.Join(u.Path, "prepare-range") rangeBytes, err := json.Marshal(ledgerRange) @@ -227,8 +222,8 @@ func (c RemoteCaptiveStellarCore) PrepareRange(ledgerRange Range) error { // IsPrepared returns true if a given ledgerRange is prepared. func (c RemoteCaptiveStellarCore) IsPrepared(ledgerRange Range) (bool, error) { - ctx := c.createContext(context.TODO()) - + // TODO: Have a context on this request so we can cancel all outstanding + // requests, not just PrepareRange. u := *c.url u.Path = path.Join(u.Path, "prepare-range") rangeBytes, err := json.Marshal(ledgerRange) @@ -236,14 +231,9 @@ func (c RemoteCaptiveStellarCore) IsPrepared(ledgerRange Range) (bool, error) { return false, errors.Wrap(err, "cannot serialize range") } body := bytes.NewReader(rangeBytes) - req, err := http.NewRequestWithContext(ctx, "POST", u.String(), body) - if err != nil { - return false, errors.Wrap(err, "failed to build request") - } - req.Header.Add("Content-Type", "application/json; charset=utf-8") var response *http.Response - response, err = c.client.Do(req) + response, err = c.client.Post(u.String(), "application/json; charset=utf-8", body) if err != nil { return false, errors.Wrap(err, "failed to execute request") } @@ -274,16 +264,12 @@ func (c RemoteCaptiveStellarCore) IsPrepared(ledgerRange Range) (bool, error) { // the first argument equal false. // This is done to provide maximum performance when streaming old ledgers. func (c RemoteCaptiveStellarCore) GetLedger(sequence uint32) (bool, xdr.LedgerCloseMeta, error) { - ctx := c.createContext(context.TODO()) - + // TODO: Have a context on this request so we can cancel all outstanding + // requests, not just PrepareRange. u := *c.url u.Path = path.Join(u.Path, "ledger", strconv.FormatUint(uint64(sequence), 10)) - req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) - if err != nil { - return false, xdr.LedgerCloseMeta{}, errors.Wrap(err, "failed to build request") - } - response, err := c.client.Do(req) + response, err := c.client.Get(u.String()) if err != nil { return false, xdr.LedgerCloseMeta{}, errors.Wrap(err, "failed to execute request") } From 63ced9376bfb6c6ee449775c64b949730ef863eb Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Tue, 20 Apr 2021 15:38:21 +0100 Subject: [PATCH 3/5] Pull out exp/services/captivecore ctx changes --- exp/services/captivecore/internal/api.go | 10 +++---- exp/services/captivecore/internal/api_test.go | 27 +++++++++---------- exp/services/captivecore/internal/server.go | 6 ++--- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/exp/services/captivecore/internal/api.go b/exp/services/captivecore/internal/api.go index 4cebd5ff83..9e666e565c 100644 --- a/exp/services/captivecore/internal/api.go +++ b/exp/services/captivecore/internal/api.go @@ -63,7 +63,7 @@ func (c *CaptiveCoreAPI) Shutdown() { c.core.Close() } -func (c *CaptiveCoreAPI) startPrepareRange(ctx context.Context, ledgerRange ledgerbackend.Range) { +func (c *CaptiveCoreAPI) startPrepareRange(ledgerRange ledgerbackend.Range) { defer c.wg.Done() err := c.core.PrepareRange(ledgerRange) @@ -100,7 +100,7 @@ func (c *CaptiveCoreAPI) startPrepareRange(ctx context.Context, ledgerRange ledg } // PrepareRange executes the PrepareRange operation on the captive core instance. -func (c *CaptiveCoreAPI) PrepareRange(ctx context.Context, ledgerRange ledgerbackend.Range) (ledgerbackend.PrepareRangeResponse, error) { +func (c *CaptiveCoreAPI) PrepareRange(ledgerRange ledgerbackend.Range) (ledgerbackend.PrepareRangeResponse, error) { c.activeRequest.Lock() defer c.activeRequest.Unlock() if c.ctx.Err() != nil { @@ -121,7 +121,7 @@ func (c *CaptiveCoreAPI) PrepareRange(ctx context.Context, ledgerRange ledgerbac c.activeRequest.valid = true c.wg.Add(1) - go c.startPrepareRange(ctx, ledgerRange) + go c.startPrepareRange(ledgerRange) return ledgerbackend.PrepareRangeResponse{ LedgerRange: ledgerRange, @@ -140,7 +140,7 @@ func (c *CaptiveCoreAPI) PrepareRange(ctx context.Context, ledgerRange ledgerbac } // GetLatestLedgerSequence determines the latest ledger sequence available on the captive core instance. -func (c *CaptiveCoreAPI) GetLatestLedgerSequence(ctx context.Context) (ledgerbackend.LatestLedgerSequenceResponse, error) { +func (c *CaptiveCoreAPI) GetLatestLedgerSequence() (ledgerbackend.LatestLedgerSequenceResponse, error) { c.activeRequest.Lock() defer c.activeRequest.Unlock() @@ -159,7 +159,7 @@ func (c *CaptiveCoreAPI) GetLatestLedgerSequence(ctx context.Context) (ledgerbac } // GetLedger fetches the ledger with the given sequence number from the captive core instance. -func (c *CaptiveCoreAPI) GetLedger(ctx context.Context, sequence uint32) (ledgerbackend.LedgerResponse, error) { +func (c *CaptiveCoreAPI) GetLedger(sequence uint32) (ledgerbackend.LedgerResponse, error) { c.activeRequest.Lock() defer c.activeRequest.Unlock() diff --git a/exp/services/captivecore/internal/api_test.go b/exp/services/captivecore/internal/api_test.go index 2d6e93ec2d..223f5e9bb4 100644 --- a/exp/services/captivecore/internal/api_test.go +++ b/exp/services/captivecore/internal/api_test.go @@ -1,7 +1,6 @@ package internal import ( - "context" "fmt" "testing" "time" @@ -19,13 +18,11 @@ func TestAPITestSuite(t *testing.T) { type APITestSuite struct { suite.Suite - ctx context.Context ledgerBackend *ledgerbackend.MockDatabaseBackend api CaptiveCoreAPI } func (s *APITestSuite) SetupTest() { - s.ctx = context.Background() s.ledgerBackend = &ledgerbackend.MockDatabaseBackend{} s.api = NewCaptiveCoreAPI(s.ledgerBackend, log.New()) } @@ -35,12 +32,12 @@ func (s *APITestSuite) TearDownTest() { } func (s *APITestSuite) TestLatestSeqActiveRequestInvalid() { - _, err := s.api.GetLatestLedgerSequence(s.ctx) + _, err := s.api.GetLatestLedgerSequence() s.Assert().Equal(err, ErrMissingPrepareRange) } func (s *APITestSuite) TestGetLedgerActiveRequestInvalid() { - _, err := s.api.GetLedger(s.ctx, 64) + _, err := s.api.GetLedger(64) s.Assert().Equal(err, ErrMissingPrepareRange) } @@ -51,7 +48,7 @@ func (s *APITestSuite) runBeforeReady(prepareRangeErr error, f func()) { WaitUntil(waitChan). Return(prepareRangeErr).Once() - response, err := s.api.PrepareRange(s.ctx, ledgerRange) + response, err := s.api.PrepareRange(ledgerRange) s.Assert().NoError(err) s.Assert().False(response.Ready) s.Assert().Equal(response.LedgerRange, ledgerRange) @@ -64,14 +61,14 @@ func (s *APITestSuite) runBeforeReady(prepareRangeErr error, f func()) { func (s *APITestSuite) TestLatestSeqActiveRequestNotReady() { s.runBeforeReady(nil, func() { - _, err := s.api.GetLatestLedgerSequence(s.ctx) + _, err := s.api.GetLatestLedgerSequence() s.Assert().Equal(err, ErrPrepareRangeNotReady) }) } func (s *APITestSuite) TestGetLedgerNotReady() { s.runBeforeReady(nil, func() { - _, err := s.api.GetLedger(s.ctx, 64) + _, err := s.api.GetLedger(64) s.Assert().Equal(err, ErrPrepareRangeNotReady) }) } @@ -80,7 +77,7 @@ func (s *APITestSuite) waitUntilReady(ledgerRange ledgerbackend.Range) { s.ledgerBackend.On("PrepareRange", ledgerRange). Return(nil).Once() - response, err := s.api.PrepareRange(s.ctx, ledgerRange) + response, err := s.api.PrepareRange(ledgerRange) s.Assert().NoError(err) s.Assert().False(response.Ready) s.Assert().Equal(response.LedgerRange, ledgerRange) @@ -94,7 +91,7 @@ func (s *APITestSuite) TestLatestSeqError() { expectedErr := fmt.Errorf("test error") s.ledgerBackend.On("GetLatestLedgerSequence").Return(uint32(0), expectedErr).Once() - _, err := s.api.GetLatestLedgerSequence(s.ctx) + _, err := s.api.GetLatestLedgerSequence() s.Assert().Equal(err, expectedErr) } @@ -105,7 +102,7 @@ func (s *APITestSuite) TestGetLedgerError() { s.ledgerBackend.On("GetLedger", uint32(64)). Return(false, xdr.LedgerCloseMeta{}, expectedErr).Once() - _, err := s.api.GetLedger(s.ctx, 64) + _, err := s.api.GetLedger(64) s.Assert().Equal(err, expectedErr) } @@ -114,7 +111,7 @@ func (s *APITestSuite) TestLatestSeqSucceeds() { expectedSeq := uint32(100) s.ledgerBackend.On("GetLatestLedgerSequence").Return(expectedSeq, nil).Once() - seq, err := s.api.GetLatestLedgerSequence(s.ctx) + seq, err := s.api.GetLatestLedgerSequence() s.Assert().NoError(err) s.Assert().Equal(seq, ledgerbackend.LatestLedgerSequenceResponse{Sequence: expectedSeq}) } @@ -133,7 +130,7 @@ func (s *APITestSuite) TestGetLedgerSucceeds() { } s.ledgerBackend.On("GetLedger", uint32(64)). Return(true, expectedLedger, nil).Once() - seq, err := s.api.GetLedger(s.ctx, 64) + seq, err := s.api.GetLedger(64) s.Assert().NoError(err) s.Assert().Equal(seq, ledgerbackend.LedgerResponse{ @@ -145,7 +142,7 @@ func (s *APITestSuite) TestGetLedgerSucceeds() { func (s *APITestSuite) TestShutDownBeforePrepareRange() { s.ledgerBackend.On("Close").Return(nil).Once() s.api.Shutdown() - _, err := s.api.PrepareRange(s.ctx, ledgerbackend.UnboundedRange(63)) + _, err := s.api.PrepareRange(ledgerbackend.UnboundedRange(63)) s.Assert().EqualError(err, "Cannot prepare range when shut down") } @@ -229,7 +226,7 @@ func (s *APITestSuite) TestRangeAlreadyPrepared() { ledgerbackend.UnboundedRange(100), ledgerbackend.BoundedRange(63, 70), } { - response, err := s.api.PrepareRange(s.ctx, ledgerRange) + response, err := s.api.PrepareRange(ledgerRange) s.Assert().NoError(err) s.Assert().True(response.Ready) s.Assert().Equal(superSetRange, response.LedgerRange) diff --git a/exp/services/captivecore/internal/server.go b/exp/services/captivecore/internal/server.go index 6c0ae43124..b451a35c93 100644 --- a/exp/services/captivecore/internal/server.go +++ b/exp/services/captivecore/internal/server.go @@ -39,7 +39,7 @@ func Handler(api CaptiveCoreAPI) http.Handler { mux := supporthttp.NewMux(api.log) mux.Get("/latest-sequence", func(w http.ResponseWriter, r *http.Request) { - response, err := api.GetLatestLedgerSequence(r.Context()) + response, err := api.GetLatestLedgerSequence() serializeResponse(api.log, w, r, response, err) }) @@ -51,7 +51,7 @@ func Handler(api CaptiveCoreAPI) http.Handler { return } - response, err := api.GetLedger(r.Context(), req.Sequence) + response, err := api.GetLedger(req.Sequence) serializeResponse(api.log, w, r, response, err) }) @@ -63,7 +63,7 @@ func Handler(api CaptiveCoreAPI) http.Handler { return } - response, err := api.PrepareRange(r.Context(), ledgerRange) + response, err := api.PrepareRange(ledgerRange) serializeResponse(api.log, w, r, response, err) }) From 1eda3d651cc3c6721bfa3045d563b85c1733f16d Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Tue, 20 Apr 2021 15:52:50 +0100 Subject: [PATCH 4/5] Add explicit close to LedgerHashStore, instead of relying on implicit db ctx cancellation --- ingest/ledgerbackend/captive_core_backend.go | 7 ++++++ .../captive_core_backend_test.go | 8 +++++++ ingest/ledgerbackend/ledger_hash_store.go | 23 ++++++++++++++++--- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/ingest/ledgerbackend/captive_core_backend.go b/ingest/ledgerbackend/captive_core_backend.go index 3730e01d1d..ea09b9aa3e 100644 --- a/ingest/ledgerbackend/captive_core_backend.go +++ b/ingest/ledgerbackend/captive_core_backend.go @@ -650,8 +650,15 @@ func (c *CaptiveStellarCore) Close() error { // after the CaptiveStellarCore context is canceled all subsequent calls to PrepareRange() will fail c.cancel() + // TODO: Sucks to ignore the error here, but no worse than it was before, + // so... + if c.ledgerHashStore != nil { + c.ledgerHashStore.Close() + } + if c.stellarCoreRunner != nil { return c.stellarCoreRunner.close() } + return nil } diff --git a/ingest/ledgerbackend/captive_core_backend_test.go b/ingest/ledgerbackend/captive_core_backend_test.go index a3aff7a9df..29aeb9aa22 100644 --- a/ingest/ledgerbackend/captive_core_backend_test.go +++ b/ingest/ledgerbackend/captive_core_backend_test.go @@ -1095,10 +1095,14 @@ func TestCaptiveUseOfLedgerHashStore(t *testing.T) { mockLedgerHashStore.On("GetLedgerHash", uint32(2)). Return("mnb", true, nil).Once() + cancelCalled := false captiveBackend := CaptiveStellarCore{ archive: mockArchive, ledgerHashStore: mockLedgerHashStore, checkpointManager: historyarchive.NewCheckpointManager(64), + cancel: context.CancelFunc(func() { + cancelCalled = true + }), } runFrom, ledgerHash, nextLedger, err := captiveBackend.runFromParams(24) @@ -1128,6 +1132,10 @@ func TestCaptiveUseOfLedgerHashStore(t *testing.T) { assert.Equal(t, "0101010100000000000000000000000000000000000000000000000000000000", ledgerHash) assert.Equal(t, uint32(192), nextLedger, "nextLedger") + mockLedgerHashStore.On("Close").Return(nil).Once() + err = captiveBackend.Close() + assert.NoError(t, err) + assert.True(t, cancelCalled) mockLedgerHashStore.AssertExpectations(t) mockArchive.AssertExpectations(t) } diff --git a/ingest/ledgerbackend/ledger_hash_store.go b/ingest/ledgerbackend/ledger_hash_store.go index e1709e5f74..ab1bdfe7eb 100644 --- a/ingest/ledgerbackend/ledger_hash_store.go +++ b/ingest/ledgerbackend/ledger_hash_store.go @@ -15,32 +15,44 @@ import ( type TrustedLedgerHashStore interface { // GetLedgerHash returns the ledger hash for the given sequence number GetLedgerHash(seq uint32) (string, bool, error) + Close() error } // HorizonDBLedgerHashStore is a TrustedLedgerHashStore which uses horizon's db to look up ledger hashes type HorizonDBLedgerHashStore struct { + cancel context.CancelFunc + ctx context.Context session *db.Session } // NewHorizonDBLedgerHashStore constructs a new TrustedLedgerHashStore backed by the horizon db func NewHorizonDBLedgerHashStore(session *db.Session) TrustedLedgerHashStore { - return HorizonDBLedgerHashStore{session: session} + ctx, cancel := context.WithCancel(context.Background()) + return HorizonDBLedgerHashStore{ + cancel: cancel, + ctx: ctx, + session: session, + } } // GetLedgerHash returns the ledger hash for the given sequence number func (h HorizonDBLedgerHashStore) GetLedgerHash(seq uint32) (string, bool, error) { - ctx := context.TODO() sql := sq.Select("hl.ledger_hash").From("history_ledgers hl"). Limit(1).Where("sequence = ?", seq) var hash string - err := h.session.Get(ctx, &hash, sql) + err := h.session.Get(h.ctx, &hash, sql) if h.session.NoRows(err) { return hash, false, nil } return hash, true, err } +func (h HorizonDBLedgerHashStore) Close() error { + h.cancel() + return h.session.Close() +} + // MockLedgerHashStore is a mock implementation of TrustedLedgerHashStore type MockLedgerHashStore struct { mock.Mock @@ -51,3 +63,8 @@ func (m *MockLedgerHashStore) GetLedgerHash(seq uint32) (string, bool, error) { args := m.Called(seq) return args.Get(0).(string), args.Get(1).(bool), args.Error(2) } + +func (m *MockLedgerHashStore) Close() error { + args := m.Called() + return args.Error(0) +} From 2f9863fa5859193bbe73458fad9e35431ee7e49a Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Tue, 20 Apr 2021 19:09:51 +0100 Subject: [PATCH 5/5] Propagate root ctx to ensure ledgerbackend and hash store shutdown --- exp/services/captivecore/internal/server_test.go | 2 ++ exp/services/captivecore/main.go | 3 ++- ingest/ledgerbackend/database_backend.go | 8 ++++---- ingest/ledgerbackend/ledger_hash_store.go | 4 ++-- ingest/ledgerbackend/remote_captive_core.go | 8 ++++++-- services/horizon/internal/db2/history/ledger_test.go | 2 +- services/horizon/internal/ingest/database_backend_test.go | 4 ++-- services/horizon/internal/ingest/main.go | 6 +++--- 8 files changed, 22 insertions(+), 15 deletions(-) diff --git a/exp/services/captivecore/internal/server_test.go b/exp/services/captivecore/internal/server_test.go index 1923767ee4..8339641e2b 100644 --- a/exp/services/captivecore/internal/server_test.go +++ b/exp/services/captivecore/internal/server_test.go @@ -1,6 +1,7 @@ package internal import ( + "context" "fmt" "io/ioutil" "net/http" @@ -35,6 +36,7 @@ func (s *ServerTestSuite) SetupTest() { s.server = httptest.NewServer(s.handler) var err error s.client, err = ledgerbackend.NewRemoteCaptive( + context.Background(), s.server.URL, ledgerbackend.PrepareRangePollInterval(time.Millisecond), ) diff --git a/exp/services/captivecore/main.go b/exp/services/captivecore/main.go index f5ec78447d..d0f2fdd425 100644 --- a/exp/services/captivecore/main.go +++ b/exp/services/captivecore/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "go/types" "strings" @@ -138,7 +139,7 @@ func main() { if err != nil { logger.WithError(err).Fatal("Could not create db connection instance") } - captiveConfig.LedgerHashStore = ledgerbackend.NewHorizonDBLedgerHashStore(dbConn) + captiveConfig.LedgerHashStore = ledgerbackend.NewHorizonDBLedgerHashStore(context.Background(), dbConn) } core, err := ledgerbackend.NewCaptive(captiveConfig) diff --git a/ingest/ledgerbackend/database_backend.go b/ingest/ledgerbackend/database_backend.go index 0780da482a..0cd19a79b0 100644 --- a/ingest/ledgerbackend/database_backend.go +++ b/ingest/ledgerbackend/database_backend.go @@ -33,19 +33,19 @@ type DatabaseBackend struct { session session } -func NewDatabaseBackend(dataSourceName, networkPassphrase string) (*DatabaseBackend, error) { +func NewDatabaseBackend(ctx context.Context, dataSourceName, networkPassphrase string) (*DatabaseBackend, error) { session, err := createSession(dataSourceName) if err != nil { return nil, err } - return NewDatabaseBackendFromSession(session, networkPassphrase) + return NewDatabaseBackendFromSession(ctx, session, networkPassphrase) } -func NewDatabaseBackendFromSession(session *db.Session, networkPassphrase string) (*DatabaseBackend, error) { +func NewDatabaseBackendFromSession(ctx context.Context, session *db.Session, networkPassphrase string) (*DatabaseBackend, error) { // TODO: To avoid changing the LedgerBackend interface in this call we create // a context once for this, so that Close() can cancel any in-progress method-calls. - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(ctx) return &DatabaseBackend{ cancel: cancel, diff --git a/ingest/ledgerbackend/ledger_hash_store.go b/ingest/ledgerbackend/ledger_hash_store.go index ab1bdfe7eb..13cd3e4d6d 100644 --- a/ingest/ledgerbackend/ledger_hash_store.go +++ b/ingest/ledgerbackend/ledger_hash_store.go @@ -26,8 +26,8 @@ type HorizonDBLedgerHashStore struct { } // NewHorizonDBLedgerHashStore constructs a new TrustedLedgerHashStore backed by the horizon db -func NewHorizonDBLedgerHashStore(session *db.Session) TrustedLedgerHashStore { - ctx, cancel := context.WithCancel(context.Background()) +func NewHorizonDBLedgerHashStore(ctx context.Context, session *db.Session) TrustedLedgerHashStore { + ctx, cancel := context.WithCancel(ctx) return HorizonDBLedgerHashStore{ cancel: cancel, ctx: ctx, diff --git a/ingest/ledgerbackend/remote_captive_core.go b/ingest/ledgerbackend/remote_captive_core.go index feb44463b8..52332ac76e 100644 --- a/ingest/ledgerbackend/remote_captive_core.go +++ b/ingest/ledgerbackend/remote_captive_core.go @@ -67,6 +67,7 @@ type RemoteCaptiveStellarCore struct { client *http.Client lock *sync.Mutex cancel context.CancelFunc + parentCtx context.Context prepareRangePollInterval time.Duration } @@ -84,7 +85,7 @@ func PrepareRangePollInterval(d time.Duration) RemoteCaptiveOption { // NewRemoteCaptive returns a new RemoteCaptiveStellarCore instance. // // Only the captiveCoreURL parameter is required. -func NewRemoteCaptive(captiveCoreURL string, options ...RemoteCaptiveOption) (RemoteCaptiveStellarCore, error) { +func NewRemoteCaptive(ctx context.Context, captiveCoreURL string, options ...RemoteCaptiveOption) (RemoteCaptiveStellarCore, error) { u, err := url.Parse(captiveCoreURL) if err != nil { return RemoteCaptiveStellarCore{}, errors.Wrap(err, "unparseable url") @@ -95,6 +96,7 @@ func NewRemoteCaptive(captiveCoreURL string, options ...RemoteCaptiveOption) (Re url: u, client: &http.Client{Timeout: 5 * time.Second}, lock: &sync.Mutex{}, + parentCtx: ctx, } for _, option := range options { option(&client) @@ -160,11 +162,13 @@ func (c RemoteCaptiveStellarCore) createContext() context.Context { c.lock.Lock() defer c.lock.Unlock() + // Cancel any outstanding PrepareRange request if c.cancel != nil { c.cancel() } - ctx, cancel := context.WithCancel(context.Background()) + // Make a new context for this new request. + ctx, cancel := context.WithCancel(c.parentCtx) c.cancel = cancel return ctx } diff --git a/services/horizon/internal/db2/history/ledger_test.go b/services/horizon/internal/db2/history/ledger_test.go index 7d5b2af05e..c148b6ed8e 100644 --- a/services/horizon/internal/db2/history/ledger_test.go +++ b/services/horizon/internal/db2/history/ledger_test.go @@ -58,7 +58,7 @@ func TestInsertLedger(t *testing.T) { test.ResetHorizonDB(t, tt.HorizonDB) q := &Q{tt.HorizonSession()} - ledgerHashStore := ledgerbackend.NewHorizonDBLedgerHashStore(tt.HorizonSession()) + ledgerHashStore := ledgerbackend.NewHorizonDBLedgerHashStore(tt.Ctx, tt.HorizonSession()) _, exists, err := ledgerHashStore.GetLedgerHash(100) tt.Assert.NoError(err) tt.Assert.False(exists) diff --git a/services/horizon/internal/ingest/database_backend_test.go b/services/horizon/internal/ingest/database_backend_test.go index 1290e3a0e9..64769b602a 100644 --- a/services/horizon/internal/ingest/database_backend_test.go +++ b/services/horizon/internal/ingest/database_backend_test.go @@ -13,7 +13,7 @@ func TestGetLatestLedger(t *testing.T) { tt.ScenarioWithoutHorizon("base") defer tt.Finish() - backend, err := ledgerbackend.NewDatabaseBackendFromSession(tt.CoreSession(), network.TestNetworkPassphrase) + backend, err := ledgerbackend.NewDatabaseBackendFromSession(tt.Ctx, tt.CoreSession(), network.TestNetworkPassphrase) tt.Assert.NoError(err) seq, err := backend.GetLatestLedgerSequence() tt.Assert.NoError(err) @@ -28,7 +28,7 @@ func TestGetLatestLedgerNotFound(t *testing.T) { _, err := tt.CoreDB.Exec(`DELETE FROM ledgerheaders`) tt.Assert.NoError(err, "failed to remove ledgerheaders") - backend, err := ledgerbackend.NewDatabaseBackendFromSession(tt.CoreSession(), network.TestNetworkPassphrase) + backend, err := ledgerbackend.NewDatabaseBackendFromSession(tt.Ctx, tt.CoreSession(), network.TestNetworkPassphrase) tt.Assert.NoError(err) _, err = backend.GetLatestLedgerSequence() tt.Assert.EqualError(err, "no ledgers exist in ledgerheaders table") diff --git a/services/horizon/internal/ingest/main.go b/services/horizon/internal/ingest/main.go index a19890b703..ac4669b412 100644 --- a/services/horizon/internal/ingest/main.go +++ b/services/horizon/internal/ingest/main.go @@ -188,7 +188,7 @@ func NewSystem(config Config) (System, error) { var ledgerBackend ledgerbackend.LedgerBackend if config.EnableCaptiveCore { if len(config.RemoteCaptiveCoreURL) > 0 { - ledgerBackend, err = ledgerbackend.NewRemoteCaptive(config.RemoteCaptiveCoreURL) + ledgerBackend, err = ledgerbackend.NewRemoteCaptive(ctx, config.RemoteCaptiveCoreURL) if err != nil { cancel() return nil, errors.Wrap(err, "error creating captive core backend") @@ -206,7 +206,7 @@ func NewSystem(config Config) (System, error) { NetworkPassphrase: config.NetworkPassphrase, HistoryArchiveURLs: []string{config.HistoryArchiveURL}, CheckpointFrequency: config.CheckpointFrequency, - LedgerHashStore: ledgerbackend.NewHorizonDBLedgerHashStore(config.HistorySession), + LedgerHashStore: ledgerbackend.NewHorizonDBLedgerHashStore(ctx, config.HistorySession), Log: logger, Context: ctx, }, @@ -218,7 +218,7 @@ func NewSystem(config Config) (System, error) { } } else { coreSession := config.CoreSession.Clone() - ledgerBackend, err = ledgerbackend.NewDatabaseBackendFromSession(coreSession, config.NetworkPassphrase) + ledgerBackend, err = ledgerbackend.NewDatabaseBackendFromSession(ctx, coreSession, config.NetworkPassphrase) if err != nil { cancel() return nil, errors.Wrap(err, "error creating ledger backend")