diff --git a/core/chains/evm/forwarders/forwarder_manager.go b/core/chains/evm/forwarders/forwarder_manager.go index 4d0257e87e2..cc52e02e31f 100644 --- a/core/chains/evm/forwarders/forwarder_manager.go +++ b/core/chains/evm/forwarders/forwarder_manager.go @@ -213,6 +213,7 @@ func (f *FwdMgr) subscribeSendersChangedLogs(addr common.Address) error { } err := f.logpoller.RegisterFilter( + f.ctx, evmlogpoller.Filter{ Name: FilterName(addr), EventSigs: []common.Hash{authChangedTopic}, @@ -253,11 +254,11 @@ func (f *FwdMgr) runLoop() { } logs, err := f.logpoller.LatestLogEventSigsAddrsWithConfs( + f.ctx, f.latestBlock, []common.Hash{authChangedTopic}, addrs, evmlogpoller.Confirmations(f.cfg.FinalityDepth()), - pg.WithParentCtx(f.ctx), ) if err != nil { f.logger.Errorw("Failed to retrieve latest log round", "err", err) diff --git a/core/chains/evm/forwarders/forwarder_manager_test.go b/core/chains/evm/forwarders/forwarder_manager_test.go index a602a5c823f..3c36ed91f23 100644 --- a/core/chains/evm/forwarders/forwarder_manager_test.go +++ b/core/chains/evm/forwarders/forwarder_manager_test.go @@ -62,7 +62,7 @@ func TestFwdMgr_MaybeForwardTransaction(t *testing.T) { t.Log(authorized) evmClient := client.NewSimulatedBackendClient(t, ec, testutils.FixtureChainID) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) fwdMgr := forwarders.NewFwdMgr(db, evmClient, lp, lggr, evmcfg.EVM()) fwdMgr.ORM = forwarders.NewORM(db) @@ -116,7 +116,7 @@ func TestFwdMgr_AccountUnauthorizedToForward_SkipsForwarding(t *testing.T) { ec.Commit() evmClient := client.NewSimulatedBackendClient(t, ec, testutils.FixtureChainID) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), evmClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) fwdMgr := forwarders.NewFwdMgr(db, evmClient, lp, lggr, evmcfg.EVM()) fwdMgr.ORM = forwarders.NewORM(db) diff --git a/core/chains/evm/headtracker/head_broadcaster_test.go b/core/chains/evm/headtracker/head_broadcaster_test.go index dcbb9bd0396..d8277582f61 100644 --- a/core/chains/evm/headtracker/head_broadcaster_test.go +++ b/core/chains/evm/headtracker/head_broadcaster_test.go @@ -70,7 +70,7 @@ func TestHeadBroadcaster_Subscribe(t *testing.T) { checker1 := &cltest.MockHeadTrackable{} checker2 := &cltest.MockHeadTrackable{} - orm := headtracker.NewORM(db, logger, cfg.Database(), *ethClient.ConfiguredChainID()) + orm := headtracker.NewORM(*ethClient.ConfiguredChainID(), db) hs := headtracker.NewHeadSaver(logger, orm, evmCfg.EVM(), evmCfg.EVM().HeadTracker()) mailMon := mailboxtest.NewMonitor(t) servicetest.Run(t, mailMon) diff --git a/core/chains/evm/headtracker/head_saver_test.go b/core/chains/evm/headtracker/head_saver_test.go index f541330bc98..27caca42b6c 100644 --- a/core/chains/evm/headtracker/head_saver_test.go +++ b/core/chains/evm/headtracker/head_saver_test.go @@ -11,7 +11,6 @@ import ( httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" ) @@ -44,9 +43,8 @@ func (c *config) BlockEmissionIdleWarningThreshold() time.Duration { func configureSaver(t *testing.T) (httypes.HeadSaver, headtracker.ORM) { db := pgtest.NewSqlxDB(t) lggr := logger.Test(t) - cfg := configtest.NewGeneralConfig(t, nil) htCfg := &config{finalityDepth: uint32(1)} - orm := headtracker.NewORM(db, lggr, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) saver := headtracker.NewHeadSaver(lggr, orm, htCfg, &headTrackerConfig{historyDepth: 6}) return saver, orm } diff --git a/core/chains/evm/headtracker/head_tracker_test.go b/core/chains/evm/headtracker/head_tracker_test.go index 22e931d6d0f..abe5df5d495 100644 --- a/core/chains/evm/headtracker/head_tracker_test.go +++ b/core/chains/evm/headtracker/head_tracker_test.go @@ -52,12 +52,10 @@ func TestHeadTracker_New(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) - config := configtest.NewGeneralConfig(t, nil) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(cltest.Head(0), nil) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) assert.Nil(t, orm.IdempotentInsertHead(testutils.Context(t), cltest.Head(1))) last := cltest.Head(16) assert.Nil(t, orm.IdempotentInsertHead(testutils.Context(t), last)) @@ -76,11 +74,10 @@ func TestHeadTracker_Save_InsertsAndTrimsTable(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for idx := 0; idx < 200; idx++ { assert.Nil(t, orm.IdempotentInsertHead(testutils.Context(t), cltest.Head(idx))) @@ -121,9 +118,8 @@ func TestHeadTracker_Get(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) chStarted := make(chan struct{}) @@ -168,9 +164,8 @@ func TestHeadTracker_Start_NewHeads(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) chStarted := make(chan struct{}) @@ -193,9 +188,8 @@ func TestHeadTracker_Start_CancelContext(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) chStarted := make(chan struct{}) ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Run(func(args mock.Arguments) { @@ -233,9 +227,8 @@ func TestHeadTracker_CallsHeadTrackableCallbacks(t *testing.T) { g := gomega.NewWithT(t) db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) @@ -272,9 +265,8 @@ func TestHeadTracker_ReconnectOnError(t *testing.T) { g := gomega.NewWithT(t) db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) mockEth := &evmtest.MockEth{EthClient: ethClient} @@ -308,9 +300,8 @@ func TestHeadTracker_ResubscribeOnSubscriptionError(t *testing.T) { g := gomega.NewWithT(t) db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) @@ -355,7 +346,6 @@ func TestHeadTracker_Start_LoadsLatestChain(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := cltest.NewTestChainScopedConfig(t) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) @@ -389,7 +379,7 @@ func TestHeadTracker_Start_LoadsLatestChain(t *testing.T) { func(ctx context.Context, ch chan<- *evmtypes.Head) error { return nil }, ) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) trackable := &cltest.MockHeadTrackable{} ht := createHeadTrackerWithChecker(t, ethClient, config.EVM(), config.EVM().HeadTracker(), orm, trackable) @@ -420,7 +410,6 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingEnabled(t *testing.T) t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].FinalityDepth = ptr[uint32](50) @@ -432,7 +421,7 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingEnabled(t *testing.T) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) checker := commonmocks.NewHeadTrackable[*evmtypes.Head, gethCommon.Hash](t) - orm := headtracker.NewORM(db, logger, config.Database(), *evmtest.MustGetDefaultChainID(t, config.EVMConfigs())) + orm := headtracker.NewORM(*evmtest.MustGetDefaultChainID(t, config.EVMConfigs()), db) csCfg := evmtest.NewChainScopedConfig(t, config) ht := createHeadTrackerWithChecker(t, ethClient, csCfg.EVM(), csCfg.EVM().HeadTracker(), orm, checker) @@ -548,7 +537,6 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingDisabled(t *testing.T t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) config := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].FinalityDepth = ptr[uint32](50) @@ -560,7 +548,7 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingDisabled(t *testing.T ethClient := evmtest.NewEthClientMockWithDefaultChain(t) checker := commonmocks.NewHeadTrackable[*evmtypes.Head, gethCommon.Hash](t) - orm := headtracker.NewORM(db, logger, config.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) evmcfg := evmtest.NewChainScopedConfig(t, config) ht := createHeadTrackerWithChecker(t, ethClient, evmcfg.EVM(), evmcfg.EVM().HeadTracker(), orm, checker) @@ -776,8 +764,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("does nothing if all the heads are in database", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for i := range heads { require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), &heads[i])) } @@ -793,8 +780,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("fetches a missing head", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for i := range heads { require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), &heads[i])) } @@ -829,8 +815,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("fetches only heads that are missing", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for i := range heads { require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), &heads[i])) } @@ -862,8 +847,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("does not backfill if chain length is already greater than or equal to depth", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for i := range heads { require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), &heads[i])) } @@ -883,8 +867,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("only backfills to height 0 if chain length would otherwise cause it to try and fetch a negative head", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil) @@ -908,8 +891,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("abandons backfill and returns error if the eth node returns not found", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for i := range heads { require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), &heads[i])) } @@ -939,8 +921,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("abandons backfill and returns error if the context time budget is exceeded", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for i := range heads { require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), &heads[i])) } @@ -968,8 +949,7 @@ func TestHeadTracker_Backfill(t *testing.T) { t.Run("abandons backfill and returns error when fetching a block by hash fails, indicating a reorg", func(t *testing.T) { db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) - logger := logger.Test(t) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) ethClient := evmtest.NewEthClientMock(t) ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil) ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(&h14, nil).Once() diff --git a/core/chains/evm/headtracker/orm.go b/core/chains/evm/headtracker/orm.go index 859f6764b63..7bc630f9d28 100644 --- a/core/chains/evm/headtracker/orm.go +++ b/core/chains/evm/headtracker/orm.go @@ -8,12 +8,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type ORM interface { @@ -30,29 +27,33 @@ type ORM interface { HeadByHash(ctx context.Context, hash common.Hash) (head *evmtypes.Head, err error) } +var _ ORM = &orm{} + type orm struct { - q pg.Q chainID ubig.Big + db sqlutil.Queryer } -func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, chainID big.Int) ORM { - return &orm{pg.NewQ(db, logger.Named(lggr, "HeadTrackerORM"), cfg), ubig.Big(chainID)} +// NewORM creates an ORM scoped to chainID. +func NewORM(chainID big.Int, db sqlutil.Queryer) ORM { + return &orm{ + chainID: ubig.Big(chainID), + db: db, + } } func (orm *orm) IdempotentInsertHead(ctx context.Context, head *evmtypes.Head) error { // listener guarantees head.EVMChainID to be equal to orm.chainID - q := orm.q.WithOpts(pg.WithParentCtx(ctx)) query := ` INSERT INTO evm.heads (hash, number, parent_hash, created_at, timestamp, l1_block_number, evm_chain_id, base_fee_per_gas) VALUES ( - :hash, :number, :parent_hash, :created_at, :timestamp, :l1_block_number, :evm_chain_id, :base_fee_per_gas) + $1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (evm_chain_id, hash) DO NOTHING` - err := q.ExecQNamed(query, head) + _, err := orm.db.ExecContext(ctx, query, head.Hash, head.Number, head.ParentHash, head.CreatedAt, head.Timestamp, head.L1BlockNumber, orm.chainID, head.BaseFeePerGas) return errors.Wrap(err, "IdempotentInsertHead failed to insert head") } func (orm *orm) TrimOldHeads(ctx context.Context, n uint) (err error) { - q := orm.q.WithOpts(pg.WithParentCtx(ctx)) - return q.ExecQ(` + _, err = orm.db.ExecContext(ctx, ` DELETE FROM evm.heads WHERE evm_chain_id = $1 AND number < ( SELECT min(number) FROM ( @@ -63,12 +64,13 @@ func (orm *orm) TrimOldHeads(ctx context.Context, n uint) (err error) { LIMIT $2 ) numbers )`, orm.chainID, n) + + return err } func (orm *orm) LatestHead(ctx context.Context) (head *evmtypes.Head, err error) { head = new(evmtypes.Head) - q := orm.q.WithOpts(pg.WithParentCtx(ctx)) - err = q.Get(head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT 1`, orm.chainID) + err = orm.db.GetContext(ctx, head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT 1`, orm.chainID) if errors.Is(err, sql.ErrNoRows) { return nil, nil } @@ -77,16 +79,14 @@ func (orm *orm) LatestHead(ctx context.Context) (head *evmtypes.Head, err error) } func (orm *orm) LatestHeads(ctx context.Context, limit uint) (heads []*evmtypes.Head, err error) { - q := orm.q.WithOpts(pg.WithParentCtx(ctx)) - err = q.Select(&heads, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT $2`, orm.chainID, limit) + err = orm.db.SelectContext(ctx, &heads, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT $2`, orm.chainID, limit) err = errors.Wrap(err, "LatestHeads failed") return } func (orm *orm) HeadByHash(ctx context.Context, hash common.Hash) (head *evmtypes.Head, err error) { - q := orm.q.WithOpts(pg.WithParentCtx(ctx)) head = new(evmtypes.Head) - err = q.Get(head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 AND hash = $2`, orm.chainID, hash) + err = orm.db.GetContext(ctx, head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 AND hash = $2`, orm.chainID, hash) if errors.Is(err, sql.ErrNoRows) { return nil, nil } diff --git a/core/chains/evm/headtracker/orm_test.go b/core/chains/evm/headtracker/orm_test.go index c9a2146daf2..19acf7a3d8f 100644 --- a/core/chains/evm/headtracker/orm_test.go +++ b/core/chains/evm/headtracker/orm_test.go @@ -3,17 +3,13 @@ package headtracker_test import ( "testing" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" ) @@ -21,9 +17,7 @@ func TestORM_IdempotentInsertHead(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) - cfg := configtest.NewGeneralConfig(t, nil) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) // Returns nil when inserting first head head := cltest.Head(0) @@ -47,9 +41,7 @@ func TestORM_TrimOldHeads(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) - cfg := configtest.NewGeneralConfig(t, nil) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) for i := 0; i < 10; i++ { head := cltest.Head(i) @@ -72,9 +64,7 @@ func TestORM_HeadByHash(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) - cfg := configtest.NewGeneralConfig(t, nil) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) var hash common.Hash for i := 0; i < 10; i++ { @@ -95,9 +85,7 @@ func TestORM_HeadByHash_NotFound(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) - cfg := configtest.NewGeneralConfig(t, nil) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) hash := cltest.Head(123).Hash head, err := orm.HeadByHash(testutils.Context(t), hash) @@ -110,9 +98,7 @@ func TestORM_LatestHeads_NoRows(t *testing.T) { t.Parallel() db := pgtest.NewSqlxDB(t) - logger := logger.Test(t) - cfg := configtest.NewGeneralConfig(t, nil) - orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID) + orm := headtracker.NewORM(cltest.FixtureChainID, db) heads, err := orm.LatestHeads(testutils.Context(t), 100) diff --git a/core/chains/evm/logpoller/disabled.go b/core/chains/evm/logpoller/disabled.go index 05d591042f4..b05c456f565 100644 --- a/core/chains/evm/logpoller/disabled.go +++ b/core/chains/evm/logpoller/disabled.go @@ -6,8 +6,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -33,80 +31,80 @@ func (disabled) Replay(ctx context.Context, fromBlock int64) error { return ErrD func (disabled) ReplayAsync(fromBlock int64) {} -func (disabled) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { return ErrDisabled } +func (disabled) RegisterFilter(ctx context.Context, filter Filter) error { return ErrDisabled } -func (disabled) UnregisterFilter(name string, qopts ...pg.QOpt) error { return ErrDisabled } +func (disabled) UnregisterFilter(ctx context.Context, name string) error { return ErrDisabled } func (disabled) HasFilter(name string) bool { return false } -func (disabled) LatestBlock(qopts ...pg.QOpt) (LogPollerBlock, error) { +func (disabled) LatestBlock(ctx context.Context) (LogPollerBlock, error) { return LogPollerBlock{}, ErrDisabled } -func (disabled) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { +func (disabled) GetBlocksRange(ctx context.Context, numbers []uint64) ([]LogPollerBlock, error) { return nil, ErrDisabled } -func (disabled) Logs(start, end int64, eventSig common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) Logs(ctx context.Context, start, end int64, eventSig common.Hash, address common.Address) ([]Log, error) { return nil, ErrDisabled } -func (disabled) LogsWithSigs(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]Log, error) { return nil, ErrDisabled } -func (disabled) LatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs Confirmations, qopts ...pg.QOpt) (*Log, error) { +func (disabled) LatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { return nil, ErrDisabled } -func (disabled) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) LatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (disabled) IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) IndexedLogs(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (disabled) IndexedLogsByBlockRange(start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) IndexedLogsByBlockRange(ctx context.Context, tart, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash) ([]Log, error) { return nil, ErrDisabled } -func (d disabled) IndexedLogsByTxHash(eventSig common.Hash, address common.Address, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (d disabled) IndexedLogsByTxHash(ctx context.Context, eventSig common.Hash, address common.Address, txHash common.Hash) ([]Log, error) { return nil, ErrDisabled } -func (disabled) IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) IndexedLogsTopicGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (disabled) IndexedLogsTopicRange(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) IndexedLogsTopicRange(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (disabled) LogsDataWordRange(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) LogsDataWordRange(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (disabled) LogsDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (disabled) LogsDataWordGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (d disabled) IndexedLogsWithSigsExcluding(address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (d disabled) IndexedLogsWithSigsExcluding(ctx context.Context, address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (d disabled) LogsCreatedAfter(eventSig common.Hash, address common.Address, time time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (d disabled) LogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, time time.Time, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (d disabled) IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (d disabled) IndexedLogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } -func (d disabled) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) (int64, error) { +func (d disabled) LatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) { return 0, ErrDisabled } -func (d disabled) LogsDataWordBetween(eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (d disabled) LogsDataWordBetween(ctx context.Context, eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } diff --git a/core/chains/evm/logpoller/helper_test.go b/core/chains/evm/logpoller/helper_test.go index 9e48690a249..cd248cf5e70 100644 --- a/core/chains/evm/logpoller/helper_test.go +++ b/core/chains/evm/logpoller/helper_test.go @@ -25,7 +25,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_emitter" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -51,8 +50,8 @@ func SetupTH(t testing.TB, useFinalityTag bool, finalityDepth, backfillBatchSize chainID2 := testutils.NewRandomEVMChainID() db := pgtest.NewSqlxDB(t) - o := logpoller.NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) - o2 := logpoller.NewORM(chainID2, db, lggr, pgtest.NewQConfig(true)) + o := logpoller.NewORM(chainID, db, lggr) + o2 := logpoller.NewORM(chainID2, db, lggr) owner := testutils.MustNewSimTransactor(t) ethDB := rawdb.NewMemoryDatabase() ec := backends.NewSimulatedBackendWithDatabase(ethDB, map[common.Address]core.GenesisAccount{ @@ -91,20 +90,20 @@ func SetupTH(t testing.TB, useFinalityTag bool, finalityDepth, backfillBatchSize func (th *TestHarness) PollAndSaveLogs(ctx context.Context, currentBlockNumber int64) int64 { th.LogPoller.PollAndSaveLogs(ctx, currentBlockNumber) - latest, _ := th.LogPoller.LatestBlock(pg.WithParentCtx(ctx)) + latest, _ := th.LogPoller.LatestBlock(ctx) return latest.BlockNumber + 1 } func (th *TestHarness) assertDontHave(t *testing.T, start, end int) { for i := start; i < end; i++ { - _, err := th.ORM.SelectBlockByNumber(int64(i)) + _, err := th.ORM.SelectBlockByNumber(testutils.Context(t), int64(i)) assert.True(t, errors.Is(err, sql.ErrNoRows)) } } func (th *TestHarness) assertHaveCanonical(t *testing.T, start, end int) { for i := start; i < end; i++ { - blk, err := th.ORM.SelectBlockByNumber(int64(i)) + blk, err := th.ORM.SelectBlockByNumber(testutils.Context(t), int64(i)) require.NoError(t, err, "block %v", i) chainBlk, err := th.Client.BlockByNumber(testutils.Context(t), big.NewInt(int64(i))) require.NoError(t, err) diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 7006c1762ef..6fcb3ee97e2 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -28,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) //go:generate mockery --quiet --name LogPoller --output ./mocks/ --case=underscore --structname LogPoller --filename log_poller.go @@ -36,31 +35,31 @@ type LogPoller interface { services.Service Replay(ctx context.Context, fromBlock int64) error ReplayAsync(fromBlock int64) - RegisterFilter(filter Filter, qopts ...pg.QOpt) error - UnregisterFilter(name string, qopts ...pg.QOpt) error + RegisterFilter(ctx context.Context, filter Filter) error + UnregisterFilter(ctx context.Context, name string) error HasFilter(name string) bool - LatestBlock(qopts ...pg.QOpt) (LogPollerBlock, error) - GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) + LatestBlock(ctx context.Context) (LogPollerBlock, error) + GetBlocksRange(ctx context.Context, numbers []uint64) ([]LogPollerBlock, error) // General querying - Logs(start, end int64, eventSig common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) - LogsWithSigs(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) - LogsCreatedAfter(eventSig common.Hash, address common.Address, time time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - LatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs Confirmations, qopts ...pg.QOpt) (*Log, error) - LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) (int64, error) + Logs(ctx context.Context, start, end int64, eventSig common.Hash, address common.Address) ([]Log, error) + LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]Log, error) + LogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, time time.Time, confs Confirmations) ([]Log, error) + LatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) + LatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) ([]Log, error) + LatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) // Content based querying - IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - IndexedLogsByBlockRange(start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) - IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - IndexedLogsByTxHash(eventSig common.Hash, address common.Address, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) - IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - IndexedLogsTopicRange(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - IndexedLogsWithSigsExcluding(address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - LogsDataWordRange(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - LogsDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - LogsDataWordBetween(eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) + IndexedLogs(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) + IndexedLogsByBlockRange(ctx context.Context, start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash) ([]Log, error) + IndexedLogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) + IndexedLogsByTxHash(ctx context.Context, eventSig common.Hash, address common.Address, txHash common.Hash) ([]Log, error) + IndexedLogsTopicGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) + IndexedLogsTopicRange(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs Confirmations) ([]Log, error) + IndexedLogsWithSigsExcluding(ctx context.Context, address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs Confirmations) ([]Log, error) + LogsDataWordRange(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) + LogsDataWordGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) + LogsDataWordBetween(ctx context.Context, eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) } type Confirmations int @@ -218,7 +217,7 @@ func (filter *Filter) Contains(other *Filter) bool { // which means that anonymous events are not supported and log.Topics >= 1 always (log.Topics[0] is the event signature). // The filter may be unregistered later by Filter.Name // Warnings/debug information is keyed by filter name. -func (lp *logPoller) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { +func (lp *logPoller) RegisterFilter(ctx context.Context, filter Filter) error { if len(filter.Addresses) == 0 { return errors.Errorf("at least one address must be specified") } @@ -249,7 +248,7 @@ func (lp *logPoller) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { lp.lggr.Warnw("Updating existing filter with more events or addresses", "name", filter.Name, "filter", filter) } - if err := lp.orm.InsertFilter(filter, qopts...); err != nil { + if err := lp.orm.InsertFilter(ctx, filter); err != nil { return errors.Wrap(err, "error inserting filter") } lp.filters[filter.Name] = filter @@ -260,7 +259,7 @@ func (lp *logPoller) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { // UnregisterFilter will remove the filter with the given name. // If the name does not exist, it will log an error but not return an error. // Warnings/debug information is keyed by filter name. -func (lp *logPoller) UnregisterFilter(name string, qopts ...pg.QOpt) error { +func (lp *logPoller) UnregisterFilter(ctx context.Context, name string) error { lp.filterMu.Lock() defer lp.filterMu.Unlock() @@ -270,7 +269,7 @@ func (lp *logPoller) UnregisterFilter(name string, qopts ...pg.QOpt) error { return nil } - if err := lp.orm.DeleteFilter(name, qopts...); err != nil { + if err := lp.orm.DeleteFilter(ctx, name); err != nil { return errors.Wrap(err, "error deleting filter") } delete(lp.filters, name) @@ -414,7 +413,7 @@ func (lp *logPoller) HealthReport() map[string]error { } func (lp *logPoller) GetReplayFromBlock(ctx context.Context, requested int64) (int64, error) { - lastProcessed, err := lp.orm.SelectLatestBlock(pg.WithParentCtx(ctx)) + lastProcessed, err := lp.orm.SelectLatestBlock(ctx) if err != nil { if !errors.Is(err, sql.ErrNoRows) { // Real DB error @@ -441,7 +440,7 @@ func (lp *logPoller) run() { loadFilters := func() error { lp.filterMu.Lock() defer lp.filterMu.Unlock() - filters, err := lp.orm.LoadFilters(pg.WithParentCtx(lp.ctx)) + filters, err := lp.orm.LoadFilters(lp.ctx) if err != nil { return errors.Wrapf(err, "Failed to load initial filters from db, retrying") @@ -496,7 +495,7 @@ func (lp *logPoller) run() { // Always start from the latest block in the db. var start int64 - lastProcessed, err := lp.orm.SelectLatestBlock(pg.WithParentCtx(lp.ctx)) + lastProcessed, err := lp.orm.SelectLatestBlock(lp.ctx) if err != nil { if !errors.Is(err, sql.ErrNoRows) { // Assume transient db reading issue, retry forever. @@ -547,7 +546,7 @@ func (lp *logPoller) run() { } case <-logPruneTick: logPruneTick = time.After(utils.WithJitter(lp.pollPeriod * 2401)) // = 7^5 avoids common factors with 1000 - if err := lp.orm.DeleteExpiredLogs(pg.WithParentCtx(lp.ctx)); err != nil { + if err := lp.orm.DeleteExpiredLogs(lp.ctx); err != nil { lp.lggr.Error(err) } } @@ -556,7 +555,7 @@ func (lp *logPoller) run() { func (lp *logPoller) BackupPollAndSaveLogs(ctx context.Context, backupPollerBlockDelay int64) { if lp.backupPollerNextBlock == 0 { - lastProcessed, err := lp.orm.SelectLatestBlock(pg.WithParentCtx(ctx)) + lastProcessed, err := lp.orm.SelectLatestBlock(ctx) if err != nil { if errors.Is(err, sql.ErrNoRows) { lp.lggr.Warnw("Backup log poller ran before first successful log poller run, skipping") @@ -642,7 +641,6 @@ func (lp *logPoller) blocksFromLogs(ctx context.Context, logs []types.Log) (bloc for _, log := range logs { numbers = append(numbers, log.BlockNumber) } - return lp.GetBlocksRange(ctx, numbers) } @@ -683,7 +681,7 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error { } lp.lggr.Debugw("Backfill found logs", "from", from, "to", to, "logs", len(gethLogs), "blocks", blocks) - err = lp.orm.InsertLogsWithBlock(convertLogs(gethLogs, blocks, lp.lggr, lp.ec.ConfiguredChainID()), blocks[len(blocks)-1], pg.WithParentCtx(ctx)) + err = lp.orm.InsertLogsWithBlock(ctx, convertLogs(gethLogs, blocks, lp.lggr, lp.ec.ConfiguredChainID()), blocks[len(blocks)-1]) if err != nil { lp.lggr.Warnw("Unable to insert logs, retrying", "err", err, "from", from, "to", to) return err @@ -721,7 +719,7 @@ func (lp *logPoller) getCurrentBlockMaybeHandleReorg(ctx context.Context, curren } // Does this currentBlock point to the same parent that we have saved? // If not, there was a reorg, so we need to rewind. - expectedParent, err1 := lp.orm.SelectBlockByNumber(currentBlockNumber-1, pg.WithParentCtx(ctx)) + expectedParent, err1 := lp.orm.SelectBlockByNumber(ctx, currentBlockNumber-1) if err1 != nil && !errors.Is(err1, sql.ErrNoRows) { // If err is not a 'no rows' error, assume transient db issue and retry lp.lggr.Warnw("Unable to read latestBlockNumber currentBlock saved", "err", err1, "currentBlockNumber", currentBlockNumber) @@ -752,7 +750,7 @@ func (lp *logPoller) getCurrentBlockMaybeHandleReorg(ctx context.Context, curren // the canonical set per read. Typically, if an application took action on a log // it would be saved elsewhere e.g. evm.txes, so it seems better to just support the fast reads. // Its also nicely analogous to reading from the chain itself. - err2 = lp.orm.DeleteLogsAndBlocksAfter(blockAfterLCA.Number, pg.WithParentCtx(ctx)) + err2 = lp.orm.DeleteLogsAndBlocksAfter(ctx, blockAfterLCA.Number) if err2 != nil { // If we error on db commit, we can't know if the tx went through or not. // We return an error here which will cause us to restart polling from lastBlockSaved + 1 @@ -839,6 +837,7 @@ func (lp *logPoller) PollAndSaveLogs(ctx context.Context, currentBlockNumber int lp.lggr.Debugw("Unfinalized log query", "logs", len(logs), "currentBlockNumber", currentBlockNumber, "blockHash", currentBlock.Hash, "timestamp", currentBlock.Timestamp.Unix()) block := NewLogPollerBlock(h, currentBlockNumber, currentBlock.Timestamp, latestFinalizedBlockNumber) err = lp.orm.InsertLogsWithBlock( + ctx, convertLogs(logs, []LogPollerBlock{block}, lp.lggr, lp.ec.ConfiguredChainID()), block, ) @@ -906,7 +905,7 @@ func (lp *logPoller) findBlockAfterLCA(ctx context.Context, current *evmtypes.He // If the parent block number becomes < the first finalized block our reorg is too deep. // This can happen only if finalityTag is not enabled and fixed finalityDepth is provided via config. for parent.Number >= latestFinalizedBlockNumber { - ourParentBlockHash, err := lp.orm.SelectBlockByNumber(parent.Number, pg.WithParentCtx(ctx)) + ourParentBlockHash, err := lp.orm.SelectBlockByNumber(ctx, parent.Number) if err != nil { return nil, err } @@ -929,7 +928,7 @@ func (lp *logPoller) findBlockAfterLCA(ctx context.Context, current *evmtypes.He // PruneOldBlocks removes blocks that are > lp.keepFinalizedBlocksDepth behind the latest finalized block. func (lp *logPoller) PruneOldBlocks(ctx context.Context) error { - latestBlock, err := lp.orm.SelectLatestBlock(pg.WithParentCtx(ctx)) + latestBlock, err := lp.orm.SelectLatestBlock(ctx) if err != nil { return err } @@ -943,65 +942,65 @@ func (lp *logPoller) PruneOldBlocks(ctx context.Context) error { } // 1-2-3-4-5(finalized)-6-7(latest), keepFinalizedBlocksDepth=3 // Remove <= 2 - return lp.orm.DeleteBlocksBefore(latestBlock.FinalizedBlockNumber-lp.keepFinalizedBlocksDepth, pg.WithParentCtx(ctx)) + return lp.orm.DeleteBlocksBefore(ctx, latestBlock.FinalizedBlockNumber-lp.keepFinalizedBlocksDepth) } // Logs returns logs matching topics and address (exactly) in the given block range, // which are canonical at time of query. -func (lp *logPoller) Logs(start, end int64, eventSig common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogs(start, end, address, eventSig, qopts...) +func (lp *logPoller) Logs(ctx context.Context, start, end int64, eventSig common.Hash, address common.Address) ([]Log, error) { + return lp.orm.SelectLogs(ctx, start, end, address, eventSig) } -func (lp *logPoller) LogsWithSigs(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsWithSigs(start, end, address, eventSigs, qopts...) +func (lp *logPoller) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]Log, error) { + return lp.orm.SelectLogsWithSigs(ctx, start, end, address, eventSigs) } -func (lp *logPoller) LogsCreatedAfter(eventSig common.Hash, address common.Address, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsCreatedAfter(address, eventSig, after, confs, qopts...) +func (lp *logPoller) LogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, after time.Time, confs Confirmations) ([]Log, error) { + return lp.orm.SelectLogsCreatedAfter(ctx, address, eventSig, after, confs) } // IndexedLogs finds all the logs that have a topic value in topicValues at index topicIndex. -func (lp *logPoller) IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogs(address, eventSig, topicIndex, topicValues, confs, qopts...) +func (lp *logPoller) IndexedLogs(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) { + return lp.orm.SelectIndexedLogs(ctx, address, eventSig, topicIndex, topicValues, confs) } // IndexedLogsByBlockRange finds all the logs that have a topic value in topicValues at index topicIndex within the block range -func (lp *logPoller) IndexedLogsByBlockRange(start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogsByBlockRange(start, end, address, eventSig, topicIndex, topicValues, qopts...) +func (lp *logPoller) IndexedLogsByBlockRange(ctx context.Context, start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash) ([]Log, error) { + return lp.orm.SelectIndexedLogsByBlockRange(ctx, start, end, address, eventSig, topicIndex, topicValues) } -func (lp *logPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogsCreatedAfter(address, eventSig, topicIndex, topicValues, after, confs, qopts...) +func (lp *logPoller) IndexedLogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) { + return lp.orm.SelectIndexedLogsCreatedAfter(ctx, address, eventSig, topicIndex, topicValues, after, confs) } -func (lp *logPoller) IndexedLogsByTxHash(eventSig common.Hash, address common.Address, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogsByTxHash(address, eventSig, txHash, qopts...) +func (lp *logPoller) IndexedLogsByTxHash(ctx context.Context, eventSig common.Hash, address common.Address, txHash common.Hash) ([]Log, error) { + return lp.orm.SelectIndexedLogsByTxHash(ctx, address, eventSig, txHash) } // LogsDataWordGreaterThan note index is 0 based. -func (lp *logPoller) LogsDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, confs, qopts...) +func (lp *logPoller) LogsDataWordGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) { + return lp.orm.SelectLogsDataWordGreaterThan(ctx, address, eventSig, wordIndex, wordValueMin, confs) } // LogsDataWordRange note index is 0 based. -func (lp *logPoller) LogsDataWordRange(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsDataWordRange(address, eventSig, wordIndex, wordValueMin, wordValueMax, confs, qopts...) +func (lp *logPoller) LogsDataWordRange(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) { + return lp.orm.SelectLogsDataWordRange(ctx, address, eventSig, wordIndex, wordValueMin, wordValueMax, confs) } // IndexedLogsTopicGreaterThan finds all the logs that have a topic value greater than topicValueMin at index topicIndex. // Only works for integer topics. -func (lp *logPoller) IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogsTopicGreaterThan(address, eventSig, topicIndex, topicValueMin, confs, qopts...) +func (lp *logPoller) IndexedLogsTopicGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) { + return lp.orm.SelectIndexedLogsTopicGreaterThan(ctx, address, eventSig, topicIndex, topicValueMin, confs) } -func (lp *logPoller) IndexedLogsTopicRange(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogsTopicRange(address, eventSig, topicIndex, topicValueMin, topicValueMax, confs, qopts...) +func (lp *logPoller) IndexedLogsTopicRange(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs Confirmations) ([]Log, error) { + return lp.orm.SelectIndexedLogsTopicRange(ctx, address, eventSig, topicIndex, topicValueMin, topicValueMax, confs) } // LatestBlock returns the latest block the log poller is on. It tracks blocks to be able // to detect reorgs. -func (lp *logPoller) LatestBlock(qopts ...pg.QOpt) (LogPollerBlock, error) { - b, err := lp.orm.SelectLatestBlock(qopts...) +func (lp *logPoller) LatestBlock(ctx context.Context) (LogPollerBlock, error) { + b, err := lp.orm.SelectLatestBlock(ctx) if err != nil { return LogPollerBlock{}, err } @@ -1009,21 +1008,21 @@ func (lp *logPoller) LatestBlock(qopts ...pg.QOpt) (LogPollerBlock, error) { return *b, nil } -func (lp *logPoller) BlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, error) { - return lp.orm.SelectBlockByNumber(n, qopts...) +func (lp *logPoller) BlockByNumber(ctx context.Context, n int64) (*LogPollerBlock, error) { + return lp.orm.SelectBlockByNumber(ctx, n) } // LatestLogByEventSigWithConfs finds the latest log that has confs number of blocks on top of the log. -func (lp *logPoller) LatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs Confirmations, qopts ...pg.QOpt) (*Log, error) { - return lp.orm.SelectLatestLogByEventSigWithConfs(eventSig, address, confs, qopts...) +func (lp *logPoller) LatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { + return lp.orm.SelectLatestLogByEventSigWithConfs(ctx, eventSig, address, confs) } -func (lp *logPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLatestLogEventSigsAddrsWithConfs(fromBlock, addresses, eventSigs, confs, qopts...) +func (lp *logPoller) LatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) ([]Log, error) { + return lp.orm.SelectLatestLogEventSigsAddrsWithConfs(ctx, fromBlock, addresses, eventSigs, confs) } -func (lp *logPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) (int64, error) { - return lp.orm.SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock, eventSigs, addresses, confs, qopts...) +func (lp *logPoller) LatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) { + return lp.orm.SelectLatestBlockByEventSigsAddrsWithConfs(ctx, fromBlock, eventSigs, addresses, confs) } // LogsDataWordBetween retrieves a slice of Log records that match specific criteria. @@ -1035,13 +1034,13 @@ func (lp *logPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, event // // This function is particularly useful for filtering logs by data word values and their positions within the event data. // It returns an empty slice if no logs match the provided criteria. -func (lp *logPoller) LogsDataWordBetween(eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsDataWordBetween(address, eventSig, wordIndexMin, wordIndexMax, wordValue, confs, qopts...) +func (lp *logPoller) LogsDataWordBetween(ctx context.Context, eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) { + return lp.orm.SelectLogsDataWordBetween(ctx, address, eventSig, wordIndexMin, wordIndexMax, wordValue, confs) } // GetBlocksRange tries to get the specified block numbers from the log pollers // blocks table. It falls back to the RPC for any unfulfilled requested blocks. -func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { +func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64) ([]LogPollerBlock, error) { var blocks []LogPollerBlock // Do nothing if no blocks are requested. @@ -1057,10 +1056,9 @@ func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts // Retrieve all blocks within this range from the log poller. blocksFound := make(map[uint64]LogPollerBlock) - qopts = append(qopts, pg.WithParentCtx(ctx)) minRequestedBlock := int64(mathutil.Min(numbers[0], numbers[1:]...)) maxRequestedBlock := int64(mathutil.Max(numbers[0], numbers[1:]...)) - lpBlocks, err := lp.orm.GetBlocksRange(minRequestedBlock, maxRequestedBlock, qopts...) + lpBlocks, err := lp.orm.GetBlocksRange(ctx, minRequestedBlock, maxRequestedBlock) if err != nil { lp.lggr.Warnw("Error while retrieving blocks from log pollers blocks table. Falling back to RPC...", "requestedBlocks", numbers, "err", err) } else { @@ -1185,8 +1183,8 @@ func (lp *logPoller) batchFetchBlocks(ctx context.Context, blocksRequested []str // // For example, query to retrieve unfulfilled requests by querying request log events without matching fulfillment log events. // The order of events is not significant. Both logs must be inside the block range and have the minimum number of confirmations -func (lp *logPoller) IndexedLogsWithSigsExcluding(address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogsWithSigsExcluding(eventSigA, eventSigB, topicIndex, address, fromBlock, toBlock, confs, qopts...) +func (lp *logPoller) IndexedLogsWithSigsExcluding(ctx context.Context, address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs Confirmations) ([]Log, error) { + return lp.orm.SelectIndexedLogsWithSigsExcluding(ctx, eventSigA, eventSigB, topicIndex, address, fromBlock, toBlock, confs) } func EvmWord(i uint64) common.Hash { diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go index 863ab0fddea..a35e01d7af6 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -30,7 +30,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_emitter" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -39,7 +38,8 @@ var ( // Validate that filters stored in log_filters_table match the filters stored in memory func validateFiltersTable(t *testing.T, lp *logPoller, orm *DbORM) { - filters, err := orm.LoadFilters() + ctx := testutils.Context(t) + filters, err := orm.LoadFilters(ctx) require.NoError(t, err) require.Equal(t, len(filters), len(lp.filters)) for name, dbFilter := range filters { @@ -61,7 +61,7 @@ func TestLogPoller_RegisterFilter(t *testing.T) { chainID := testutils.NewRandomEVMChainID() db := pgtest.NewSqlxDB(t) - orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + orm := NewORM(chainID, db, lggr) // Set up a test chain with a log emitting contract deployed. lp := NewLogPoller(orm, nil, lggr, time.Hour, false, 1, 1, 2, 1000) @@ -71,36 +71,36 @@ func TestLogPoller_RegisterFilter(t *testing.T) { require.Equal(t, 1, len(f.Addresses)) assert.Equal(t, common.HexToAddress("0x0000000000000000000000000000000000000000"), f.Addresses[0]) - err := lp.RegisterFilter(Filter{"Emitter Log 1", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{a1}, 0}) + err := lp.RegisterFilter(testutils.Context(t), Filter{"Emitter Log 1", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{a1}, 0}) require.NoError(t, err) assert.Equal(t, []common.Address{a1}, lp.Filter(nil, nil, nil).Addresses) assert.Equal(t, [][]common.Hash{{EmitterABI.Events["Log1"].ID}}, lp.Filter(nil, nil, nil).Topics) validateFiltersTable(t, lp, orm) // Should de-dupe EventSigs - err = lp.RegisterFilter(Filter{"Emitter Log 1 + 2", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{a2}, 0}) + err = lp.RegisterFilter(testutils.Context(t), Filter{"Emitter Log 1 + 2", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{a2}, 0}) require.NoError(t, err) assert.Equal(t, []common.Address{a1, a2}, lp.Filter(nil, nil, nil).Addresses) assert.Equal(t, [][]common.Hash{{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}}, lp.Filter(nil, nil, nil).Topics) validateFiltersTable(t, lp, orm) // Should de-dupe Addresses - err = lp.RegisterFilter(Filter{"Emitter Log 1 + 2 dupe", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{a2}, 0}) + err = lp.RegisterFilter(testutils.Context(t), Filter{"Emitter Log 1 + 2 dupe", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{a2}, 0}) require.NoError(t, err) assert.Equal(t, []common.Address{a1, a2}, lp.Filter(nil, nil, nil).Addresses) assert.Equal(t, [][]common.Hash{{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}}, lp.Filter(nil, nil, nil).Topics) validateFiltersTable(t, lp, orm) // Address required. - err = lp.RegisterFilter(Filter{"no address", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{}, 0}) + err = lp.RegisterFilter(testutils.Context(t), Filter{"no address", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{}, 0}) require.Error(t, err) // Event required - err = lp.RegisterFilter(Filter{"No event", []common.Hash{}, []common.Address{a1}, 0}) + err = lp.RegisterFilter(testutils.Context(t), Filter{"No event", []common.Hash{}, []common.Address{a1}, 0}) require.Error(t, err) validateFiltersTable(t, lp, orm) // Removing non-existence Filter should log error but return nil - err = lp.UnregisterFilter("Filter doesn't exist") + err = lp.UnregisterFilter(testutils.Context(t), "Filter doesn't exist") require.NoError(t, err) require.Equal(t, observedLogs.Len(), 1) require.Contains(t, observedLogs.TakeAll()[0].Entry.Message, "not found") @@ -114,19 +114,19 @@ func TestLogPoller_RegisterFilter(t *testing.T) { require.True(t, ok, "'Emitter Log 1 + 2 dupe' Filter missing") // Removing an existing Filter should remove it from both memory and db - err = lp.UnregisterFilter("Emitter Log 1 + 2") + err = lp.UnregisterFilter(testutils.Context(t), "Emitter Log 1 + 2") require.NoError(t, err) _, ok = lp.filters["Emitter Log 1 + 2"] require.False(t, ok, "'Emitter Log 1 Filter' should have been removed by UnregisterFilter()") require.Len(t, lp.filters, 2) validateFiltersTable(t, lp, orm) - err = lp.UnregisterFilter("Emitter Log 1 + 2 dupe") + err = lp.UnregisterFilter(testutils.Context(t), "Emitter Log 1 + 2 dupe") require.NoError(t, err) - err = lp.UnregisterFilter("Emitter Log 1") + err = lp.UnregisterFilter(testutils.Context(t), "Emitter Log 1") require.NoError(t, err) assert.Len(t, lp.filters, 0) - filters, err := lp.orm.LoadFilters() + filters, err := lp.orm.LoadFilters(testutils.Context(t)) require.NoError(t, err) assert.Len(t, filters, 0) @@ -197,7 +197,7 @@ func TestLogPoller_BackupPollerStartup(t *testing.T) { lggr, observedLogs := logger.TestObserved(t, zapcore.WarnLevel) chainID := testutils.FixtureChainID db := pgtest.NewSqlxDB(t) - orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + orm := NewORM(chainID, db, lggr) head := evmtypes.Head{Number: 3} events := []common.Hash{EmitterABI.Events["Log1"].ID} @@ -225,7 +225,7 @@ func TestLogPoller_BackupPollerStartup(t *testing.T) { lp.PollAndSaveLogs(ctx, 3) - lastProcessed, err := lp.orm.SelectLatestBlock(pg.WithParentCtx(ctx)) + lastProcessed, err := lp.orm.SelectLatestBlock(ctx) require.NoError(t, err) require.Equal(t, int64(3), lastProcessed.BlockNumber) @@ -240,7 +240,7 @@ func TestLogPoller_Replay(t *testing.T) { lggr, observedLogs := logger.TestObserved(t, zapcore.ErrorLevel) chainID := testutils.FixtureChainID db := pgtest.NewSqlxDB(t) - orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + orm := NewORM(chainID, db, lggr) head := evmtypes.Head{Number: 4} events := []common.Hash{EmitterABI.Events["Log1"].ID} @@ -262,7 +262,7 @@ func TestLogPoller_Replay(t *testing.T) { // process 1 log in block 3 lp.PollAndSaveLogs(testutils.Context(t), 4) - latest, err := lp.LatestBlock() + latest, err := lp.LatestBlock(testutils.Context(t)) require.NoError(t, err) require.Equal(t, int64(4), latest.BlockNumber) @@ -438,7 +438,7 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { lggr := logger.Test(t) chainID := testutils.FixtureChainID db := pgtest.NewSqlxDB(t) - orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + orm := NewORM(chainID, db, lggr) t.Run("pick latest block from chain and use finality from config with finality disabled", func(t *testing.T) { head := evmtypes.Head{Number: 4} @@ -516,7 +516,7 @@ func benchmarkFilter(b *testing.B, nFilters, nAddresses, nEvents int) { for j := 0; j < nEvents; j++ { events = append(events, common.BigToHash(big.NewInt(int64(j+1)))) } - err := lp.RegisterFilter(Filter{Name: "my Filter", EventSigs: events, Addresses: addresses}) + err := lp.RegisterFilter(testutils.Context(b), Filter{Name: "my Filter", EventSigs: events, Addresses: addresses}) require.NoError(b, err) } b.ResetTimer() diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 2508e676e6c..3f86ae846d4 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -38,7 +38,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) func logRuntime(t testing.TB, start time.Time) { @@ -50,6 +49,7 @@ func populateDatabase(t testing.TB, o *logpoller.DbORM, chainID *big.Int) (commo address1 := common.HexToAddress("0x2ab9a2Dc53736b361b72d900CdF9F78F9406fbbb") address2 := common.HexToAddress("0x6E225058950f237371261C985Db6bDe26df2200E") startDate := time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC) + ctx := testutils.Context(t) for j := 1; j < 100; j++ { var logs []logpoller.Log @@ -77,8 +77,8 @@ func populateDatabase(t testing.TB, o *logpoller.DbORM, chainID *big.Int) (commo }) } - require.NoError(t, o.InsertLogs(logs)) - require.NoError(t, o.InsertBlock(utils.RandomHash(), int64((j+1)*1000-1), startDate.Add(time.Duration(j*1000)*time.Hour), 0)) + require.NoError(t, o.InsertLogs(ctx, logs)) + require.NoError(t, o.InsertBlock(ctx, utils.RandomHash(), int64((j+1)*1000-1), startDate.Add(time.Duration(j*1000)*time.Hour), 0)) } return event1, address1, address2 @@ -86,8 +86,9 @@ func populateDatabase(t testing.TB, o *logpoller.DbORM, chainID *big.Int) (commo func BenchmarkSelectLogsCreatedAfter(b *testing.B) { chainId := big.NewInt(137) + ctx := testutils.Context(b) _, db := heavyweight.FullTestDBV2(b, nil) - o := logpoller.NewORM(chainId, db, logger.Test(b), pgtest.NewQConfig(false)) + o := logpoller.NewORM(chainId, db, logger.Test(b)) event, address, _ := populateDatabase(b, o, chainId) // Setting searchDate to pick around 5k logs @@ -96,7 +97,7 @@ func BenchmarkSelectLogsCreatedAfter(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - logs, err := o.SelectLogsCreatedAfter(address, event, searchDate, 500) + logs, err := o.SelectLogsCreatedAfter(ctx, address, event, searchDate, 500) require.NotZero(b, len(logs)) require.NoError(b, err) } @@ -105,52 +106,54 @@ func BenchmarkSelectLogsCreatedAfter(b *testing.B) { func TestPopulateLoadedDB(t *testing.T) { t.Skip("Only for local load testing and query analysis") _, db := heavyweight.FullTestDBV2(t, nil) + ctx := testutils.Context(t) chainID := big.NewInt(137) - o := logpoller.NewORM(big.NewInt(137), db, logger.Test(t), pgtest.NewQConfig(true)) + o := logpoller.NewORM(big.NewInt(137), db, logger.Test(t)) event1, address1, address2 := populateDatabase(t, o, chainID) func() { defer logRuntime(t, time.Now()) - _, err1 := o.SelectLogs(750000, 800000, address1, event1) + _, err1 := o.SelectLogs(ctx, 750000, 800000, address1, event1) require.NoError(t, err1) }() func() { defer logRuntime(t, time.Now()) - _, err1 := o.SelectLatestLogEventSigsAddrsWithConfs(0, []common.Address{address1}, []common.Hash{event1}, 0) + _, err1 := o.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0, []common.Address{address1}, []common.Hash{event1}, 0) require.NoError(t, err1) }() // Confirm all the logs. - require.NoError(t, o.InsertBlock(common.HexToHash("0x10"), 1000000, time.Now(), 0)) + require.NoError(t, o.InsertBlock(ctx, common.HexToHash("0x10"), 1000000, time.Now(), 0)) func() { defer logRuntime(t, time.Now()) - lgs, err1 := o.SelectLogsDataWordRange(address1, event1, 0, logpoller.EvmWord(500000), logpoller.EvmWord(500020), 0) + lgs, err1 := o.SelectLogsDataWordRange(ctx, address1, event1, 0, logpoller.EvmWord(50000), logpoller.EvmWord(50020), 0) require.NoError(t, err1) // 10 since every other log is for address1 - assert.Equal(t, 10, len(lgs)) + require.Equal(t, 10, len(lgs)) }() func() { defer logRuntime(t, time.Now()) - lgs, err1 := o.SelectIndexedLogs(address2, event1, 1, []common.Hash{logpoller.EvmWord(500000), logpoller.EvmWord(500020)}, 0) + lgs, err1 := o.SelectIndexedLogs(ctx, address2, event1, 1, []common.Hash{logpoller.EvmWord(50000), logpoller.EvmWord(50020)}, 0) require.NoError(t, err1) - assert.Equal(t, 2, len(lgs)) + require.Equal(t, 2, len(lgs)) }() func() { defer logRuntime(t, time.Now()) - lgs, err1 := o.SelectIndexedLogsTopicRange(address1, event1, 1, logpoller.EvmWord(500000), logpoller.EvmWord(500020), 0) + lgs, err1 := o.SelectIndexedLogsTopicRange(ctx, address1, event1, 1, logpoller.EvmWord(50000), logpoller.EvmWord(50020), 0) require.NoError(t, err1) - assert.Equal(t, 10, len(lgs)) + require.Equal(t, 10, len(lgs)) }() } func TestLogPoller_Integration(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) th.Client.Commit() // Block 2. Ensure we have finality number of blocks + ctx := testutils.Context(t) - require.NoError(t, th.LogPoller.RegisterFilter(logpoller.Filter{"Integration test", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{th.EmitterAddress1}, 0})) + require.NoError(t, th.LogPoller.RegisterFilter(ctx, logpoller.Filter{"Integration test", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{th.EmitterAddress1}, 0})) require.Len(t, th.LogPoller.Filter(nil, nil, nil).Addresses, 1) require.Len(t, th.LogPoller.Filter(nil, nil, nil).Topics, 1) @@ -174,20 +177,19 @@ func TestLogPoller_Integration(t *testing.T) { require.NoError(t, th.LogPoller.Replay(testutils.Context(t), 4)) // We should immediately have at least logs 4-7 - logs, err := th.LogPoller.Logs(4, 7, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t))) + logs, err := th.LogPoller.Logs(ctx, 4, 7, EmitterABI.Events["Log1"].ID, th.EmitterAddress1) require.NoError(t, err) require.Equal(t, 4, len(logs)) // Once the backup poller runs we should also have the log from block 3 testutils.AssertEventually(t, func() bool { - l, err2 := th.LogPoller.Logs(3, 3, EmitterABI.Events["Log1"].ID, th.EmitterAddress1) + l, err2 := th.LogPoller.Logs(ctx, 3, 3, EmitterABI.Events["Log1"].ID, th.EmitterAddress1) require.NoError(t, err2) return len(l) == 1 }) // Now let's update the Filter and replay to get Log2 logs. - err = th.LogPoller.RegisterFilter(logpoller.Filter{ + err = th.LogPoller.RegisterFilter(ctx, logpoller.Filter{ "Emitter - log2", []common.Hash{EmitterABI.Events["Log2"].ID}, []common.Address{th.EmitterAddress1}, 0, }) @@ -197,7 +199,7 @@ func TestLogPoller_Integration(t *testing.T) { assert.Error(t, th.LogPoller.Replay(testutils.Context(t), 20)) // Still shouldn't have any Log2 logs yet - logs, err = th.LogPoller.Logs(2, 7, EmitterABI.Events["Log2"].ID, th.EmitterAddress1) + logs, err = th.LogPoller.Logs(ctx, 2, 7, EmitterABI.Events["Log2"].ID, th.EmitterAddress1) require.NoError(t, err) require.Len(t, logs, 0) @@ -205,8 +207,7 @@ func TestLogPoller_Integration(t *testing.T) { require.NoError(t, th.LogPoller.Replay(testutils.Context(t), 4)) // We should immediately see 4 logs2 logs. - logs, err = th.LogPoller.Logs(2, 7, EmitterABI.Events["Log2"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t))) + logs, err = th.LogPoller.Logs(ctx, 2, 7, EmitterABI.Events["Log2"].ID, th.EmitterAddress1) require.NoError(t, err) assert.Equal(t, 4, len(logs)) @@ -259,25 +260,26 @@ func Test_BackupLogPoller(t *testing.T) { EmitterABI.Events["Log2"].ID}, []common.Address{th.EmitterAddress1}, 0} - err := th.LogPoller.RegisterFilter(filter1) + err := th.LogPoller.RegisterFilter(ctx, filter1) require.NoError(t, err) - filters, err := th.ORM.LoadFilters(pg.WithParentCtx(testutils.Context(t))) + filters, err := th.ORM.LoadFilters(ctx) require.NoError(t, err) require.Equal(t, 1, len(filters)) require.Equal(t, filter1, filters["filter1"]) err = th.LogPoller.RegisterFilter( + ctx, logpoller.Filter{"filter2", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{th.EmitterAddress2}, 0}) require.NoError(t, err) defer func() { - assert.NoError(t, th.LogPoller.UnregisterFilter("filter1")) + assert.NoError(t, th.LogPoller.UnregisterFilter(ctx, "filter1")) }() defer func() { - assert.NoError(t, th.LogPoller.UnregisterFilter("filter2")) + assert.NoError(t, th.LogPoller.UnregisterFilter(ctx, "filter2")) }() // generate some tx's with logs @@ -333,8 +335,7 @@ func Test_BackupLogPoller(t *testing.T) { require.Equal(t, 32, len(fLogs)) // logs shouldn't show up yet - logs, err := th.LogPoller.Logs(34, 34, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t))) + logs, err := th.LogPoller.Logs(ctx, 34, 34, EmitterABI.Events["Log1"].ID, th.EmitterAddress1) require.NoError(t, err) assert.Equal(t, 0, len(logs)) @@ -343,17 +344,16 @@ func Test_BackupLogPoller(t *testing.T) { markBlockAsFinalized(t, th, 34) // Run ordinary poller + backup poller at least once - currentBlock, _ := th.LogPoller.LatestBlock(pg.WithParentCtx(testutils.Context(t))) + currentBlock, _ := th.LogPoller.LatestBlock(ctx) th.LogPoller.PollAndSaveLogs(ctx, currentBlock.BlockNumber+1) th.LogPoller.BackupPollAndSaveLogs(ctx, 100) - currentBlock, _ = th.LogPoller.LatestBlock(pg.WithParentCtx(testutils.Context(t))) + currentBlock, _ = th.LogPoller.LatestBlock(ctx) require.Equal(t, int64(37), currentBlock.BlockNumber+1) // logs still shouldn't show up, because we don't want to backfill the last finalized log // to help with reorg detection - logs, err = th.LogPoller.Logs(34, 34, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t))) + logs, err = th.LogPoller.Logs(ctx, 34, 34, EmitterABI.Events["Log1"].ID, th.EmitterAddress1) require.NoError(t, err) assert.Equal(t, 0, len(logs)) th.Client.Commit() @@ -362,21 +362,18 @@ func Test_BackupLogPoller(t *testing.T) { // Run ordinary poller + backup poller at least once more th.LogPoller.PollAndSaveLogs(ctx, currentBlockNumber+1) th.LogPoller.BackupPollAndSaveLogs(ctx, 100) - currentBlock, _ = th.LogPoller.LatestBlock(pg.WithParentCtx(testutils.Context(t))) + currentBlock, _ = th.LogPoller.LatestBlock(ctx) require.Equal(t, int64(38), currentBlock.BlockNumber+1) // all 3 logs in block 34 should show up now, thanks to backup logger - logs, err = th.LogPoller.Logs(30, 37, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t))) + logs, err = th.LogPoller.Logs(ctx, 30, 37, EmitterABI.Events["Log1"].ID, th.EmitterAddress1) require.NoError(t, err) assert.Equal(t, 5, len(logs)) - logs, err = th.LogPoller.Logs(34, 34, EmitterABI.Events["Log2"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t))) + logs, err = th.LogPoller.Logs(ctx, 34, 34, EmitterABI.Events["Log2"].ID, th.EmitterAddress1) require.NoError(t, err) assert.Equal(t, 1, len(logs)) - logs, err = th.LogPoller.Logs(32, 36, EmitterABI.Events["Log1"].ID, th.EmitterAddress2, - pg.WithParentCtx(testutils.Context(t))) + logs, err = th.LogPoller.Logs(ctx, 32, 36, EmitterABI.Events["Log1"].ID, th.EmitterAddress2) require.NoError(t, err) assert.Equal(t, 1, len(logs)) }) @@ -410,7 +407,7 @@ func TestLogPoller_BackupPollAndSaveLogsWithPollerNotWorking(t *testing.T) { // 0 -> 1 -> 2 -> ... -> currentBlock - 10 (finalized) -> .. -> currentBlock markBlockAsFinalized(t, th, currentBlock-10) - err = th.LogPoller.RegisterFilter(logpoller.Filter{ + err = th.LogPoller.RegisterFilter(ctx, logpoller.Filter{ Name: "Test Emitter", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, Addresses: []common.Address{th.EmitterAddress1}, @@ -423,11 +420,11 @@ func TestLogPoller_BackupPollAndSaveLogsWithPollerNotWorking(t *testing.T) { require.NoError(t, err) logs, err := th.LogPoller.Logs( + ctx, 0, currentBlock, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) require.Len(t, logs, emittedLogs-10) @@ -439,11 +436,11 @@ func TestLogPoller_BackupPollAndSaveLogsWithPollerNotWorking(t *testing.T) { // All emitted logs should be backfilled logs, err = th.LogPoller.Logs( + ctx, 0, currentBlock+1, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) require.Len(t, logs, emittedLogs) @@ -473,14 +470,14 @@ func TestLogPoller_BackupPollAndSaveLogsWithDeepBlockDelay(t *testing.T) { th.PollAndSaveLogs(ctx, 1) // Check that latest block has the same properties as the head - latestBlock, err := th.LogPoller.LatestBlock() + latestBlock, err := th.LogPoller.LatestBlock(ctx) require.NoError(t, err) assert.Equal(t, latestBlock.BlockNumber, header.Number.Int64()) assert.Equal(t, latestBlock.FinalizedBlockNumber, header.Number.Int64()) assert.Equal(t, latestBlock.BlockHash, header.Hash()) // Register filter - err = th.LogPoller.RegisterFilter(logpoller.Filter{ + err = th.LogPoller.RegisterFilter(ctx, logpoller.Filter{ Name: "Test Emitter", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, Addresses: []common.Address{th.EmitterAddress1}, @@ -493,11 +490,11 @@ func TestLogPoller_BackupPollAndSaveLogsWithDeepBlockDelay(t *testing.T) { // All emitted logs should be backfilled logs, err := th.LogPoller.Logs( + ctx, 0, header.Number.Int64()+1, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) require.Len(t, logs, emittedLogs) @@ -538,7 +535,7 @@ func TestLogPoller_BackupPollAndSaveLogsSkippingLogsThatAreTooOld(t *testing.T) markBlockAsFinalized(t, th, secondBatchBlock) // Register filter - err := th.LogPoller.RegisterFilter(logpoller.Filter{ + err := th.LogPoller.RegisterFilter(ctx, logpoller.Filter{ Name: "Test Emitter", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, Addresses: []common.Address{th.EmitterAddress1}, @@ -552,11 +549,11 @@ func TestLogPoller_BackupPollAndSaveLogsSkippingLogsThatAreTooOld(t *testing.T) // Only the 2nd batch + 1 log from a previous batch should be backfilled, because we perform backfill starting // from one block behind the latest finalized block logs, err := th.LogPoller.Logs( + ctx, 0, secondBatchBlock, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) require.Len(t, logs, logsBatch+1) @@ -571,7 +568,7 @@ func TestLogPoller_BlockTimestamps(t *testing.T) { addresses := []common.Address{th.EmitterAddress1, th.EmitterAddress2} topics := []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID} - err := th.LogPoller.RegisterFilter(logpoller.Filter{"convertLogs", topics, addresses, 0}) + err := th.LogPoller.RegisterFilter(ctx, logpoller.Filter{"convertLogs", topics, addresses, 0}) require.NoError(t, err) blk, err := th.Client.BlockByNumber(ctx, nil) @@ -626,13 +623,11 @@ func TestLogPoller_BlockTimestamps(t *testing.T) { require.NoError(t, err) require.Len(t, gethLogs, 2) - lb, _ := th.LogPoller.LatestBlock(pg.WithParentCtx(testutils.Context(t))) + lb, _ := th.LogPoller.LatestBlock(ctx) th.PollAndSaveLogs(ctx, lb.BlockNumber+1) - lg1, err := th.LogPoller.Logs(0, 20, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(ctx)) + lg1, err := th.LogPoller.Logs(ctx, 0, 20, EmitterABI.Events["Log1"].ID, th.EmitterAddress1) require.NoError(t, err) - lg2, err := th.LogPoller.Logs(0, 20, EmitterABI.Events["Log2"].ID, th.EmitterAddress2, - pg.WithParentCtx(ctx)) + lg2, err := th.LogPoller.Logs(ctx, 0, 20, EmitterABI.Events["Log2"].ID, th.EmitterAddress2) require.NoError(t, err) // Logs should have correct timestamps @@ -662,7 +657,7 @@ func TestLogPoller_SynchronizedWithGeth(t *testing.T) { t.Log("Starting test", mineOrReorg) chainID := testutils.NewRandomEVMChainID() // Set up a test chain with a log emitting contract deployed. - orm := logpoller.NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + orm := logpoller.NewORM(chainID, db, lggr) // Note this property test is run concurrently and the sim is not threadsafe. ec := backends.NewSimulatedBackend(map[common.Address]core.GenesisAccount{ owner.From: { @@ -677,14 +672,14 @@ func TestLogPoller_SynchronizedWithGeth(t *testing.T) { } currentBlockNumber := int64(1) lp.PollAndSaveLogs(testutils.Context(t), currentBlockNumber) - currentBlock, err := lp.LatestBlock(pg.WithParentCtx(testutils.Context(t))) + currentBlock, err := lp.LatestBlock(testutils.Context(t)) require.NoError(t, err) matchesGeth := func() bool { // Check every block is identical latest, err1 := ec.BlockByNumber(testutils.Context(t), nil) require.NoError(t, err1) for i := 1; i < int(latest.NumberU64()); i++ { - ourBlock, err1 := lp.BlockByNumber(int64(i)) + ourBlock, err1 := lp.BlockByNumber(testutils.Context(t), int64(i)) require.NoError(t, err1) gethBlock, err1 := ec.BlockByNumber(testutils.Context(t), big.NewInt(int64(i))) require.NoError(t, err1) @@ -728,7 +723,7 @@ func TestLogPoller_SynchronizedWithGeth(t *testing.T) { t.Logf("New latest (%v, %x), latest parent %x)\n", latest.NumberU64(), latest.Hash(), latest.ParentHash()) } lp.PollAndSaveLogs(testutils.Context(t), currentBlock.BlockNumber) - currentBlock, err = lp.LatestBlock(pg.WithParentCtx(testutils.Context(t))) + currentBlock, err = lp.LatestBlock(testutils.Context(t)) require.NoError(t, err) } return matchesGeth() @@ -761,7 +756,7 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { th := SetupTH(t, tt.finalityTag, tt.finalityDepth, 3, 2, 1000) // Set up a log poller listening for log emitter logs. - err := th.LogPoller.RegisterFilter(logpoller.Filter{ + err := th.LogPoller.RegisterFilter(testutils.Context(t), logpoller.Filter{ "Test Emitter 1 & 2", []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{th.EmitterAddress1, th.EmitterAddress2}, 0, }) @@ -779,7 +774,7 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { assert.Equal(t, int64(2), newStart) // We expect to have saved block 1. - lpb, err := th.ORM.SelectBlockByNumber(1) + lpb, err := th.ORM.SelectBlockByNumber(testutils.Context(t), 1) require.NoError(t, err) assert.Equal(t, lpb.BlockHash, b.Hash()) assert.Equal(t, lpb.BlockNumber, int64(b.NumberU64())) @@ -787,7 +782,7 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { assert.Equal(t, uint64(10), b.Time()) // No logs. - lgs, err := th.ORM.SelectLogsByBlockRange(1, 1) + lgs, err := th.ORM.SelectLogsByBlockRange(testutils.Context(t), 1, 1) require.NoError(t, err) assert.Equal(t, 0, len(lgs)) th.assertHaveCanonical(t, 1, 1) @@ -795,7 +790,7 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { // Polling again should be a noop, since we are at the latest. newStart = th.PollAndSaveLogs(testutils.Context(t), newStart) assert.Equal(t, int64(2), newStart) - latest, err := th.ORM.SelectLatestBlock() + latest, err := th.ORM.SelectLatestBlock(testutils.Context(t)) require.NoError(t, err) assert.Equal(t, int64(1), latest.BlockNumber) th.assertHaveCanonical(t, 1, 1) @@ -810,10 +805,10 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { // Polling should get us the L1 log. newStart = th.PollAndSaveLogs(testutils.Context(t), newStart) assert.Equal(t, int64(3), newStart) - latest, err = th.ORM.SelectLatestBlock() + latest, err = th.ORM.SelectLatestBlock(testutils.Context(t)) require.NoError(t, err) assert.Equal(t, int64(2), latest.BlockNumber) - lgs, err = th.ORM.SelectLogsByBlockRange(1, 3) + lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 1, 3) require.NoError(t, err) require.Equal(t, 1, len(lgs)) assert.Equal(t, th.EmitterAddress1, lgs[0].Address) @@ -845,10 +840,10 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { newStart = th.PollAndSaveLogs(testutils.Context(t), newStart) assert.Equal(t, int64(4), newStart) - latest, err = th.ORM.SelectLatestBlock() + latest, err = th.ORM.SelectLatestBlock(testutils.Context(t)) require.NoError(t, err) assert.Equal(t, int64(3), latest.BlockNumber) - lgs, err = th.ORM.SelectLogsByBlockRange(1, 3) + lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 1, 3) require.NoError(t, err) require.Equal(t, 1, len(lgs)) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000002`), lgs[0].Data) @@ -868,10 +863,10 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { markBlockAsFinalized(t, th, 1) newStart = th.PollAndSaveLogs(testutils.Context(t), newStart) assert.Equal(t, int64(5), newStart) - latest, err = th.ORM.SelectLatestBlock() + latest, err = th.ORM.SelectLatestBlock(testutils.Context(t)) require.NoError(t, err) assert.Equal(t, int64(4), latest.BlockNumber) - lgs, err = th.ORM.SelectLogsByBlockRange(1, 3) + lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 1, 3) require.NoError(t, err) // We expect ONLY L1_1 and L1_3 since L1_2 is reorg'd out. assert.Equal(t, 2, len(lgs)) @@ -904,7 +899,7 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { newStart = th.PollAndSaveLogs(testutils.Context(t), newStart) assert.Equal(t, int64(7), newStart) - lgs, err = th.ORM.SelectLogsByBlockRange(4, 6) + lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 4, 6) require.NoError(t, err) require.Equal(t, 3, len(lgs)) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000004`), lgs[0].Data) @@ -934,7 +929,7 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { newStart = th.PollAndSaveLogs(testutils.Context(t), newStart) assert.Equal(t, int64(11), newStart) - lgs, err = th.ORM.SelectLogsByBlockRange(7, 9) + lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 7, 9) require.NoError(t, err) require.Equal(t, 3, len(lgs)) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000007`), lgs[0].Data) @@ -963,7 +958,7 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { newStart = th.PollAndSaveLogs(testutils.Context(t), newStart) assert.Equal(t, int64(18), newStart) - lgs, err = th.ORM.SelectLogsByBlockRange(11, 17) + lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 11, 17) require.NoError(t, err) assert.Equal(t, 7, len(lgs)) th.assertHaveCanonical(t, 14, 16) // Should have last finalized block plus unfinalized blocks @@ -1009,7 +1004,7 @@ func TestLogPoller_PollAndSaveLogsDeepReorg(t *testing.T) { th := SetupTH(t, tt.finalityTag, tt.finalityDepth, 3, 2, 1000) // Set up a log poller listening for log emitter logs. - err := th.LogPoller.RegisterFilter(logpoller.Filter{ + err := th.LogPoller.RegisterFilter(testutils.Context(t), logpoller.Filter{ Name: "Test Emitter", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, Addresses: []common.Address{th.EmitterAddress1}, @@ -1028,7 +1023,7 @@ func TestLogPoller_PollAndSaveLogsDeepReorg(t *testing.T) { newStart := th.PollAndSaveLogs(testutils.Context(t), 1) assert.Equal(t, int64(3), newStart) // Check that L1_1 has a proper data payload - lgs, err := th.ORM.SelectLogsByBlockRange(2, 2) + lgs, err := th.ORM.SelectLogsByBlockRange(testutils.Context(t), 2, 2) require.NoError(t, err) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000001`), lgs[0].Data) @@ -1054,7 +1049,7 @@ func TestLogPoller_PollAndSaveLogsDeepReorg(t *testing.T) { assert.Equal(t, int64(10), newStart) // Expect L1_2 to be properly updated - lgs, err = th.ORM.SelectLogsByBlockRange(2, 2) + lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 2, 2) require.NoError(t, err) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000002`), lgs[0].Data) th.assertHaveCanonical(t, 1, 1) @@ -1080,14 +1075,14 @@ func TestLogPoller_LoadFilters(t *testing.T) { assert.False(t, filter2.Contains(&filter1)) assert.True(t, filter1.Contains(&filter3)) - err := th.LogPoller.RegisterFilter(filter1) + err := th.LogPoller.RegisterFilter(testutils.Context(t), filter1) require.NoError(t, err) - err = th.LogPoller.RegisterFilter(filter2) + err = th.LogPoller.RegisterFilter(testutils.Context(t), filter2) require.NoError(t, err) - err = th.LogPoller.RegisterFilter(filter3) + err = th.LogPoller.RegisterFilter(testutils.Context(t), filter3) require.NoError(t, err) - filters, err := th.ORM.LoadFilters() + filters, err := th.ORM.LoadFilters(testutils.Context(t)) require.NoError(t, err) require.NotNil(t, filters) require.Len(t, filters, 3) @@ -1119,7 +1114,7 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { t.Parallel() th := SetupTH(t, false, 2, 3, 2, 1000) - err := th.LogPoller.RegisterFilter(logpoller.Filter{"GetBlocks Test", []common.Hash{ + err := th.LogPoller.RegisterFilter(testutils.Context(t), logpoller.Filter{"GetBlocks Test", []common.Hash{ EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, []common.Address{th.EmitterAddress1, th.EmitterAddress2}, 0}, ) require.NoError(t, err) @@ -1149,7 +1144,7 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { th.Client.Commit() // Assert block 2 is not yet in DB - _, err = th.ORM.SelectBlockByNumber(2) + _, err = th.ORM.SelectBlockByNumber(testutils.Context(t), 2) require.Error(t, err) // getBlocksRange is able to retrieve block 2 by calling RPC @@ -1164,7 +1159,7 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { th.Client.Commit() // Assert block 3 is not yet in DB - _, err = th.ORM.SelectBlockByNumber(3) + _, err = th.ORM.SelectBlockByNumber(testutils.Context(t), 3) require.Error(t, err) // getBlocksRange is able to retrieve blocks 1 and 3, without retrieving block 2 @@ -1177,10 +1172,10 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { // after calling PollAndSaveLogs, block 2 & 3 are persisted in DB th.LogPoller.PollAndSaveLogs(testutils.Context(t), 1) - block, err := th.ORM.SelectBlockByNumber(2) + block, err := th.ORM.SelectBlockByNumber(testutils.Context(t), 2) require.NoError(t, err) assert.Equal(t, 2, int(block.BlockNumber)) - block, err = th.ORM.SelectBlockByNumber(3) + block, err = th.ORM.SelectBlockByNumber(testutils.Context(t), 3) require.NoError(t, err) assert.Equal(t, 3, int(block.BlockNumber)) @@ -1216,13 +1211,11 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { require.Error(t, err) assert.Contains(t, err.Error(), "context canceled") - // test still works when qopts is cancelled - // but context object is not + // test canceled ctx ctx, cancel = context.WithCancel(testutils.Context(t)) - qopts := pg.WithParentCtx(ctx) cancel() - _, err = th.LogPoller.GetBlocksRange(testutils.Context(t), blockNums, qopts) - require.NoError(t, err) + _, err = th.LogPoller.GetBlocksRange(ctx, blockNums) + require.Equal(t, err, context.Canceled) } func TestGetReplayFromBlock(t *testing.T) { @@ -1251,7 +1244,7 @@ func TestGetReplayFromBlock(t *testing.T) { requested = int64(15) fromBlock, err = th.LogPoller.GetReplayFromBlock(testutils.Context(t), requested) require.NoError(t, err) - latest, err := th.LogPoller.LatestBlock(pg.WithParentCtx(testutils.Context(t))) + latest, err := th.LogPoller.LatestBlock(testutils.Context(t)) require.NoError(t, err) assert.Equal(t, latest.BlockNumber, fromBlock) @@ -1269,7 +1262,7 @@ func TestLogPoller_DBErrorHandling(t *testing.T) { chainID1 := testutils.NewRandomEVMChainID() chainID2 := testutils.NewRandomEVMChainID() db := pgtest.NewSqlxDB(t) - o := logpoller.NewORM(chainID1, db, lggr, pgtest.NewQConfig(true)) + o := logpoller.NewORM(chainID1, db, lggr) owner := testutils.MustNewSimTransactor(t) ethDB := rawdb.NewMemoryDatabase() @@ -1303,9 +1296,10 @@ func TestLogPoller_DBErrorHandling(t *testing.T) { time.Sleep(100 * time.Millisecond) require.NoError(t, lp.Start(ctx)) require.Eventually(t, func() bool { - return observedLogs.Len() >= 5 + return observedLogs.Len() >= 3 }, 2*time.Second, 20*time.Millisecond) - lp.Close() + err = lp.Close() + require.NoError(t, err) logMsgs := make(map[string]int) for _, obs := range observedLogs.All() { @@ -1317,7 +1311,6 @@ func TestLogPoller_DBErrorHandling(t *testing.T) { } } - assert.Contains(t, logMsgs, "SQL ERROR") assert.Contains(t, logMsgs, "Failed loading filters in main logpoller loop, retrying later") assert.Contains(t, logMsgs, "Error executing replay, could not get fromBlock") assert.Contains(t, logMsgs, "Backup log poller ran before filters loaded, skipping") @@ -1335,7 +1328,7 @@ func TestTooManyLogResults(t *testing.T) { lggr, obs := logger.TestObserved(t, zapcore.DebugLevel) chainID := testutils.NewRandomEVMChainID() db := pgtest.NewSqlxDB(t) - o := logpoller.NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + o := logpoller.NewORM(chainID, db, lggr) lp := logpoller.NewLogPoller(o, ec, lggr, 1*time.Hour, false, 2, 20, 10, 1000) expected := []int64{10, 5, 2, 1} @@ -1365,10 +1358,10 @@ func TestTooManyLogResults(t *testing.T) { }) addr := testutils.NewAddress() - err := lp.RegisterFilter(logpoller.Filter{"Integration test", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{addr}, 0}) + err := lp.RegisterFilter(testutils.Context(t), logpoller.Filter{"Integration test", []common.Hash{EmitterABI.Events["Log1"].ID}, []common.Address{addr}, 0}) require.NoError(t, err) lp.PollAndSaveLogs(ctx, 5) - block, err2 := o.SelectLatestBlock() + block, err2 := o.SelectLatestBlock(testutils.Context(t)) require.NoError(t, err2) assert.Equal(t, int64(298), block.BlockNumber) @@ -1399,7 +1392,7 @@ func TestTooManyLogResults(t *testing.T) { }) lp.PollAndSaveLogs(ctx, 298) - block, err2 = o.SelectLatestBlock() + block, err2 = o.SelectLatestBlock(testutils.Context(t)) require.NoError(t, err2) assert.Equal(t, int64(298), block.BlockNumber) warns := obs.FilterMessageSnippet("halving block range").FilterLevelExact(zapcore.WarnLevel).All() @@ -1422,7 +1415,7 @@ func Test_PollAndQueryFinalizedBlocks(t *testing.T) { th := SetupTH(t, true, 2, 3, 2, 1000) eventSig := EmitterABI.Events["Log1"].ID - err := th.LogPoller.RegisterFilter(logpoller.Filter{ + err := th.LogPoller.RegisterFilter(testutils.Context(t), logpoller.Filter{ Name: "GetBlocks Test", EventSigs: []common.Hash{eventSig}, Addresses: []common.Address{th.EmitterAddress1}}, @@ -1451,6 +1444,7 @@ func Test_PollAndQueryFinalizedBlocks(t *testing.T) { require.Equal(t, int(currentBlock), firstBatchLen+secondBatchLen+2) finalizedLogs, err := th.LogPoller.LogsDataWordGreaterThan( + testutils.Context(t), eventSig, th.EmitterAddress1, 0, @@ -1462,6 +1456,7 @@ func Test_PollAndQueryFinalizedBlocks(t *testing.T) { numberOfConfirmations := 1 logsByConfs, err := th.LogPoller.LogsDataWordGreaterThan( + testutils.Context(t), eventSig, th.EmitterAddress1, 0, @@ -1505,7 +1500,7 @@ func Test_PollAndSavePersistsFinalityInBlocks(t *testing.T) { t.Run(tt.name, func(t *testing.T) { th := SetupTH(t, tt.useFinalityTag, tt.finalityDepth, 3, 2, 1000) // Should return error before the first poll and save - _, err := th.LogPoller.LatestBlock() + _, err := th.LogPoller.LatestBlock(testutils.Context(t)) require.Error(t, err) // Mark first block as finalized @@ -1519,7 +1514,7 @@ func Test_PollAndSavePersistsFinalityInBlocks(t *testing.T) { th.PollAndSaveLogs(ctx, 1) - latestBlock, err := th.LogPoller.LatestBlock() + latestBlock, err := th.LogPoller.LatestBlock(testutils.Context(t)) require.NoError(t, err) require.Equal(t, int64(numberOfBlocks), latestBlock.BlockNumber) require.Equal(t, tt.expectedFinalizedBlock, latestBlock.FinalizedBlockNumber) @@ -1567,7 +1562,7 @@ func Test_CreatedAfterQueriesWithBackfill(t *testing.T) { // First PollAndSave, no filters are registered currentBlock := th.PollAndSaveLogs(ctx, 1) - err = th.LogPoller.RegisterFilter(logpoller.Filter{ + err = th.LogPoller.RegisterFilter(ctx, logpoller.Filter{ Name: "Test Emitter", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID}, Addresses: []common.Address{th.EmitterAddress1}, @@ -1586,22 +1581,22 @@ func Test_CreatedAfterQueriesWithBackfill(t *testing.T) { // Make sure that all logs are backfilled logs, err := th.LogPoller.Logs( + ctx, 0, currentBlock, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, - pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) require.Len(t, logs, emittedLogs) // We should get all the logs by the block_timestamp logs, err = th.LogPoller.LogsCreatedAfter( + ctx, EmitterABI.Events["Log1"].ID, th.EmitterAddress1, genesisBlockTime, 0, - pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) require.Len(t, logs, emittedLogs) @@ -1644,7 +1639,7 @@ func Test_PruneOldBlocks(t *testing.T) { th := SetupTH(t, true, 0, 3, 2, tt.keepFinalizedBlocksDepth) for i := 1; i <= tt.blockToCreate; i++ { - err := th.ORM.InsertBlock(utils.RandomBytes32(), int64(i+10), time.Now(), int64(i)) + err := th.ORM.InsertBlock(testutils.Context(t), utils.RandomBytes32(), int64(i+10), time.Now(), int64(i)) require.NoError(t, err) } @@ -1654,7 +1649,7 @@ func Test_PruneOldBlocks(t *testing.T) { } require.NoError(t, th.LogPoller.PruneOldBlocks(ctx)) - blocks, err := th.ORM.GetBlocksRange(0, math.MaxInt64, pg.WithParentCtx(ctx)) + blocks, err := th.ORM.GetBlocksRange(testutils.Context(t), 0, math.MaxInt64) require.NoError(t, err) assert.Len(t, blocks, tt.blocksLeft) }) diff --git a/core/chains/evm/logpoller/mocks/log_poller.go b/core/chains/evm/logpoller/mocks/log_poller.go index 65d808b98d5..2bf24881405 100644 --- a/core/chains/evm/logpoller/mocks/log_poller.go +++ b/core/chains/evm/logpoller/mocks/log_poller.go @@ -11,8 +11,6 @@ import ( mock "github.com/stretchr/testify/mock" - pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" - time "time" ) @@ -39,16 +37,9 @@ func (_m *LogPoller) Close() error { return r0 } -// GetBlocksRange provides a mock function with given fields: ctx, numbers, qopts -func (_m *LogPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, numbers) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// GetBlocksRange provides a mock function with given fields: ctx, numbers +func (_m *LogPoller) GetBlocksRange(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) { + ret := _m.Called(ctx, numbers) if len(ret) == 0 { panic("no return value specified for GetBlocksRange") @@ -56,19 +47,19 @@ func (_m *LogPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts var r0 []logpoller.LogPollerBlock var r1 error - if rf, ok := ret.Get(0).(func(context.Context, []uint64, ...pg.QOpt) ([]logpoller.LogPollerBlock, error)); ok { - return rf(ctx, numbers, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []uint64) ([]logpoller.LogPollerBlock, error)); ok { + return rf(ctx, numbers) } - if rf, ok := ret.Get(0).(func(context.Context, []uint64, ...pg.QOpt) []logpoller.LogPollerBlock); ok { - r0 = rf(ctx, numbers, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []uint64) []logpoller.LogPollerBlock); ok { + r0 = rf(ctx, numbers) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.LogPollerBlock) } } - if rf, ok := ret.Get(1).(func(context.Context, []uint64, ...pg.QOpt) error); ok { - r1 = rf(ctx, numbers, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, []uint64) error); ok { + r1 = rf(ctx, numbers) } else { r1 = ret.Error(1) } @@ -114,16 +105,9 @@ func (_m *LogPoller) HealthReport() map[string]error { return r0 } -// IndexedLogs provides a mock function with given fields: eventSig, address, topicIndex, topicValues, confs, qopts -func (_m *LogPoller) IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, topicIndex, topicValues, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IndexedLogs provides a mock function with given fields: ctx, eventSig, address, topicIndex, topicValues, confs +func (_m *LogPoller) IndexedLogs(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, topicIndex, topicValues, confs) if len(ret) == 0 { panic("no return value specified for IndexedLogs") @@ -131,19 +115,19 @@ func (_m *LogPoller) IndexedLogs(eventSig common.Hash, address common.Address, t var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, []common.Hash, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, topicIndex, topicValues, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, []common.Hash, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, topicIndex, topicValues, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, []common.Hash, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, topicIndex, topicValues, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, []common.Hash, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, topicIndex, topicValues, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, []common.Hash, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, topicIndex, topicValues, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, int, []common.Hash, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, topicIndex, topicValues, confs) } else { r1 = ret.Error(1) } @@ -151,16 +135,9 @@ func (_m *LogPoller) IndexedLogs(eventSig common.Hash, address common.Address, t return r0, r1 } -// IndexedLogsByBlockRange provides a mock function with given fields: start, end, eventSig, address, topicIndex, topicValues, qopts -func (_m *LogPoller) IndexedLogsByBlockRange(start int64, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, start, end, eventSig, address, topicIndex, topicValues) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IndexedLogsByBlockRange provides a mock function with given fields: ctx, start, end, eventSig, address, topicIndex, topicValues +func (_m *LogPoller) IndexedLogsByBlockRange(ctx context.Context, start int64, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash) ([]logpoller.Log, error) { + ret := _m.Called(ctx, start, end, eventSig, address, topicIndex, topicValues) if len(ret) == 0 { panic("no return value specified for IndexedLogsByBlockRange") @@ -168,19 +145,19 @@ func (_m *LogPoller) IndexedLogsByBlockRange(start int64, end int64, eventSig co var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(int64, int64, common.Hash, common.Address, int, []common.Hash, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(start, end, eventSig, address, topicIndex, topicValues, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, common.Hash, common.Address, int, []common.Hash) ([]logpoller.Log, error)); ok { + return rf(ctx, start, end, eventSig, address, topicIndex, topicValues) } - if rf, ok := ret.Get(0).(func(int64, int64, common.Hash, common.Address, int, []common.Hash, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(start, end, eventSig, address, topicIndex, topicValues, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, common.Hash, common.Address, int, []common.Hash) []logpoller.Log); ok { + r0 = rf(ctx, start, end, eventSig, address, topicIndex, topicValues) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(int64, int64, common.Hash, common.Address, int, []common.Hash, ...pg.QOpt) error); ok { - r1 = rf(start, end, eventSig, address, topicIndex, topicValues, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64, int64, common.Hash, common.Address, int, []common.Hash) error); ok { + r1 = rf(ctx, start, end, eventSig, address, topicIndex, topicValues) } else { r1 = ret.Error(1) } @@ -188,16 +165,9 @@ func (_m *LogPoller) IndexedLogsByBlockRange(start int64, end int64, eventSig co return r0, r1 } -// IndexedLogsByTxHash provides a mock function with given fields: eventSig, address, txHash, qopts -func (_m *LogPoller) IndexedLogsByTxHash(eventSig common.Hash, address common.Address, txHash common.Hash, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, txHash) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IndexedLogsByTxHash provides a mock function with given fields: ctx, eventSig, address, txHash +func (_m *LogPoller) IndexedLogsByTxHash(ctx context.Context, eventSig common.Hash, address common.Address, txHash common.Hash) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, txHash) if len(ret) == 0 { panic("no return value specified for IndexedLogsByTxHash") @@ -205,19 +175,19 @@ func (_m *LogPoller) IndexedLogsByTxHash(eventSig common.Hash, address common.Ad var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, common.Hash, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, txHash, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, common.Hash) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, txHash) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, common.Hash, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, txHash, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, common.Hash) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, txHash) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, common.Hash, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, txHash, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, common.Hash) error); ok { + r1 = rf(ctx, eventSig, address, txHash) } else { r1 = ret.Error(1) } @@ -225,16 +195,9 @@ func (_m *LogPoller) IndexedLogsByTxHash(eventSig common.Hash, address common.Ad return r0, r1 } -// IndexedLogsCreatedAfter provides a mock function with given fields: eventSig, address, topicIndex, topicValues, after, confs, qopts -func (_m *LogPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, topicIndex, topicValues, after, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IndexedLogsCreatedAfter provides a mock function with given fields: ctx, eventSig, address, topicIndex, topicValues, after, confs +func (_m *LogPoller) IndexedLogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, topicIndex, topicValues, after, confs) if len(ret) == 0 { panic("no return value specified for IndexedLogsCreatedAfter") @@ -242,19 +205,19 @@ func (_m *LogPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address commo var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, []common.Hash, time.Time, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, topicIndex, topicValues, after, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, []common.Hash, time.Time, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, topicIndex, topicValues, after, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, []common.Hash, time.Time, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, topicIndex, topicValues, after, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, []common.Hash, time.Time, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, topicIndex, topicValues, after, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, []common.Hash, time.Time, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, topicIndex, topicValues, after, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, int, []common.Hash, time.Time, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, topicIndex, topicValues, after, confs) } else { r1 = ret.Error(1) } @@ -262,16 +225,9 @@ func (_m *LogPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address commo return r0, r1 } -// IndexedLogsTopicGreaterThan provides a mock function with given fields: eventSig, address, topicIndex, topicValueMin, confs, qopts -func (_m *LogPoller) IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, topicIndex, topicValueMin, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IndexedLogsTopicGreaterThan provides a mock function with given fields: ctx, eventSig, address, topicIndex, topicValueMin, confs +func (_m *LogPoller) IndexedLogsTopicGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, topicIndex, topicValueMin, confs) if len(ret) == 0 { panic("no return value specified for IndexedLogsTopicGreaterThan") @@ -279,19 +235,19 @@ func (_m *LogPoller) IndexedLogsTopicGreaterThan(eventSig common.Hash, address c var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, topicIndex, topicValueMin, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, topicIndex, topicValueMin, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, topicIndex, topicValueMin, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, topicIndex, topicValueMin, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, topicIndex, topicValueMin, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, int, common.Hash, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, topicIndex, topicValueMin, confs) } else { r1 = ret.Error(1) } @@ -299,16 +255,9 @@ func (_m *LogPoller) IndexedLogsTopicGreaterThan(eventSig common.Hash, address c return r0, r1 } -// IndexedLogsTopicRange provides a mock function with given fields: eventSig, address, topicIndex, topicValueMin, topicValueMax, confs, qopts -func (_m *LogPoller) IndexedLogsTopicRange(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, topicIndex, topicValueMin, topicValueMax, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IndexedLogsTopicRange provides a mock function with given fields: ctx, eventSig, address, topicIndex, topicValueMin, topicValueMax, confs +func (_m *LogPoller) IndexedLogsTopicRange(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, topicIndex, topicValueMin, topicValueMax, confs) if len(ret) == 0 { panic("no return value specified for IndexedLogsTopicRange") @@ -316,19 +265,19 @@ func (_m *LogPoller) IndexedLogsTopicRange(eventSig common.Hash, address common. var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, topicIndex, topicValueMin, topicValueMax, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, topicIndex, topicValueMin, topicValueMax, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, topicIndex, topicValueMin, topicValueMax, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, topicIndex, topicValueMin, topicValueMax, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, topicIndex, topicValueMin, topicValueMax, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, topicIndex, topicValueMin, topicValueMax, confs) } else { r1 = ret.Error(1) } @@ -336,16 +285,9 @@ func (_m *LogPoller) IndexedLogsTopicRange(eventSig common.Hash, address common. return r0, r1 } -// IndexedLogsWithSigsExcluding provides a mock function with given fields: address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs, qopts -func (_m *LogPoller) IndexedLogsWithSigsExcluding(address common.Address, eventSigA common.Hash, eventSigB common.Hash, topicIndex int, fromBlock int64, toBlock int64, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IndexedLogsWithSigsExcluding provides a mock function with given fields: ctx, address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs +func (_m *LogPoller) IndexedLogsWithSigsExcluding(ctx context.Context, address common.Address, eventSigA common.Hash, eventSigB common.Hash, topicIndex int, fromBlock int64, toBlock int64, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs) if len(ret) == 0 { panic("no return value specified for IndexedLogsWithSigsExcluding") @@ -353,19 +295,19 @@ func (_m *LogPoller) IndexedLogsWithSigsExcluding(address common.Address, eventS var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Address, common.Hash, common.Hash, int, int64, int64, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Hash, common.Hash, int, int64, int64, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs) } - if rf, ok := ret.Get(0).(func(common.Address, common.Hash, common.Hash, int, int64, int64, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Hash, common.Hash, int, int64, int64, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Address, common.Hash, common.Hash, int, int64, int64, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Address, common.Hash, common.Hash, int, int64, int64, logpoller.Confirmations) error); ok { + r1 = rf(ctx, address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs) } else { r1 = ret.Error(1) } @@ -373,15 +315,9 @@ func (_m *LogPoller) IndexedLogsWithSigsExcluding(address common.Address, eventS return r0, r1 } -// LatestBlock provides a mock function with given fields: qopts -func (_m *LogPoller) LatestBlock(qopts ...pg.QOpt) (logpoller.LogPollerBlock, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LatestBlock provides a mock function with given fields: ctx +func (_m *LogPoller) LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for LatestBlock") @@ -389,17 +325,17 @@ func (_m *LogPoller) LatestBlock(qopts ...pg.QOpt) (logpoller.LogPollerBlock, er var r0 logpoller.LogPollerBlock var r1 error - if rf, ok := ret.Get(0).(func(...pg.QOpt) (logpoller.LogPollerBlock, error)); ok { - return rf(qopts...) + if rf, ok := ret.Get(0).(func(context.Context) (logpoller.LogPollerBlock, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func(...pg.QOpt) logpoller.LogPollerBlock); ok { - r0 = rf(qopts...) + if rf, ok := ret.Get(0).(func(context.Context) logpoller.LogPollerBlock); ok { + r0 = rf(ctx) } else { r0 = ret.Get(0).(logpoller.LogPollerBlock) } - if rf, ok := ret.Get(1).(func(...pg.QOpt) error); ok { - r1 = rf(qopts...) + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) } else { r1 = ret.Error(1) } @@ -407,16 +343,9 @@ func (_m *LogPoller) LatestBlock(qopts ...pg.QOpt) (logpoller.LogPollerBlock, er return r0, r1 } -// LatestBlockByEventSigsAddrsWithConfs provides a mock function with given fields: fromBlock, eventSigs, addresses, confs, qopts -func (_m *LogPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs logpoller.Confirmations, qopts ...pg.QOpt) (int64, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, fromBlock, eventSigs, addresses, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LatestBlockByEventSigsAddrsWithConfs provides a mock function with given fields: ctx, fromBlock, eventSigs, addresses, confs +func (_m *LogPoller) LatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs logpoller.Confirmations) (int64, error) { + ret := _m.Called(ctx, fromBlock, eventSigs, addresses, confs) if len(ret) == 0 { panic("no return value specified for LatestBlockByEventSigsAddrsWithConfs") @@ -424,17 +353,17 @@ func (_m *LogPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, event var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(int64, []common.Hash, []common.Address, logpoller.Confirmations, ...pg.QOpt) (int64, error)); ok { - return rf(fromBlock, eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, []common.Hash, []common.Address, logpoller.Confirmations) (int64, error)); ok { + return rf(ctx, fromBlock, eventSigs, addresses, confs) } - if rf, ok := ret.Get(0).(func(int64, []common.Hash, []common.Address, logpoller.Confirmations, ...pg.QOpt) int64); ok { - r0 = rf(fromBlock, eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, []common.Hash, []common.Address, logpoller.Confirmations) int64); ok { + r0 = rf(ctx, fromBlock, eventSigs, addresses, confs) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(int64, []common.Hash, []common.Address, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(fromBlock, eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64, []common.Hash, []common.Address, logpoller.Confirmations) error); ok { + r1 = rf(ctx, fromBlock, eventSigs, addresses, confs) } else { r1 = ret.Error(1) } @@ -442,16 +371,9 @@ func (_m *LogPoller) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, event return r0, r1 } -// LatestLogByEventSigWithConfs provides a mock function with given fields: eventSig, address, confs, qopts -func (_m *LogPoller) LatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs logpoller.Confirmations, qopts ...pg.QOpt) (*logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LatestLogByEventSigWithConfs provides a mock function with given fields: ctx, eventSig, address, confs +func (_m *LogPoller) LatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs logpoller.Confirmations) (*logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, confs) if len(ret) == 0 { panic("no return value specified for LatestLogByEventSigWithConfs") @@ -459,19 +381,19 @@ func (_m *LogPoller) LatestLogByEventSigWithConfs(eventSig common.Hash, address var r0 *logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, logpoller.Confirmations, ...pg.QOpt) (*logpoller.Log, error)); ok { - return rf(eventSig, address, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, logpoller.Confirmations) (*logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, logpoller.Confirmations, ...pg.QOpt) *logpoller.Log); ok { - r0 = rf(eventSig, address, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, logpoller.Confirmations) *logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, confs) } else { r1 = ret.Error(1) } @@ -479,16 +401,9 @@ func (_m *LogPoller) LatestLogByEventSigWithConfs(eventSig common.Hash, address return r0, r1 } -// LatestLogEventSigsAddrsWithConfs provides a mock function with given fields: fromBlock, eventSigs, addresses, confs, qopts -func (_m *LogPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, fromBlock, eventSigs, addresses, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LatestLogEventSigsAddrsWithConfs provides a mock function with given fields: ctx, fromBlock, eventSigs, addresses, confs +func (_m *LogPoller) LatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, fromBlock, eventSigs, addresses, confs) if len(ret) == 0 { panic("no return value specified for LatestLogEventSigsAddrsWithConfs") @@ -496,19 +411,19 @@ func (_m *LogPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(int64, []common.Hash, []common.Address, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(fromBlock, eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, []common.Hash, []common.Address, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, fromBlock, eventSigs, addresses, confs) } - if rf, ok := ret.Get(0).(func(int64, []common.Hash, []common.Address, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(fromBlock, eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, []common.Hash, []common.Address, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, fromBlock, eventSigs, addresses, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(int64, []common.Hash, []common.Address, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(fromBlock, eventSigs, addresses, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64, []common.Hash, []common.Address, logpoller.Confirmations) error); ok { + r1 = rf(ctx, fromBlock, eventSigs, addresses, confs) } else { r1 = ret.Error(1) } @@ -516,16 +431,9 @@ func (_m *LogPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs return r0, r1 } -// Logs provides a mock function with given fields: start, end, eventSig, address, qopts -func (_m *LogPoller) Logs(start int64, end int64, eventSig common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, start, end, eventSig, address) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// Logs provides a mock function with given fields: ctx, start, end, eventSig, address +func (_m *LogPoller) Logs(ctx context.Context, start int64, end int64, eventSig common.Hash, address common.Address) ([]logpoller.Log, error) { + ret := _m.Called(ctx, start, end, eventSig, address) if len(ret) == 0 { panic("no return value specified for Logs") @@ -533,19 +441,19 @@ func (_m *LogPoller) Logs(start int64, end int64, eventSig common.Hash, address var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(int64, int64, common.Hash, common.Address, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(start, end, eventSig, address, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, common.Hash, common.Address) ([]logpoller.Log, error)); ok { + return rf(ctx, start, end, eventSig, address) } - if rf, ok := ret.Get(0).(func(int64, int64, common.Hash, common.Address, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(start, end, eventSig, address, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, common.Hash, common.Address) []logpoller.Log); ok { + r0 = rf(ctx, start, end, eventSig, address) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(int64, int64, common.Hash, common.Address, ...pg.QOpt) error); ok { - r1 = rf(start, end, eventSig, address, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64, int64, common.Hash, common.Address) error); ok { + r1 = rf(ctx, start, end, eventSig, address) } else { r1 = ret.Error(1) } @@ -553,16 +461,9 @@ func (_m *LogPoller) Logs(start int64, end int64, eventSig common.Hash, address return r0, r1 } -// LogsCreatedAfter provides a mock function with given fields: eventSig, address, _a2, confs, qopts -func (_m *LogPoller) LogsCreatedAfter(eventSig common.Hash, address common.Address, _a2 time.Time, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, _a2, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LogsCreatedAfter provides a mock function with given fields: ctx, eventSig, address, _a3, confs +func (_m *LogPoller) LogsCreatedAfter(ctx context.Context, eventSig common.Hash, address common.Address, _a3 time.Time, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, _a3, confs) if len(ret) == 0 { panic("no return value specified for LogsCreatedAfter") @@ -570,19 +471,19 @@ func (_m *LogPoller) LogsCreatedAfter(eventSig common.Hash, address common.Addre var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, time.Time, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, _a2, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, time.Time, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, _a3, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, time.Time, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, _a2, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, time.Time, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, _a3, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, time.Time, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, _a2, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, time.Time, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, _a3, confs) } else { r1 = ret.Error(1) } @@ -590,16 +491,9 @@ func (_m *LogPoller) LogsCreatedAfter(eventSig common.Hash, address common.Addre return r0, r1 } -// LogsDataWordBetween provides a mock function with given fields: eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs, qopts -func (_m *LogPoller) LogsDataWordBetween(eventSig common.Hash, address common.Address, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LogsDataWordBetween provides a mock function with given fields: ctx, eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs +func (_m *LogPoller) LogsDataWordBetween(ctx context.Context, eventSig common.Hash, address common.Address, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs) if len(ret) == 0 { panic("no return value specified for LogsDataWordBetween") @@ -607,19 +501,19 @@ func (_m *LogPoller) LogsDataWordBetween(eventSig common.Hash, address common.Ad var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, int, common.Hash, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, int, common.Hash, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, int, int, common.Hash, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, wordIndexMin, wordIndexMax, wordValue, confs) } else { r1 = ret.Error(1) } @@ -627,16 +521,9 @@ func (_m *LogPoller) LogsDataWordBetween(eventSig common.Hash, address common.Ad return r0, r1 } -// LogsDataWordGreaterThan provides a mock function with given fields: eventSig, address, wordIndex, wordValueMin, confs, qopts -func (_m *LogPoller) LogsDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, wordIndex, wordValueMin, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LogsDataWordGreaterThan provides a mock function with given fields: ctx, eventSig, address, wordIndex, wordValueMin, confs +func (_m *LogPoller) LogsDataWordGreaterThan(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, wordIndex, wordValueMin, confs) if len(ret) == 0 { panic("no return value specified for LogsDataWordGreaterThan") @@ -644,19 +531,19 @@ func (_m *LogPoller) LogsDataWordGreaterThan(eventSig common.Hash, address commo var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, wordIndex, wordValueMin, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, wordIndex, wordValueMin, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, wordIndex, wordValueMin, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, wordIndex, wordValueMin, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, common.Hash, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, wordIndex, wordValueMin, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, int, common.Hash, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, wordIndex, wordValueMin, confs) } else { r1 = ret.Error(1) } @@ -664,16 +551,9 @@ func (_m *LogPoller) LogsDataWordGreaterThan(eventSig common.Hash, address commo return r0, r1 } -// LogsDataWordRange provides a mock function with given fields: eventSig, address, wordIndex, wordValueMin, wordValueMax, confs, qopts -func (_m *LogPoller) LogsDataWordRange(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, wordValueMax common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, eventSig, address, wordIndex, wordValueMin, wordValueMax, confs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LogsDataWordRange provides a mock function with given fields: ctx, eventSig, address, wordIndex, wordValueMin, wordValueMax, confs +func (_m *LogPoller) LogsDataWordRange(ctx context.Context, eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, wordValueMax common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { + ret := _m.Called(ctx, eventSig, address, wordIndex, wordValueMin, wordValueMax, confs) if len(ret) == 0 { panic("no return value specified for LogsDataWordRange") @@ -681,19 +561,19 @@ func (_m *LogPoller) LogsDataWordRange(eventSig common.Hash, address common.Addr var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(eventSig, address, wordIndex, wordValueMin, wordValueMax, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations) ([]logpoller.Log, error)); ok { + return rf(ctx, eventSig, address, wordIndex, wordValueMin, wordValueMax, confs) } - if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(eventSig, address, wordIndex, wordValueMin, wordValueMax, confs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations) []logpoller.Log); ok { + r0 = rf(ctx, eventSig, address, wordIndex, wordValueMin, wordValueMax, confs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations, ...pg.QOpt) error); ok { - r1 = rf(eventSig, address, wordIndex, wordValueMin, wordValueMax, confs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, common.Address, int, common.Hash, common.Hash, logpoller.Confirmations) error); ok { + r1 = rf(ctx, eventSig, address, wordIndex, wordValueMin, wordValueMax, confs) } else { r1 = ret.Error(1) } @@ -701,16 +581,9 @@ func (_m *LogPoller) LogsDataWordRange(eventSig common.Hash, address common.Addr return r0, r1 } -// LogsWithSigs provides a mock function with given fields: start, end, eventSigs, address, qopts -func (_m *LogPoller) LogsWithSigs(start int64, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, start, end, eventSigs, address) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// LogsWithSigs provides a mock function with given fields: ctx, start, end, eventSigs, address +func (_m *LogPoller) LogsWithSigs(ctx context.Context, start int64, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { + ret := _m.Called(ctx, start, end, eventSigs, address) if len(ret) == 0 { panic("no return value specified for LogsWithSigs") @@ -718,19 +591,19 @@ func (_m *LogPoller) LogsWithSigs(start int64, end int64, eventSigs []common.Has var r0 []logpoller.Log var r1 error - if rf, ok := ret.Get(0).(func(int64, int64, []common.Hash, common.Address, ...pg.QOpt) ([]logpoller.Log, error)); ok { - return rf(start, end, eventSigs, address, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, []common.Hash, common.Address) ([]logpoller.Log, error)); ok { + return rf(ctx, start, end, eventSigs, address) } - if rf, ok := ret.Get(0).(func(int64, int64, []common.Hash, common.Address, ...pg.QOpt) []logpoller.Log); ok { - r0 = rf(start, end, eventSigs, address, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int64, []common.Hash, common.Address) []logpoller.Log); ok { + r0 = rf(ctx, start, end, eventSigs, address) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]logpoller.Log) } } - if rf, ok := ret.Get(1).(func(int64, int64, []common.Hash, common.Address, ...pg.QOpt) error); ok { - r1 = rf(start, end, eventSigs, address, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64, int64, []common.Hash, common.Address) error); ok { + r1 = rf(ctx, start, end, eventSigs, address) } else { r1 = ret.Error(1) } @@ -774,24 +647,17 @@ func (_m *LogPoller) Ready() error { return r0 } -// RegisterFilter provides a mock function with given fields: filter, qopts -func (_m *LogPoller) RegisterFilter(filter logpoller.Filter, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, filter) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// RegisterFilter provides a mock function with given fields: ctx, filter +func (_m *LogPoller) RegisterFilter(ctx context.Context, filter logpoller.Filter) error { + ret := _m.Called(ctx, filter) if len(ret) == 0 { panic("no return value specified for RegisterFilter") } var r0 error - if rf, ok := ret.Get(0).(func(logpoller.Filter, ...pg.QOpt) error); ok { - r0 = rf(filter, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, logpoller.Filter) error); ok { + r0 = rf(ctx, filter) } else { r0 = ret.Error(0) } @@ -840,24 +706,17 @@ func (_m *LogPoller) Start(_a0 context.Context) error { return r0 } -// UnregisterFilter provides a mock function with given fields: name, qopts -func (_m *LogPoller) UnregisterFilter(name string, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, name) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// UnregisterFilter provides a mock function with given fields: ctx, name +func (_m *LogPoller) UnregisterFilter(ctx context.Context, name string) error { + ret := _m.Called(ctx, name) if len(ret) == 0 { panic("no return value specified for UnregisterFilter") } var r0 error - if rf, ok := ret.Get(0).(func(string, ...pg.QOpt) error); ok { - r0 = rf(name, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, name) } else { r0 = ret.Error(0) } diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index a7a0d3c03d5..956d1b7ee00 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -1,6 +1,7 @@ package logpoller import ( + "context" "math/big" "time" @@ -10,8 +11,6 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" "github.com/smartcontractkit/chainlink-common/pkg/logger" - - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type queryType string @@ -77,9 +76,9 @@ type ObservedORM struct { // NewObservedORM creates an observed version of log poller's ORM created by NewORM // Please see ObservedLogPoller for more details on how latencies are measured -func NewObservedORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *ObservedORM { +func NewObservedORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger) *ObservedORM { return &ObservedORM{ - ORM: NewORM(chainID, db, lggr, cfg), + ORM: NewORM(chainID, db, lggr), queryDuration: lpQueryDuration, datasetSize: lpQueryDataSets, logsInserted: lpLogsInserted, @@ -88,169 +87,169 @@ func NewObservedORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QC } } -func (o *ObservedORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error { +func (o *ObservedORM) InsertLogs(ctx context.Context, logs []Log) error { err := withObservedExec(o, "InsertLogs", create, func() error { - return o.ORM.InsertLogs(logs, qopts...) + return o.ORM.InsertLogs(ctx, logs) }) trackInsertedLogsAndBlock(o, logs, nil, err) return err } -func (o *ObservedORM) InsertLogsWithBlock(logs []Log, block LogPollerBlock, qopts ...pg.QOpt) error { +func (o *ObservedORM) InsertLogsWithBlock(ctx context.Context, logs []Log, block LogPollerBlock) error { err := withObservedExec(o, "InsertLogsWithBlock", create, func() error { - return o.ORM.InsertLogsWithBlock(logs, block, qopts...) + return o.ORM.InsertLogsWithBlock(ctx, logs, block) }) trackInsertedLogsAndBlock(o, logs, &block, err) return err } -func (o *ObservedORM) InsertFilter(filter Filter, qopts ...pg.QOpt) error { +func (o *ObservedORM) InsertFilter(ctx context.Context, filter Filter) error { return withObservedExec(o, "InsertFilter", create, func() error { - return o.ORM.InsertFilter(filter, qopts...) + return o.ORM.InsertFilter(ctx, filter) }) } -func (o *ObservedORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) { +func (o *ObservedORM) LoadFilters(ctx context.Context) (map[string]Filter, error) { return withObservedQuery(o, "LoadFilters", func() (map[string]Filter, error) { - return o.ORM.LoadFilters(qopts...) + return o.ORM.LoadFilters(ctx) }) } -func (o *ObservedORM) DeleteFilter(name string, qopts ...pg.QOpt) error { +func (o *ObservedORM) DeleteFilter(ctx context.Context, name string) error { return withObservedExec(o, "DeleteFilter", del, func() error { - return o.ORM.DeleteFilter(name, qopts...) + return o.ORM.DeleteFilter(ctx, name) }) } -func (o *ObservedORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { +func (o *ObservedORM) DeleteBlocksBefore(ctx context.Context, end int64) error { return withObservedExec(o, "DeleteBlocksBefore", del, func() error { - return o.ORM.DeleteBlocksBefore(end, qopts...) + return o.ORM.DeleteBlocksBefore(ctx, end) }) } -func (o *ObservedORM) DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) error { +func (o *ObservedORM) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error { return withObservedExec(o, "DeleteLogsAndBlocksAfter", del, func() error { - return o.ORM.DeleteLogsAndBlocksAfter(start, qopts...) + return o.ORM.DeleteLogsAndBlocksAfter(ctx, start) }) } -func (o *ObservedORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { +func (o *ObservedORM) DeleteExpiredLogs(ctx context.Context) error { return withObservedExec(o, "DeleteExpiredLogs", del, func() error { - return o.ORM.DeleteExpiredLogs(qopts...) + return o.ORM.DeleteExpiredLogs(ctx) }) } -func (o *ObservedORM) SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, error) { +func (o *ObservedORM) SelectBlockByNumber(ctx context.Context, n int64) (*LogPollerBlock, error) { return withObservedQuery(o, "SelectBlockByNumber", func() (*LogPollerBlock, error) { - return o.ORM.SelectBlockByNumber(n, qopts...) + return o.ORM.SelectBlockByNumber(ctx, n) }) } -func (o *ObservedORM) SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) { +func (o *ObservedORM) SelectLatestBlock(ctx context.Context) (*LogPollerBlock, error) { return withObservedQuery(o, "SelectLatestBlock", func() (*LogPollerBlock, error) { - return o.ORM.SelectLatestBlock(qopts...) + return o.ORM.SelectLatestBlock(ctx) }) } -func (o *ObservedORM) SelectLatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs Confirmations, qopts ...pg.QOpt) (*Log, error) { +func (o *ObservedORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { return withObservedQuery(o, "SelectLatestLogByEventSigWithConfs", func() (*Log, error) { - return o.ORM.SelectLatestLogByEventSigWithConfs(eventSig, address, confs, qopts...) + return o.ORM.SelectLatestLogByEventSigWithConfs(ctx, eventSig, address, confs) }) } -func (o *ObservedORM) SelectLogsWithSigs(start, end int64, address common.Address, eventSigs []common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectLogsWithSigs(ctx context.Context, start, end int64, address common.Address, eventSigs []common.Hash) ([]Log, error) { return withObservedQueryAndResults(o, "SelectLogsWithSigs", func() ([]Log, error) { - return o.ORM.SelectLogsWithSigs(start, end, address, eventSigs, qopts...) + return o.ORM.SelectLogsWithSigs(ctx, start, end, address, eventSigs) }) } -func (o *ObservedORM) SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, after time.Time, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectLogsCreatedAfter", func() ([]Log, error) { - return o.ORM.SelectLogsCreatedAfter(address, eventSig, after, confs, qopts...) + return o.ORM.SelectLogsCreatedAfter(ctx, address, eventSig, after, confs) }) } -func (o *ObservedORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectIndexedLogs(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectIndexedLogs", func() ([]Log, error) { - return o.ORM.SelectIndexedLogs(address, eventSig, topicIndex, topicValues, confs, qopts...) + return o.ORM.SelectIndexedLogs(ctx, address, eventSig, topicIndex, topicValues, confs) }) } -func (o *ObservedORM) SelectIndexedLogsByBlockRange(start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectIndexedLogsByBlockRange(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash) ([]Log, error) { return withObservedQueryAndResults(o, "SelectIndexedLogsByBlockRange", func() ([]Log, error) { - return o.ORM.SelectIndexedLogsByBlockRange(start, end, address, eventSig, topicIndex, topicValues, qopts...) + return o.ORM.SelectIndexedLogsByBlockRange(ctx, start, end, address, eventSig, topicIndex, topicValues) }) } -func (o *ObservedORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectIndexedLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectIndexedLogsCreatedAfter", func() ([]Log, error) { - return o.ORM.SelectIndexedLogsCreatedAfter(address, eventSig, topicIndex, topicValues, after, confs, qopts...) + return o.ORM.SelectIndexedLogsCreatedAfter(ctx, address, eventSig, topicIndex, topicValues, after, confs) }) } -func (o *ObservedORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectIndexedLogsWithSigsExcluding", func() ([]Log, error) { - return o.ORM.SelectIndexedLogsWithSigsExcluding(sigA, sigB, topicIndex, address, startBlock, endBlock, confs, qopts...) + return o.ORM.SelectIndexedLogsWithSigsExcluding(ctx, sigA, sigB, topicIndex, address, startBlock, endBlock, confs) }) } -func (o *ObservedORM) SelectLogs(start, end int64, address common.Address, eventSig common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectLogs(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash) ([]Log, error) { return withObservedQueryAndResults(o, "SelectLogs", func() ([]Log, error) { - return o.ORM.SelectLogs(start, end, address, eventSig, qopts...) + return o.ORM.SelectLogs(ctx, start, end, address, eventSig) }) } -func (o *ObservedORM) SelectIndexedLogsByTxHash(address common.Address, eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Address, eventSig common.Hash, txHash common.Hash) ([]Log, error) { return withObservedQueryAndResults(o, "SelectIndexedLogsByTxHash", func() ([]Log, error) { - return o.ORM.SelectIndexedLogsByTxHash(address, eventSig, txHash, qopts...) + return o.ORM.SelectIndexedLogsByTxHash(ctx, address, eventSig, txHash) }) } -func (o *ObservedORM) GetBlocksRange(start int64, end int64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { +func (o *ObservedORM) GetBlocksRange(ctx context.Context, start int64, end int64) ([]LogPollerBlock, error) { return withObservedQueryAndResults(o, "GetBlocksRange", func() ([]LogPollerBlock, error) { - return o.ORM.GetBlocksRange(start, end, qopts...) + return o.ORM.GetBlocksRange(ctx, start, end) }) } -func (o *ObservedORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectLatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectLatestLogEventSigsAddrsWithConfs", func() ([]Log, error) { - return o.ORM.SelectLatestLogEventSigsAddrsWithConfs(fromBlock, addresses, eventSigs, confs, qopts...) + return o.ORM.SelectLatestLogEventSigsAddrsWithConfs(ctx, fromBlock, addresses, eventSigs, confs) }) } -func (o *ObservedORM) SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) (int64, error) { +func (o *ObservedORM) SelectLatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) { return withObservedQuery(o, "SelectLatestBlockByEventSigsAddrsWithConfs", func() (int64, error) { - return o.ORM.SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock, eventSigs, addresses, confs, qopts...) + return o.ORM.SelectLatestBlockByEventSigsAddrsWithConfs(ctx, fromBlock, eventSigs, addresses, confs) }) } -func (o *ObservedORM) SelectLogsDataWordRange(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectLogsDataWordRange(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectLogsDataWordRange", func() ([]Log, error) { - return o.ORM.SelectLogsDataWordRange(address, eventSig, wordIndex, wordValueMin, wordValueMax, confs, qopts...) + return o.ORM.SelectLogsDataWordRange(ctx, address, eventSig, wordIndex, wordValueMin, wordValueMax, confs) }) } -func (o *ObservedORM) SelectLogsDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectLogsDataWordGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectLogsDataWordGreaterThan", func() ([]Log, error) { - return o.ORM.SelectLogsDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, confs, qopts...) + return o.ORM.SelectLogsDataWordGreaterThan(ctx, address, eventSig, wordIndex, wordValueMin, confs) }) } -func (o *ObservedORM) SelectLogsDataWordBetween(address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectLogsDataWordBetween(ctx context.Context, address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectLogsDataWordBetween", func() ([]Log, error) { - return o.ORM.SelectLogsDataWordBetween(address, eventSig, wordIndexMin, wordIndexMax, wordValue, confs, qopts...) + return o.ORM.SelectLogsDataWordBetween(ctx, address, eventSig, wordIndexMin, wordIndexMax, wordValue, confs) }) } -func (o *ObservedORM) SelectIndexedLogsTopicGreaterThan(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectIndexedLogsTopicGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectIndexedLogsTopicGreaterThan", func() ([]Log, error) { - return o.ORM.SelectIndexedLogsTopicGreaterThan(address, eventSig, topicIndex, topicValueMin, confs, qopts...) + return o.ORM.SelectIndexedLogsTopicGreaterThan(ctx, address, eventSig, topicIndex, topicValueMin, confs) }) } -func (o *ObservedORM) SelectIndexedLogsTopicRange(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) SelectIndexedLogsTopicRange(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations) ([]Log, error) { return withObservedQueryAndResults(o, "SelectIndexedLogsTopicRange", func() ([]Log, error) { - return o.ORM.SelectIndexedLogsTopicRange(address, eventSig, topicIndex, topicValueMin, topicValueMax, confs, qopts...) + return o.ORM.SelectIndexedLogsTopicRange(ctx, address, eventSig, topicIndex, topicValueMin, topicValueMax, confs) }) } diff --git a/core/chains/evm/logpoller/observability_test.go b/core/chains/evm/logpoller/observability_test.go index eb81273af2c..78c27b4b8f7 100644 --- a/core/chains/evm/logpoller/observability_test.go +++ b/core/chains/evm/logpoller/observability_test.go @@ -20,7 +20,6 @@ import ( ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) func TestMultipleMetricsArePublished(t *testing.T) { @@ -29,19 +28,19 @@ func TestMultipleMetricsArePublished(t *testing.T) { t.Cleanup(func() { resetMetrics(*orm) }) require.Equal(t, 0, testutil.CollectAndCount(orm.queryDuration)) - _, _ = orm.SelectIndexedLogs(common.Address{}, common.Hash{}, 1, []common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = orm.SelectIndexedLogsByBlockRange(0, 1, common.Address{}, common.Hash{}, 1, []common.Hash{}, pg.WithParentCtx(ctx)) - _, _ = orm.SelectIndexedLogsTopicGreaterThan(common.Address{}, common.Hash{}, 1, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = orm.SelectIndexedLogsTopicRange(common.Address{}, common.Hash{}, 1, common.Hash{}, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = orm.SelectIndexedLogsWithSigsExcluding(common.Hash{}, common.Hash{}, 1, common.Address{}, 0, 1, 1, pg.WithParentCtx(ctx)) - _, _ = orm.SelectLogsDataWordRange(common.Address{}, common.Hash{}, 0, common.Hash{}, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = orm.SelectLogsDataWordGreaterThan(common.Address{}, common.Hash{}, 0, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = orm.SelectLogsCreatedAfter(common.Address{}, common.Hash{}, time.Now(), 0, pg.WithParentCtx(ctx)) - _, _ = orm.SelectLatestLogByEventSigWithConfs(common.Hash{}, common.Address{}, 0, pg.WithParentCtx(ctx)) - _, _ = orm.SelectLatestLogEventSigsAddrsWithConfs(0, []common.Address{{}}, []common.Hash{{}}, 1, pg.WithParentCtx(ctx)) - _, _ = orm.SelectIndexedLogsCreatedAfter(common.Address{}, common.Hash{}, 1, []common.Hash{}, time.Now(), 0, pg.WithParentCtx(ctx)) - _ = orm.InsertLogs([]Log{}, pg.WithParentCtx(ctx)) - _ = orm.InsertLogsWithBlock([]Log{}, NewLogPollerBlock(common.Hash{}, 1, time.Now(), 0), pg.WithParentCtx(ctx)) + _, _ = orm.SelectIndexedLogs(ctx, common.Address{}, common.Hash{}, 1, []common.Hash{}, 1) + _, _ = orm.SelectIndexedLogsByBlockRange(ctx, 0, 1, common.Address{}, common.Hash{}, 1, []common.Hash{}) + _, _ = orm.SelectIndexedLogsTopicGreaterThan(ctx, common.Address{}, common.Hash{}, 1, common.Hash{}, 1) + _, _ = orm.SelectIndexedLogsTopicRange(ctx, common.Address{}, common.Hash{}, 1, common.Hash{}, common.Hash{}, 1) + _, _ = orm.SelectIndexedLogsWithSigsExcluding(ctx, common.Hash{}, common.Hash{}, 1, common.Address{}, 0, 1, 1) + _, _ = orm.SelectLogsDataWordRange(ctx, common.Address{}, common.Hash{}, 0, common.Hash{}, common.Hash{}, 1) + _, _ = orm.SelectLogsDataWordGreaterThan(ctx, common.Address{}, common.Hash{}, 0, common.Hash{}, 1) + _, _ = orm.SelectLogsCreatedAfter(ctx, common.Address{}, common.Hash{}, time.Now(), 0) + _, _ = orm.SelectLatestLogByEventSigWithConfs(ctx, common.Hash{}, common.Address{}, 0) + _, _ = orm.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0, []common.Address{{}}, []common.Hash{{}}, 1) + _, _ = orm.SelectIndexedLogsCreatedAfter(ctx, common.Address{}, common.Hash{}, 1, []common.Hash{}, time.Now(), 0) + _ = orm.InsertLogs(ctx, []Log{}) + _ = orm.InsertLogsWithBlock(ctx, []Log{}, NewLogPollerBlock(common.Hash{}, 1, time.Now(), 0)) require.Equal(t, 13, testutil.CollectAndCount(orm.queryDuration)) require.Equal(t, 10, testutil.CollectAndCount(orm.datasetSize)) @@ -53,7 +52,7 @@ func TestShouldPublishDurationInCaseOfError(t *testing.T) { t.Cleanup(func() { resetMetrics(*orm) }) require.Equal(t, 0, testutil.CollectAndCount(orm.queryDuration)) - _, err := orm.SelectLatestLogByEventSigWithConfs(common.Hash{}, common.Address{}, 0, pg.WithParentCtx(ctx)) + _, err := orm.SelectLatestLogByEventSigWithConfs(ctx, common.Hash{}, common.Address{}, 0) require.Error(t, err) require.Equal(t, 1, testutil.CollectAndCount(orm.queryDuration)) @@ -100,25 +99,26 @@ func TestMetricsAreProperlyPopulatedForWrites(t *testing.T) { } func TestCountersAreProperlyPopulatedForWrites(t *testing.T) { + ctx := testutils.Context(t) orm := createObservedORM(t, 420) logs := generateRandomLogs(420, 20) // First insert 10 logs - require.NoError(t, orm.InsertLogs(logs[:10])) + require.NoError(t, orm.InsertLogs(ctx, logs[:10])) assert.Equal(t, float64(10), testutil.ToFloat64(orm.logsInserted.WithLabelValues("420"))) // Insert 5 more logs with block - require.NoError(t, orm.InsertLogsWithBlock(logs[10:15], NewLogPollerBlock(utils.RandomBytes32(), 10, time.Now(), 5))) + require.NoError(t, orm.InsertLogsWithBlock(ctx, logs[10:15], NewLogPollerBlock(utils.RandomBytes32(), 10, time.Now(), 5))) assert.Equal(t, float64(15), testutil.ToFloat64(orm.logsInserted.WithLabelValues("420"))) assert.Equal(t, float64(1), testutil.ToFloat64(orm.blocksInserted.WithLabelValues("420"))) // Insert 5 more logs with block - require.NoError(t, orm.InsertLogsWithBlock(logs[15:], NewLogPollerBlock(utils.RandomBytes32(), 15, time.Now(), 5))) + require.NoError(t, orm.InsertLogsWithBlock(ctx, logs[15:], NewLogPollerBlock(utils.RandomBytes32(), 15, time.Now(), 5))) assert.Equal(t, float64(20), testutil.ToFloat64(orm.logsInserted.WithLabelValues("420"))) assert.Equal(t, float64(2), testutil.ToFloat64(orm.blocksInserted.WithLabelValues("420"))) // Don't update counters in case of an error - require.Error(t, orm.InsertLogsWithBlock(logs, NewLogPollerBlock(utils.RandomBytes32(), 0, time.Now(), 0))) + require.Error(t, orm.InsertLogsWithBlock(ctx, logs, NewLogPollerBlock(utils.RandomBytes32(), 0, time.Now(), 0))) assert.Equal(t, float64(20), testutil.ToFloat64(orm.logsInserted.WithLabelValues("420"))) assert.Equal(t, float64(2), testutil.ToFloat64(orm.blocksInserted.WithLabelValues("420"))) } @@ -146,9 +146,7 @@ func generateRandomLogs(chainId, count int) []Log { func createObservedORM(t *testing.T, chainId int64) *ObservedORM { lggr, _ := logger.TestObserved(t, zapcore.ErrorLevel) db := pgtest.NewSqlxDB(t) - return NewObservedORM( - big.NewInt(chainId), db, lggr, pgtest.NewQConfig(true), - ) + return NewObservedORM(big.NewInt(chainId), db, lggr) } func resetMetrics(lp ObservedORM) { diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 1db8271ccb6..296abfcdfc6 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -12,218 +12,202 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) // ORM represents the persistent data access layer used by the log poller. At this moment, it's a bit leaky abstraction, because // it exposes some of the database implementation details (e.g. pg.Q). Ideally it should be agnostic and could be applied to any persistence layer. // What is more, LogPoller should not be aware of the underlying database implementation and delegate all the queries to the ORM. type ORM interface { - InsertLogs(logs []Log, qopts ...pg.QOpt) error - InsertLogsWithBlock(logs []Log, block LogPollerBlock, qopts ...pg.QOpt) error - InsertFilter(filter Filter, qopts ...pg.QOpt) error - - LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) - DeleteFilter(name string, qopts ...pg.QOpt) error - - DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error - DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) error - DeleteExpiredLogs(qopts ...pg.QOpt) error - - GetBlocksRange(start int64, end int64, qopts ...pg.QOpt) ([]LogPollerBlock, error) - SelectBlockByNumber(blockNumber int64, qopts ...pg.QOpt) (*LogPollerBlock, error) - SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) - - SelectLogs(start, end int64, address common.Address, eventSig common.Hash, qopts ...pg.QOpt) ([]Log, error) - SelectLogsWithSigs(start, end int64, address common.Address, eventSigs []common.Hash, qopts ...pg.QOpt) ([]Log, error) - SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectLatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs Confirmations, qopts ...pg.QOpt) (*Log, error) - SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) (int64, error) - - SelectIndexedLogs(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectIndexedLogsByBlockRange(start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) - SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectIndexedLogsTopicGreaterThan(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectIndexedLogsTopicRange(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectIndexedLogsByTxHash(address common.Address, eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) - SelectLogsDataWordRange(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectLogsDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) - SelectLogsDataWordBetween(address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) + InsertLogs(ctx context.Context, logs []Log) error + InsertLogsWithBlock(ctx context.Context, logs []Log, block LogPollerBlock) error + InsertFilter(ctx context.Context, filter Filter) error + + LoadFilters(ctx context.Context) (map[string]Filter, error) + DeleteFilter(ctx context.Context, name string) error + + DeleteBlocksBefore(ctx context.Context, end int64) error + DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error + DeleteExpiredLogs(ctx context.Context) error + + GetBlocksRange(ctx context.Context, start int64, end int64) ([]LogPollerBlock, error) + SelectBlockByNumber(ctx context.Context, blockNumber int64) (*LogPollerBlock, error) + SelectLatestBlock(ctx context.Context) (*LogPollerBlock, error) + + SelectLogs(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash) ([]Log, error) + SelectLogsWithSigs(ctx context.Context, start, end int64, address common.Address, eventSigs []common.Hash) ([]Log, error) + SelectLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, after time.Time, confs Confirmations) ([]Log, error) + SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) + SelectLatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations) ([]Log, error) + SelectLatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) + + SelectIndexedLogs(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) + SelectIndexedLogsByBlockRange(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash) ([]Log, error) + SelectIndexedLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) + SelectIndexedLogsTopicGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) + SelectIndexedLogsTopicRange(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations) ([]Log, error) + SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations) ([]Log, error) + SelectIndexedLogsByTxHash(ctx context.Context, address common.Address, eventSig common.Hash, txHash common.Hash) ([]Log, error) + SelectLogsDataWordRange(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) + SelectLogsDataWordGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) + SelectLogsDataWordBetween(ctx context.Context, address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) } type DbORM struct { chainID *big.Int - q pg.Q + db sqlutil.Queryer lggr logger.Logger } +var _ ORM = &DbORM{} + // NewORM creates a DbORM scoped to chainID. -func NewORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *DbORM { - namedLogger := logger.Named(lggr, "Configs") - q := pg.NewQ(db, namedLogger, cfg) +func NewORM(chainID *big.Int, db sqlutil.Queryer, lggr logger.Logger) *DbORM { return &DbORM{ chainID: chainID, - q: q, + db: db, lggr: lggr, } } +func (o *DbORM) Transaction(ctx context.Context, fn func(*DbORM) error) (err error) { + return sqlutil.Transact(ctx, o.new, o.db, nil, fn) +} + +// new returns a NewORM like o, but backed by q. +func (o *DbORM) new(q sqlutil.Queryer) *DbORM { return NewORM(o.chainID, q, o.lggr) } + // InsertBlock is idempotent to support replays. -func (o *DbORM) InsertBlock(blockHash common.Hash, blockNumber int64, blockTimestamp time.Time, finalizedBlock int64, qopts ...pg.QOpt) error { - args, err := newQueryArgs(o.chainID). - withCustomHashArg("block_hash", blockHash). - withCustomArg("block_number", blockNumber). - withCustomArg("block_timestamp", blockTimestamp). - withCustomArg("finalized_block_number", finalizedBlock). - toArgs() - if err != nil { - return err - } - return o.q.WithOpts(qopts...).ExecQNamed(` - INSERT INTO evm.log_poller_blocks - (evm_chain_id, block_hash, block_number, block_timestamp, finalized_block_number, created_at) - VALUES (:evm_chain_id, :block_hash, :block_number, :block_timestamp, :finalized_block_number, NOW()) - ON CONFLICT DO NOTHING`, args) +func (o *DbORM) InsertBlock(ctx context.Context, blockHash common.Hash, blockNumber int64, blockTimestamp time.Time, finalizedBlock int64) error { + query := `INSERT INTO evm.log_poller_blocks (evm_chain_id, block_hash, block_number, block_timestamp, finalized_block_number, created_at) + VALUES ($1, $2, $3, $4, $5, NOW()) + ON CONFLICT DO NOTHING` + _, err := o.db.ExecContext(ctx, query, ubig.New(o.chainID), blockHash.Bytes(), blockNumber, blockTimestamp, finalizedBlock) + return err } // InsertFilter is idempotent. // // Each address/event pair must have a unique job id, so it may be removed when the job is deleted. // If a second job tries to overwrite the same pair, this should fail. -func (o *DbORM) InsertFilter(filter Filter, qopts ...pg.QOpt) (err error) { - args, err := newQueryArgs(o.chainID). - withCustomArg("name", filter.Name). - withCustomArg("retention", filter.Retention). - withAddressArray(filter.Addresses). - withEventSigArray(filter.EventSigs). - toArgs() - if err != nil { - return err - } +func (o *DbORM) InsertFilter(ctx context.Context, filter Filter) (err error) { // '::' has to be escaped in the query string // https://github.com/jmoiron/sqlx/issues/91, https://github.com/jmoiron/sqlx/issues/428 - return o.q.WithOpts(qopts...).ExecQNamed(` + query := ` INSERT INTO evm.log_poller_filters (name, evm_chain_id, retention, created_at, address, event) SELECT * FROM - (SELECT :name, :evm_chain_id ::::NUMERIC, :retention ::::BIGINT, NOW()) x, - (SELECT unnest(:address_array ::::BYTEA[]) addr) a, - (SELECT unnest(:event_sig_array ::::BYTEA[]) ev) e + (SELECT $1, $2 ::NUMERIC, $3 ::BIGINT, NOW()) x, + (SELECT unnest($4 ::BYTEA[]) addr) a, + (SELECT unnest($5 ::BYTEA[]) ev) e ON CONFLICT (name, evm_chain_id, address, event) - DO UPDATE SET retention=:retention ::::BIGINT`, args) + DO UPDATE SET retention=$3 ::BIGINT` + + _, err = o.db.ExecContext(ctx, query, filter.Name, ubig.New(o.chainID), filter.Retention, concatBytes(filter.Addresses), concatBytes(filter.EventSigs)) + return err } // DeleteFilter removes all events,address pairs associated with the Filter -func (o *DbORM) DeleteFilter(name string, qopts ...pg.QOpt) error { - q := o.q.WithOpts(qopts...) - return q.ExecQ(`DELETE FROM evm.log_poller_filters WHERE name = $1 AND evm_chain_id = $2`, name, ubig.New(o.chainID)) +func (o *DbORM) DeleteFilter(ctx context.Context, name string) error { + _, err := o.db.ExecContext(ctx, + `DELETE FROM evm.log_poller_filters WHERE name = $1 AND evm_chain_id = $2`, + name, ubig.New(o.chainID)) + return err + } -// LoadFiltersForChain returns all filters for this chain -func (o *DbORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) { - q := o.q.WithOpts(qopts...) - rows := make([]Filter, 0) - err := q.Select(&rows, `SELECT name, +// LoadFilters returns all filters for this chain +func (o *DbORM) LoadFilters(ctx context.Context) (map[string]Filter, error) { + query := `SELECT name, ARRAY_AGG(DISTINCT address)::BYTEA[] AS addresses, ARRAY_AGG(DISTINCT event)::BYTEA[] AS event_sigs, MAX(retention) AS retention FROM evm.log_poller_filters WHERE evm_chain_id = $1 - GROUP BY name`, ubig.New(o.chainID)) + GROUP BY name` + var rows []Filter + err := o.db.SelectContext(ctx, &rows, query, ubig.New(o.chainID)) filters := make(map[string]Filter) for _, filter := range rows { filters[filter.Name] = filter } - return filters, err } -func (o *DbORM) SelectBlockByHash(hash common.Hash, qopts ...pg.QOpt) (*LogPollerBlock, error) { - q := o.q.WithOpts(qopts...) +func (o *DbORM) SelectBlockByHash(ctx context.Context, hash common.Hash) (*LogPollerBlock, error) { var b LogPollerBlock - if err := q.Get(&b, `SELECT * FROM evm.log_poller_blocks WHERE block_hash = $1 AND evm_chain_id = $2`, hash, ubig.New(o.chainID)); err != nil { + if err := o.db.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE block_hash = $1 AND evm_chain_id = $2`, hash.Bytes(), ubig.New(o.chainID)); err != nil { return nil, err } return &b, nil } -func (o *DbORM) SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, error) { - q := o.q.WithOpts(qopts...) +func (o *DbORM) SelectBlockByNumber(ctx context.Context, n int64) (*LogPollerBlock, error) { var b LogPollerBlock - if err := q.Get(&b, `SELECT * FROM evm.log_poller_blocks WHERE block_number = $1 AND evm_chain_id = $2`, n, ubig.New(o.chainID)); err != nil { + if err := o.db.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE block_number = $1 AND evm_chain_id = $2`, n, ubig.New(o.chainID)); err != nil { return nil, err } return &b, nil } -func (o *DbORM) SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) { - q := o.q.WithOpts(qopts...) +func (o *DbORM) SelectLatestBlock(ctx context.Context) (*LogPollerBlock, error) { var b LogPollerBlock - if err := q.Get(&b, `SELECT * FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1`, ubig.New(o.chainID)); err != nil { + if err := o.db.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1`, ubig.New(o.chainID)); err != nil { return nil, err } return &b, nil } -func (o *DbORM) SelectLatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs Confirmations, qopts ...pg.QOpt) (*Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withConfs(confs). - toArgs() - if err != nil { - return nil, err - } +func (o *DbORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND event_sig = :event_sig - AND address = :address + WHERE evm_chain_id = $1 + AND event_sig = $2 + AND address = $3 AND block_number <= %s - ORDER BY (block_number, log_index) DESC LIMIT 1`, nestedBlockNumberQuery(confs)) + ORDER BY (block_number, log_index) DESC LIMIT 1`, + nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var l Log - if err := o.q.WithOpts(qopts...).GetNamed(query, &l, args); err != nil { + + if err := o.db.GetContext(ctx, &l, query, ubig.New(o.chainID), eventSig.Bytes(), address); err != nil { return nil, err } return &l, nil } // DeleteBlocksBefore delete all blocks before and including end. -func (o *DbORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { - q := o.q.WithOpts(qopts...) - _, err := q.Exec(`DELETE FROM evm.log_poller_blocks WHERE block_number <= $1 AND evm_chain_id = $2`, end, ubig.New(o.chainID)) +func (o *DbORM) DeleteBlocksBefore(ctx context.Context, end int64) error { + _, err := o.db.ExecContext(ctx, `DELETE FROM evm.log_poller_blocks WHERE block_number <= $1 AND evm_chain_id = $2`, end, ubig.New(o.chainID)) return err } -func (o *DbORM) DeleteLogsAndBlocksAfter(start int64, qopts ...pg.QOpt) error { - return o.q.WithOpts(qopts...).Transaction(func(tx pg.Queryer) error { - args, err := newQueryArgs(o.chainID). - withStartBlock(start). - toArgs() - if err != nil { - o.lggr.Error("Cant build args for DeleteLogsAndBlocksAfter queries", "err", err) - return err - } - +func (o *DbORM) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error { + // These deletes are bounded by reorg depth, so they are + // fast and should not slow down the log readers. + return o.Transaction(ctx, func(orm *DbORM) error { // Applying upper bound filter is critical for Postgres performance (especially for evm.logs table) // because it allows the planner to properly estimate the number of rows to be scanned. // If not applied, these queries can become very slow. After some critical number // of logs, Postgres will try to scan all the logs in the index by block_number. // Latency without upper bound filter can be orders of magnitude higher for large number of logs. - _, err = tx.NamedExec(`DELETE FROM evm.log_poller_blocks - WHERE evm_chain_id = :evm_chain_id - AND block_number >= :start_block - AND block_number <= (SELECT MAX(block_number) FROM evm.log_poller_blocks WHERE evm_chain_id = :evm_chain_id)`, args) + _, err := o.db.ExecContext(ctx, `DELETE FROM evm.log_poller_blocks + WHERE evm_chain_id = $1 + AND block_number >= $2 + AND block_number <= (SELECT MAX(block_number) + FROM evm.log_poller_blocks + WHERE evm_chain_id = $1)`, + ubig.New(o.chainID), start) if err != nil { o.lggr.Warnw("Unable to clear reorged blocks, retrying", "err", err) return err } - _, err = tx.NamedExec(`DELETE FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND block_number >= :start_block - AND block_number <= (SELECT MAX(block_number) FROM evm.logs WHERE evm_chain_id = :evm_chain_id)`, args) + _, err = o.db.ExecContext(ctx, `DELETE FROM evm.logs + WHERE evm_chain_id = $1 + AND block_number >= $2 + AND block_number <= (SELECT MAX(block_number) FROM evm.logs WHERE evm_chain_id = $1)`, + ubig.New(o.chainID), start) if err != nil { o.lggr.Warnw("Unable to clear reorged logs, retrying", "err", err) return err @@ -240,11 +224,8 @@ type Exp struct { ShouldDelete bool } -func (o *DbORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { - qopts = append(qopts, pg.WithLongQueryTimeout()) - q := o.q.WithOpts(qopts...) - - return q.ExecQ(`WITH r AS +func (o *DbORM) DeleteExpiredLogs(ctx context.Context) error { + _, err := o.db.ExecContext(ctx, `WITH r AS ( SELECT address, event, MAX(retention) AS retention FROM evm.log_poller_filters WHERE evm_chain_id=$1 GROUP BY evm_chain_id,address, event HAVING NOT 0 = ANY(ARRAY_AGG(retention)) @@ -252,23 +233,23 @@ func (o *DbORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { WHERE l.evm_chain_id = $1 AND l.address=r.address AND l.event_sig=r.event AND l.created_at <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second')`, // retention is in nanoseconds (time.Duration aka BIGINT) ubig.New(o.chainID)) + return err } // InsertLogs is idempotent to support replays. -func (o *DbORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error { +func (o *DbORM) InsertLogs(ctx context.Context, logs []Log) error { if err := o.validateLogs(logs); err != nil { return err } - - return o.q.WithOpts(qopts...).Transaction(func(tx pg.Queryer) error { - return o.insertLogsWithinTx(logs, tx) + return o.Transaction(ctx, func(orm *DbORM) error { + return o.insertLogsWithinTx(ctx, logs, orm.db.(*sqlx.Tx)) }) } -func (o *DbORM) InsertLogsWithBlock(logs []Log, block LogPollerBlock, qopts ...pg.QOpt) error { +func (o *DbORM) InsertLogsWithBlock(ctx context.Context, logs []Log, block LogPollerBlock) error { // Optimization, don't open TX when there is only a block to be persisted if len(logs) == 0 { - return o.InsertBlock(block.BlockHash, block.BlockNumber, block.BlockTimestamp, block.FinalizedBlockNumber, qopts...) + return o.InsertBlock(ctx, block.BlockHash, block.BlockNumber, block.BlockTimestamp, block.FinalizedBlockNumber) } if err := o.validateLogs(logs); err != nil { @@ -276,15 +257,23 @@ func (o *DbORM) InsertLogsWithBlock(logs []Log, block LogPollerBlock, qopts ...p } // Block and logs goes with the same TX to ensure atomicity - return o.q.WithOpts(qopts...).Transaction(func(tx pg.Queryer) error { - if err := o.InsertBlock(block.BlockHash, block.BlockNumber, block.BlockTimestamp, block.FinalizedBlockNumber, pg.WithQueryer(tx)); err != nil { + return o.Transaction(ctx, func(orm *DbORM) error { + if err := o.insertBlockWithinTx(ctx, orm.db.(*sqlx.Tx), block.BlockHash, block.BlockNumber, block.BlockTimestamp, block.FinalizedBlockNumber); err != nil { return err } - return o.insertLogsWithinTx(logs, tx) + return o.insertLogsWithinTx(ctx, logs, orm.db.(*sqlx.Tx)) }) } -func (o *DbORM) insertLogsWithinTx(logs []Log, tx pg.Queryer) error { +func (o *DbORM) insertBlockWithinTx(ctx context.Context, tx *sqlx.Tx, blockHash common.Hash, blockNumber int64, blockTimestamp time.Time, finalizedBlock int64) error { + query := `INSERT INTO evm.log_poller_blocks (evm_chain_id, block_hash, block_number, block_timestamp, finalized_block_number, created_at) + VALUES ($1, $2, $3, $4, $5, NOW()) + ON CONFLICT DO NOTHING` + _, err := tx.ExecContext(ctx, query, ubig.New(o.chainID), blockHash.Bytes(), blockNumber, blockTimestamp, finalizedBlock) + return err +} + +func (o *DbORM) insertLogsWithinTx(ctx context.Context, logs []Log, tx *sqlx.Tx) error { batchInsertSize := 4000 for i := 0; i < len(logs); i += batchInsertSize { start, end := i, i+batchInsertSize @@ -292,7 +281,7 @@ func (o *DbORM) insertLogsWithinTx(logs []Log, tx pg.Queryer) error { end = len(logs) } - _, err := tx.NamedExec(` + _, err := tx.NamedExecContext(ctx, ` INSERT INTO evm.logs (evm_chain_id, log_index, block_hash, block_number, block_timestamp, address, event_sig, topics, tx_hash, data, created_at) VALUES @@ -323,46 +312,31 @@ func (o *DbORM) validateLogs(logs []Log) error { return nil } -func (o *DbORM) SelectLogsByBlockRange(start, end int64) ([]Log, error) { - args, err := newQueryArgs(o.chainID). - withStartBlock(start). - withEndBlock(end). - toArgs() - if err != nil { - return nil, err - } - +func (o *DbORM) SelectLogsByBlockRange(ctx context.Context, start, end int64) ([]Log, error) { var logs []Log - err = o.q.SelectNamed(&logs, ` + err := o.db.SelectContext(ctx, &logs, ` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND block_number >= :start_block - AND block_number <= :end_block - ORDER BY (block_number, log_index, created_at)`, args) + WHERE evm_chain_id = $1 + AND block_number >= $2 + AND block_number <= $3 + ORDER BY (block_number, log_index, created_at)`, ubig.New(o.chainID), start, end) if err != nil { return nil, err } return logs, nil } -// SelectLogsByBlockRangeFilter finds the logs in a given block range. -func (o *DbORM) SelectLogs(start, end int64, address common.Address, eventSig common.Hash, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withStartBlock(start). - withEndBlock(end). - toArgs() - if err != nil { - return nil, err - } +// SelectLogs finds the logs in a given block range. +func (o *DbORM) SelectLogs(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash) ([]Log, error) { var logs []Log - err = o.q.WithOpts(qopts...).SelectNamed(&logs, ` + err := o.db.SelectContext(ctx, &logs, ` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND block_number >= :start_block - AND block_number <= :end_block - ORDER BY (block_number, log_index)`, args) + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND block_number >= $4 + AND block_number <= $5 + ORDER BY (block_number, log_index)`, ubig.New(o.chainID), address, eventSig.Bytes(), start, end) if err != nil { return nil, err } @@ -370,73 +344,48 @@ func (o *DbORM) SelectLogs(start, end int64, address common.Address, eventSig co } // SelectLogsCreatedAfter finds logs created after some timestamp. -func (o *DbORM) SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withBlockTimestampAfter(after). - withConfs(confs). - toArgs() - if err != nil { - return nil, err - } - +func (o *DbORM) SelectLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, after time.Time, confs Confirmations) ([]Log, error) { query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND block_timestamp > :block_timestamp_after + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND block_timestamp > $4 AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY (block_number, log_index)`, + nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var logs []Log - if err = o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), after); err != nil { return nil, err } return logs, nil } -// SelectLogsWithSigsByBlockRangeFilter finds the logs in the given block range with the given event signatures +// SelectLogsWithSigs finds the logs in the given block range with the given event signatures // emitted from the given address. -func (o *DbORM) SelectLogsWithSigs(start, end int64, address common.Address, eventSigs []common.Hash, qopts ...pg.QOpt) (logs []Log, err error) { - args, err := newQueryArgs(o.chainID). - withAddress(address). - withEventSigArray(eventSigs). - withStartBlock(start). - withEndBlock(end). - toArgs() - if err != nil { - return nil, err - } - - q := o.q.WithOpts(qopts...) - err = q.SelectNamed(&logs, ` +func (o *DbORM) SelectLogsWithSigs(ctx context.Context, start, end int64, address common.Address, eventSigs []common.Hash) (logs []Log, err error) { + err = o.db.SelectContext(ctx, &logs, ` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = ANY(:event_sig_array) - AND block_number BETWEEN :start_block AND :end_block - ORDER BY (block_number, log_index)`, args) + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = ANY($3) + AND block_number BETWEEN $4 AND $5 + ORDER BY (block_number, log_index)`, ubig.New(o.chainID), address, concatBytes(eventSigs), start, end) if errors.Is(err, sql.ErrNoRows) { return nil, nil } return logs, err } -func (o *DbORM) GetBlocksRange(start int64, end int64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { - args, err := newQueryArgs(o.chainID). - withStartBlock(start). - withEndBlock(end). - toArgs() - if err != nil { - return nil, err - } +func (o *DbORM) GetBlocksRange(ctx context.Context, start int64, end int64) ([]LogPollerBlock, error) { var blocks []LogPollerBlock - err = o.q.WithOpts(qopts...).SelectNamed(&blocks, ` + err := o.db.SelectContext(ctx, &blocks, ` SELECT * FROM evm.log_poller_blocks - WHERE block_number >= :start_block - AND block_number <= :end_block - AND evm_chain_id = :evm_chain_id - ORDER BY block_number ASC`, args) + WHERE block_number >= $1 + AND block_number <= $2 + AND evm_chain_id = $3 + ORDER BY block_number ASC`, start, end, ubig.New(o.chainID)) if err != nil { return nil, err } @@ -444,280 +393,214 @@ func (o *DbORM) GetBlocksRange(start int64, end int64, qopts ...pg.QOpt) ([]LogP } // SelectLatestLogEventSigsAddrsWithConfs finds the latest log by (address, event) combination that matches a list of Addresses and list of events -func (o *DbORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgs(o.chainID). - withAddressArray(addresses). - withEventSigArray(eventSigs). - withStartBlock(fromBlock). - withConfs(confs). - toArgs() - if err != nil { - return nil, err - } +func (o *DbORM) SelectLatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations) ([]Log, error) { + // TODO: cant convert byteArray!? query := fmt.Sprintf(` SELECT * FROM evm.logs WHERE (block_number, address, event_sig) IN ( SELECT MAX(block_number), address, event_sig FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND event_sig = ANY(:event_sig_array) - AND address = ANY(:address_array) - AND block_number > :start_block + WHERE evm_chain_id = $1 + AND event_sig = ANY($2) + AND address = ANY($3) + AND block_number > $4 AND block_number <= %s GROUP BY event_sig, address ) - ORDER BY block_number ASC`, nestedBlockNumberQuery(confs)) + ORDER BY block_number ASC`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) + var logs []Log - if err := o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), concatBytes(eventSigs), concatBytes(addresses), fromBlock); err != nil { return nil, errors.Wrap(err, "failed to execute query") } return logs, nil } -// SelectLatestBlockNumberEventSigsAddrsWithConfs finds the latest block number that matches a list of Addresses and list of events. It returns 0 if there is no matching block -func (o *DbORM) SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations, qopts ...pg.QOpt) (int64, error) { - args, err := newQueryArgs(o.chainID). - withEventSigArray(eventSigs). - withAddressArray(addresses). - withStartBlock(fromBlock). - withConfs(confs). - toArgs() - if err != nil { - return 0, err - } +// SelectLatestBlockByEventSigsAddrsWithConfs finds the latest block number that matches a list of Addresses and list of events. It returns 0 if there is no matching block +func (o *DbORM) SelectLatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) { query := fmt.Sprintf(` SELECT COALESCE(MAX(block_number), 0) FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND event_sig = ANY(:event_sig_array) - AND address = ANY(:address_array) - AND block_number > :start_block - AND block_number <= %s`, nestedBlockNumberQuery(confs)) + WHERE evm_chain_id = $1 + AND event_sig = ANY($2) + AND address = ANY($3) + AND block_number > $4 + AND block_number <= %s`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var blockNumber int64 - if err := o.q.WithOpts(qopts...).GetNamed(query, &blockNumber, args); err != nil { + if err := o.db.GetContext(ctx, &blockNumber, query, ubig.New(o.chainID), concatBytes(eventSigs), concatBytes(addresses), fromBlock); err != nil { return 0, err } return blockNumber, nil } -func (o *DbORM) SelectLogsDataWordRange(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withWordIndex(wordIndex). - withWordValueMin(wordValueMin). - withWordValueMax(wordValueMax). - withConfs(confs). - toArgs() - if err != nil { - return nil, err - } - query := fmt.Sprintf(`SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND substring(data from 32*:word_index+1 for 32) >= :word_value_min - AND substring(data from 32*:word_index+1 for 32) <= :word_value_max - AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) +func (o *DbORM) SelectLogsDataWordRange(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) { + query := fmt.Sprintf(`SELECT * FROM evm.logs + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND substring(data from 32*$4+1 for 32) >= $5 + AND substring(data from 32*$4+1 for 32) <= $6 + AND block_number <= %s + ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var logs []Log - if err := o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), wordValueMax.Bytes()); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectLogsDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withWordIndex(wordIndex). - withWordValueMin(wordValueMin). - withConfs(confs). - toArgs() - if err != nil { - return nil, err - } +func (o *DbORM) SelectLogsDataWordGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) { query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND substring(data from 32*:word_index+1 for 32) >= :word_value_min + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND substring(data from 32*$4+1 for 32) >= $5 AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var logs []Log - if err = o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes()); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectLogsDataWordBetween(address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withWordIndexMin(wordIndexMin). - withWordIndexMax(wordIndexMax). - withWordValue(wordValue). - withConfs(confs). - toArgs() - if err != nil { - return nil, err - } +func (o *DbORM) SelectLogsDataWordBetween(ctx context.Context, address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) { query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND substring(data from 32*:word_index_min+1 for 32) <= :word_value - AND substring(data from 32*:word_index_max+1 for 32) >= :word_value + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND substring(data from 32*$4+1 for 32) <= $5 + AND substring(data from 32*$6+1 for 32) >= $5 AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var logs []Log - if err = o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), wordIndexMin, wordValue.Bytes(), wordIndexMax); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsTopicGreaterThan(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withTopicIndex(topicIndex). - withTopicValueMin(topicValueMin). - withConfs(confs). - toArgs() +func (o *DbORM) SelectIndexedLogsTopicGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) { + topicIndex, err := UseTopicIndex(topicIndex) if err != nil { return nil, err } + query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND topics[:topic_index] >= :topic_value_min + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND topics[$4] >= $5 AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var logs []Log - if err = o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), topicIndex, topicValueMin.Bytes()); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsTopicRange(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withTopicIndex(topicIndex). - withTopicValueMin(topicValueMin). - withTopicValueMax(topicValueMax). - withConfs(confs). - toArgs() +func (o *DbORM) SelectIndexedLogsTopicRange(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations) ([]Log, error) { + topicIndex, err := UseTopicIndex(topicIndex) if err != nil { return nil, err } + query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND topics[:topic_index] >= :topic_value_min - AND topics[:topic_index] <= :topic_value_max + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND topics[$4] >= $5 + AND topics[$4] <= $6 AND block_number <= %s - ORDER BY (evm.logs.block_number, evm.logs.log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY (evm.logs.block_number, evm.logs.log_index)`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) + var logs []Log - if err := o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), topicIndex, topicValueMin.Bytes(), topicValueMax.Bytes()); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withTopicIndex(topicIndex). - withTopicValues(topicValues). - withConfs(confs). - toArgs() +func (o *DbORM) SelectIndexedLogs(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) { + topicIndex, err := UseTopicIndex(topicIndex) if err != nil { return nil, err } + query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND topics[:topic_index] = ANY(:topic_values) + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND topics[$4] = ANY($5) AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) + var logs []Log - if err := o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), topicIndex, concatBytes(topicValues)); err != nil { return nil, err } return logs, nil } -// SelectIndexedLogsByBlockRangeFilter finds the indexed logs in a given block range. -func (o *DbORM) SelectIndexedLogsByBlockRange(start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withTopicIndex(topicIndex). - withTopicValues(topicValues). - withStartBlock(start). - withEndBlock(end). - toArgs() +// SelectIndexedLogsByBlockRange finds the indexed logs in a given block range. +func (o *DbORM) SelectIndexedLogsByBlockRange(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash) ([]Log, error) { + topicIndex, err := UseTopicIndex(topicIndex) if err != nil { return nil, err } + var logs []Log - err = o.q.WithOpts(qopts...).SelectNamed(&logs, ` + err = o.db.SelectContext(ctx, &logs, ` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND topics[:topic_index] = ANY(:topic_values) - AND block_number >= :start_block - AND block_number <= :end_block - ORDER BY (block_number, log_index)`, args) + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND topics[$4] = ANY($5) + AND block_number >= $6 + AND block_number <= $7 + ORDER BY (block_number, log_index)`, + ubig.New(o.chainID), address, eventSig.Bytes(), topicIndex, concatBytes(topicValues), start, end) if err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgsForEvent(o.chainID, address, eventSig). - withBlockTimestampAfter(after). - withConfs(confs). - withTopicIndex(topicIndex). - withTopicValues(topicValues). - toArgs() +func (o *DbORM) SelectIndexedLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) { + topicIndex, err := UseTopicIndex(topicIndex) if err != nil { return nil, err } query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND topics[:topic_index] = ANY(:topic_values) - AND block_timestamp > :block_timestamp_after + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND topics[$4] = ANY($5) + AND block_timestamp > $6 AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs, ubig.New(o.chainID))) var logs []Log - if err = o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, eventSig.Bytes(), topicIndex, concatBytes(topicValues), after); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsByTxHash(address common.Address, eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgs(o.chainID). - withTxHash(txHash). - withAddress(address). - withEventSig(eventSig). - toArgs() - if err != nil { - return nil, err - } +func (o *DbORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Address, eventSig common.Hash, txHash common.Hash) ([]Log, error) { var logs []Log - err = o.q.WithOpts(qopts...).SelectNamed(&logs, ` + err := o.db.SelectContext(ctx, &logs, ` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :event_sig - AND tx_hash = :tx_hash - ORDER BY (block_number, log_index)`, args) + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND tx_hash = $4 + ORDER BY (block_number, log_index)`, ubig.New(o.chainID), address, eventSig.Bytes(), txHash.Bytes()) if err != nil { return nil, err } @@ -725,60 +608,74 @@ func (o *DbORM) SelectIndexedLogsByTxHash(address common.Address, eventSig commo } // SelectIndexedLogsWithSigsExcluding query's for logs that have signature A and exclude logs that have a corresponding signature B, matching is done based on the topic index both logs should be inside the block range and have the minimum number of confirmations -func (o *DbORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations, qopts ...pg.QOpt) ([]Log, error) { - args, err := newQueryArgs(o.chainID). - withAddress(address). - withTopicIndex(topicIndex). - withStartBlock(startBlock). - withEndBlock(endBlock). - withCustomHashArg("sigA", sigA). - withCustomHashArg("sigB", sigB). - withConfs(confs). - toArgs() +func (o *DbORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations) ([]Log, error) { + topicIndex, err := UseTopicIndex(topicIndex) if err != nil { return nil, err } - nestedQuery := nestedBlockNumberQuery(confs) + nestedQuery := nestedBlockNumberQuery(confs, ubig.New(o.chainID)) query := fmt.Sprintf(` SELECT * FROM evm.logs - WHERE evm_chain_id = :evm_chain_id - AND address = :address - AND event_sig = :sigA - AND block_number BETWEEN :start_block AND :end_block + WHERE evm_chain_id = $1 + AND address = $2 + AND event_sig = $3 + AND block_number BETWEEN $5 AND $6 AND block_number <= %s EXCEPT SELECT a.* FROM evm.logs AS a INNER JOIN evm.logs B ON a.evm_chain_id = b.evm_chain_id AND a.address = b.address - AND a.topics[:topic_index] = b.topics[:topic_index] - AND a.event_sig = :sigA - AND b.event_sig = :sigB - AND b.block_number BETWEEN :start_block AND :end_block + AND a.topics[$7] = b.topics[$7] + AND a.event_sig = $3 + AND b.event_sig = $4 + AND b.block_number BETWEEN $5 AND $6 AND b.block_number <= %s ORDER BY block_number,log_index ASC`, nestedQuery, nestedQuery) + var logs []Log - if err := o.q.WithOpts(qopts...).SelectNamed(&logs, query, args); err != nil { + if err := o.db.SelectContext(ctx, &logs, query, ubig.New(o.chainID), address, sigA.Bytes(), sigB.Bytes(), startBlock, endBlock, topicIndex); err != nil { return nil, err } return logs, nil } -func nestedBlockNumberQuery(confs Confirmations) string { +func nestedBlockNumberQuery(confs Confirmations, chainID *ubig.Big) string { if confs == Finalized { - return ` + return fmt.Sprintf(` (SELECT finalized_block_number FROM evm.log_poller_blocks - WHERE evm_chain_id = :evm_chain_id - ORDER BY block_number DESC LIMIT 1) ` + WHERE evm_chain_id = %v + ORDER BY block_number DESC LIMIT 1) `, chainID) } // Intentionally wrap with greatest() function and don't return negative block numbers when :confs > :block_number // It doesn't impact logic of the outer query, because block numbers are never less or equal to 0 (guarded by log_poller_blocks_block_number_check) - return ` - (SELECT greatest(block_number - :confs, 0) + return fmt.Sprintf(` + (SELECT greatest(block_number - %d, 0) FROM evm.log_poller_blocks - WHERE evm_chain_id = :evm_chain_id - ORDER BY block_number DESC LIMIT 1) ` + WHERE evm_chain_id = %v + ORDER BY block_number DESC LIMIT 1) `, confs, chainID) + +} + +func UseTopicIndex(index int) (int, error) { + // Only topicIndex 1 through 3 is valid. 0 is the event sig and only 4 total topics are allowed + if !(index == 1 || index == 2 || index == 3) { + return 0, fmt.Errorf("invalid index for topic: %d", index) + } + // Add 1 since postgresql arrays are 1-indexed. + return index + 1, nil +} +type bytesProducer interface { + Bytes() []byte +} + +func concatBytes[T bytesProducer](byteSlice []T) [][]byte { + var output [][]byte + for _, b := range byteSlice { + output = append(output, b.Bytes()) + } + return output } diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index bcaa6f72fa0..dc187e59de0 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -22,8 +22,6 @@ import ( ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type block struct { @@ -68,6 +66,7 @@ func GenLogWithData(chainID *big.Int, address common.Address, eventSig common.Ha func TestLogPoller_Batching(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) th := SetupTH(t, false, 2, 3, 2, 1000) var logs []logpoller.Log // Inserts are limited to 65535 parameters. A log being 10 parameters this results in @@ -76,8 +75,8 @@ func TestLogPoller_Batching(t *testing.T) { for i := 0; i < 15000; i++ { logs = append(logs, GenLog(th.ChainID, int64(i+1), 1, "0x3", EmitterABI.Events["Log1"].ID.Bytes(), th.EmitterAddress1)) } - require.NoError(t, th.ORM.InsertLogs(logs)) - lgs, err := th.ORM.SelectLogsByBlockRange(1, 1) + require.NoError(t, th.ORM.InsertLogs(ctx, logs)) + lgs, err := th.ORM.SelectLogsByBlockRange(ctx, 1, 1) require.NoError(t, err) // Make sure all logs are inserted require.Equal(t, len(logs), len(lgs)) @@ -86,6 +85,7 @@ func TestLogPoller_Batching(t *testing.T) { func TestORM_GetBlocks_From_Range(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) o1 := th.ORM + ctx := testutils.Context(t) // Insert many blocks and read them back together blocks := []block{ { @@ -115,7 +115,7 @@ func TestORM_GetBlocks_From_Range(t *testing.T) { }, } for _, b := range blocks { - require.NoError(t, o1.InsertBlock(b.hash, b.number, time.Unix(b.timestamp, 0).UTC(), 0)) + require.NoError(t, o1.InsertBlock(ctx, b.hash, b.number, time.Unix(b.timestamp, 0).UTC(), 0)) } var blockNumbers []int64 @@ -123,17 +123,17 @@ func TestORM_GetBlocks_From_Range(t *testing.T) { blockNumbers = append(blockNumbers, b.number) } - lpBlocks, err := o1.GetBlocksRange(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) + lpBlocks, err := o1.GetBlocksRange(ctx, blockNumbers[0], blockNumbers[len(blockNumbers)-1]) require.NoError(t, err) assert.Len(t, lpBlocks, len(blocks)) // Ignores non-existent block - lpBlocks2, err := o1.GetBlocksRange(blockNumbers[0], 15) + lpBlocks2, err := o1.GetBlocksRange(ctx, blockNumbers[0], 15) require.NoError(t, err) assert.Len(t, lpBlocks2, len(blocks)) // Only non-existent blocks - lpBlocks3, err := o1.GetBlocksRange(15, 15) + lpBlocks3, err := o1.GetBlocksRange(ctx, 15, 15) require.NoError(t, err) assert.Len(t, lpBlocks3, 0) } @@ -141,13 +141,14 @@ func TestORM_GetBlocks_From_Range(t *testing.T) { func TestORM_GetBlocks_From_Range_Recent_Blocks(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) o1 := th.ORM + ctx := testutils.Context(t) // Insert many blocks and read them back together var recentBlocks []block for i := 1; i <= 256; i++ { recentBlocks = append(recentBlocks, block{number: int64(i), hash: common.HexToHash(fmt.Sprintf("0x%d", i))}) } for _, b := range recentBlocks { - require.NoError(t, o1.InsertBlock(b.hash, b.number, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, b.hash, b.number, time.Now(), 0)) } var blockNumbers []int64 @@ -155,17 +156,17 @@ func TestORM_GetBlocks_From_Range_Recent_Blocks(t *testing.T) { blockNumbers = append(blockNumbers, b.number) } - lpBlocks, err := o1.GetBlocksRange(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) + lpBlocks, err := o1.GetBlocksRange(ctx, blockNumbers[0], blockNumbers[len(blockNumbers)-1]) require.NoError(t, err) assert.Len(t, lpBlocks, len(recentBlocks)) // Ignores non-existent block - lpBlocks2, err := o1.GetBlocksRange(blockNumbers[0], 257) + lpBlocks2, err := o1.GetBlocksRange(ctx, blockNumbers[0], 257) require.NoError(t, err) assert.Len(t, lpBlocks2, len(recentBlocks)) // Only non-existent blocks - lpBlocks3, err := o1.GetBlocksRange(257, 257) + lpBlocks3, err := o1.GetBlocksRange(ctx, 257, 257) require.NoError(t, err) assert.Len(t, lpBlocks3, 0) } @@ -174,51 +175,52 @@ func TestORM(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) o1 := th.ORM o2 := th.ORM2 + ctx := testutils.Context(t) // Insert and read back a block. - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 10, time.Now(), 0)) - b, err := o1.SelectBlockByHash(common.HexToHash("0x1234")) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1234"), 10, time.Now(), 0)) + b, err := o1.SelectBlockByHash(ctx, common.HexToHash("0x1234")) require.NoError(t, err) assert.Equal(t, b.BlockNumber, int64(10)) assert.Equal(t, b.BlockHash.Bytes(), common.HexToHash("0x1234").Bytes()) assert.Equal(t, b.EvmChainId.String(), th.ChainID.String()) // Insert blocks from a different chain - require.NoError(t, o2.InsertBlock(common.HexToHash("0x1234"), 11, time.Now(), 0)) - require.NoError(t, o2.InsertBlock(common.HexToHash("0x1235"), 12, time.Now(), 0)) - b2, err := o2.SelectBlockByHash(common.HexToHash("0x1234")) + require.NoError(t, o2.InsertBlock(ctx, common.HexToHash("0x1234"), 11, time.Now(), 0)) + require.NoError(t, o2.InsertBlock(ctx, common.HexToHash("0x1235"), 12, time.Now(), 0)) + b2, err := o2.SelectBlockByHash(ctx, common.HexToHash("0x1234")) require.NoError(t, err) assert.Equal(t, b2.BlockNumber, int64(11)) assert.Equal(t, b2.BlockHash.Bytes(), common.HexToHash("0x1234").Bytes()) assert.Equal(t, b2.EvmChainId.String(), th.ChainID2.String()) - latest, err := o1.SelectLatestBlock() + latest, err := o1.SelectLatestBlock(ctx) require.NoError(t, err) assert.Equal(t, int64(10), latest.BlockNumber) - latest, err = o2.SelectLatestBlock() + latest, err = o2.SelectLatestBlock(ctx) require.NoError(t, err) assert.Equal(t, int64(12), latest.BlockNumber) // Delete a block (only 10 on chain). - require.NoError(t, o1.DeleteLogsAndBlocksAfter(10)) - _, err = o1.SelectBlockByHash(common.HexToHash("0x1234")) + require.NoError(t, o1.DeleteLogsAndBlocksAfter(ctx, 10)) + _, err = o1.SelectBlockByHash(ctx, common.HexToHash("0x1234")) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) // Delete blocks from another chain. - require.NoError(t, o2.DeleteLogsAndBlocksAfter(11)) - _, err = o2.SelectBlockByHash(common.HexToHash("0x1234")) + require.NoError(t, o2.DeleteLogsAndBlocksAfter(ctx, 11)) + _, err = o2.SelectBlockByHash(ctx, common.HexToHash("0x1234")) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) // Delete blocks after should also delete block 12. - _, err = o2.SelectBlockByHash(common.HexToHash("0x1235")) + _, err = o2.SelectBlockByHash(ctx, common.HexToHash("0x1235")) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) // Should be able to insert and read back a log. topic := common.HexToHash("0x1599") topic2 := common.HexToHash("0x1600") - require.NoError(t, o1.InsertLogs([]logpoller.Log{ + require.NoError(t, o1.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: ubig.New(th.ChainID), LogIndex: 1, @@ -310,86 +312,86 @@ func TestORM(t *testing.T) { })) t.Log(latest.BlockNumber) - logs, err := o1.SelectLogsByBlockRange(1, 17) + logs, err := o1.SelectLogsByBlockRange(ctx, 1, 17) require.NoError(t, err) require.Len(t, logs, 8) - logs, err = o1.SelectLogsByBlockRange(10, 10) + logs, err = o1.SelectLogsByBlockRange(ctx, 10, 10) require.NoError(t, err) require.Equal(t, 1, len(logs)) assert.Equal(t, []byte("hello"), logs[0].Data) - logs, err = o1.SelectLogs(1, 1, common.HexToAddress("0x1234"), topic) + logs, err = o1.SelectLogs(ctx, 1, 1, common.HexToAddress("0x1234"), topic) require.NoError(t, err) assert.Equal(t, 0, len(logs)) - logs, err = o1.SelectLogs(10, 10, common.HexToAddress("0x1234"), topic) + logs, err = o1.SelectLogs(ctx, 10, 10, common.HexToAddress("0x1234"), topic) require.NoError(t, err) require.Equal(t, 1, len(logs)) // With no blocks, should be an error - _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) + _, err = o1.SelectLatestLogByEventSigWithConfs(ctx, topic, common.HexToAddress("0x1234"), 0) require.Error(t, err) - assert.True(t, errors.Is(err, sql.ErrNoRows)) + require.True(t, errors.Is(err, sql.ErrNoRows)) // With block 10, only 0 confs should work - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 10, time.Now(), 0)) - log, err := o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1234"), 10, time.Now(), 0)) + log, err := o1.SelectLatestLogByEventSigWithConfs(ctx, topic, common.HexToAddress("0x1234"), 0) require.NoError(t, err) assert.Equal(t, int64(10), log.BlockNumber) - _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 1) + _, err = o1.SelectLatestLogByEventSigWithConfs(ctx, topic, common.HexToAddress("0x1234"), 1) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) // With block 12, anything <=2 should work - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 11, time.Now(), 0)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1235"), 12, time.Now(), 0)) - _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1234"), 11, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1235"), 12, time.Now(), 0)) + _, err = o1.SelectLatestLogByEventSigWithConfs(ctx, topic, common.HexToAddress("0x1234"), 0) require.NoError(t, err) - _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 1) + _, err = o1.SelectLatestLogByEventSigWithConfs(ctx, topic, common.HexToAddress("0x1234"), 1) require.NoError(t, err) - _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 2) + _, err = o1.SelectLatestLogByEventSigWithConfs(ctx, topic, common.HexToAddress("0x1234"), 2) require.NoError(t, err) - _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 3) + _, err = o1.SelectLatestLogByEventSigWithConfs(ctx, topic, common.HexToAddress("0x1234"), 3) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) // Required for confirmations to work - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 13, time.Now(), 0)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1235"), 14, time.Now(), 0)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1236"), 15, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1234"), 13, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1235"), 14, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1236"), 15, time.Now(), 0)) // Latest log for topic for addr "0x1234" is @ block 11 - lgs, err := o1.SelectLatestLogEventSigsAddrsWithConfs(0 /* startBlock */, []common.Address{common.HexToAddress("0x1234")}, []common.Hash{topic}, 0) + lgs, err := o1.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0 /* startBlock */, []common.Address{common.HexToAddress("0x1234")}, []common.Hash{topic}, 0) require.NoError(t, err) require.Equal(t, 1, len(lgs)) require.Equal(t, int64(11), lgs[0].BlockNumber) // should return two entries one for each address with the latest update - lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic}, 0) + lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic}, 0) require.NoError(t, err) require.Equal(t, 2, len(lgs)) // should return two entries one for each topic for addr 0x1234 - lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(0 /* startBlock */, []common.Address{common.HexToAddress("0x1234")}, []common.Hash{topic, topic2}, 0) + lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0 /* startBlock */, []common.Address{common.HexToAddress("0x1234")}, []common.Hash{topic, topic2}, 0) require.NoError(t, err) require.Equal(t, 2, len(lgs)) // should return 4 entries one for each (address,topic) combination - lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic, topic2}, 0) + lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic, topic2}, 0) require.NoError(t, err) require.Equal(t, 4, len(lgs)) // should return 3 entries of logs with atleast 1 confirmation - lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic, topic2}, 1) + lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic, topic2}, 1) require.NoError(t, err) require.Equal(t, 3, len(lgs)) // should return 2 entries of logs with atleast 2 confirmation - lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic, topic2}, 2) + lgs, err = o1.SelectLatestLogEventSigsAddrsWithConfs(ctx, 0 /* startBlock */, []common.Address{common.HexToAddress("0x1234"), common.HexToAddress("0x1235")}, []common.Hash{topic, topic2}, 2) require.NoError(t, err) require.Equal(t, 2, len(lgs)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1237"), 16, time.Now(), 0)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1238"), 17, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1237"), 16, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1238"), 17, time.Now(), 0)) filter0 := logpoller.Filter{ Name: "permanent retention filter", @@ -411,29 +413,29 @@ func TestORM(t *testing.T) { } // Test inserting filters and reading them back - require.NoError(t, o1.InsertFilter(filter0)) - require.NoError(t, o1.InsertFilter(filter12)) - require.NoError(t, o1.InsertFilter(filter2)) + require.NoError(t, o1.InsertFilter(ctx, filter0)) + require.NoError(t, o1.InsertFilter(ctx, filter12)) + require.NoError(t, o1.InsertFilter(ctx, filter2)) - filters, err := o1.LoadFilters() + filters, err := o1.LoadFilters(ctx) require.NoError(t, err) require.Len(t, filters, 3) assert.Equal(t, filter0, filters["permanent retention filter"]) assert.Equal(t, filter12, filters["short retention filter"]) assert.Equal(t, filter2, filters["long retention filter"]) - latest, err = o1.SelectLatestBlock() + latest, err = o1.SelectLatestBlock(ctx) require.NoError(t, err) require.Equal(t, int64(17), latest.BlockNumber) - logs, err = o1.SelectLogsByBlockRange(1, latest.BlockNumber) + logs, err = o1.SelectLogsByBlockRange(ctx, 1, latest.BlockNumber) require.NoError(t, err) require.Len(t, logs, 8) // Delete expired logs time.Sleep(2 * time.Millisecond) // just in case we haven't reached the end of the 1ms retention period - err = o1.DeleteExpiredLogs(pg.WithParentCtx(testutils.Context(t))) + err = o1.DeleteExpiredLogs(ctx) require.NoError(t, err) - logs, err = o1.SelectLogsByBlockRange(1, latest.BlockNumber) + logs, err = o1.SelectLogsByBlockRange(ctx, 1, latest.BlockNumber) require.NoError(t, err) // The only log which should be deleted is the one which matches filter1 (ret=1ms) but not filter12 (ret=1 hour) // Importantly, it shouldn't delete any logs matching only filter0 (ret=0 meaning permanent retention). Anything @@ -441,9 +443,9 @@ func TestORM(t *testing.T) { assert.Len(t, logs, 7) // Delete logs after should delete all logs. - err = o1.DeleteLogsAndBlocksAfter(1) + err = o1.DeleteLogsAndBlocksAfter(ctx, 1) require.NoError(t, err) - logs, err = o1.SelectLogsByBlockRange(1, latest.BlockNumber) + logs, err = o1.SelectLogsByBlockRange(ctx, 1, latest.BlockNumber) require.NoError(t, err) require.Zero(t, len(logs)) } @@ -463,66 +465,67 @@ func insertLogsTopicValueRange(t *testing.T, chainID *big.Int, o *logpoller.DbOR Data: []byte("hello"), }) } - require.NoError(t, o.InsertLogs(lgs)) + require.NoError(t, o.InsertLogs(testutils.Context(t), lgs)) } func TestORM_IndexedLogs(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) o1 := th.ORM + ctx := testutils.Context(t) eventSig := common.HexToHash("0x1599") addr := common.HexToAddress("0x1234") - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1"), 1, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1"), 1, time.Now(), 0)) insertLogsTopicValueRange(t, th.ChainID, o1, addr, 1, eventSig, 1, 3) insertLogsTopicValueRange(t, th.ChainID, o1, addr, 2, eventSig, 4, 4) // unconfirmed - lgs, err := o1.SelectIndexedLogs(addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}, 0) + lgs, err := o1.SelectIndexedLogs(ctx, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}, 0) require.NoError(t, err) require.Equal(t, 1, len(lgs)) assert.Equal(t, logpoller.EvmWord(1).Bytes(), lgs[0].GetTopics()[1].Bytes()) - lgs, err = o1.SelectIndexedLogs(addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1), logpoller.EvmWord(2)}, 0) + lgs, err = o1.SelectIndexedLogs(ctx, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1), logpoller.EvmWord(2)}, 0) require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - lgs, err = o1.SelectIndexedLogsByBlockRange(1, 1, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) + lgs, err = o1.SelectIndexedLogsByBlockRange(ctx, 1, 1, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - lgs, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(2)}) + lgs, err = o1.SelectIndexedLogsByBlockRange(ctx, 1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(2)}) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - lgs, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) + lgs, err = o1.SelectIndexedLogsByBlockRange(ctx, 1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - _, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 0, []common.Hash{logpoller.EvmWord(1)}) + _, err = o1.SelectIndexedLogsByBlockRange(ctx, 1, 2, addr, eventSig, 0, []common.Hash{logpoller.EvmWord(1)}) require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 0") - _, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 4, []common.Hash{logpoller.EvmWord(1)}) + _, err = o1.SelectIndexedLogsByBlockRange(ctx, 1, 2, addr, eventSig, 4, []common.Hash{logpoller.EvmWord(1)}) require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 4") - lgs, err = o1.SelectIndexedLogsTopicGreaterThan(addr, eventSig, 1, logpoller.EvmWord(2), 0) + lgs, err = o1.SelectIndexedLogsTopicGreaterThan(ctx, addr, eventSig, 1, logpoller.EvmWord(2), 0) require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) + lgs, err = o1.SelectIndexedLogsTopicRange(ctx, addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) assert.Equal(t, logpoller.EvmWord(3).Bytes(), lgs[0].GetTopics()[1].Bytes()) - lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(1), logpoller.EvmWord(3), 0) + lgs, err = o1.SelectIndexedLogsTopicRange(ctx, addr, eventSig, 1, logpoller.EvmWord(1), logpoller.EvmWord(3), 0) require.NoError(t, err) assert.Equal(t, 3, len(lgs)) // Check confirmations work as expected. - require.NoError(t, o1.InsertBlock(common.HexToHash("0x2"), 2, time.Now(), 0)) - lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x2"), 2, time.Now(), 0)) + lgs, err = o1.SelectIndexedLogsTopicRange(ctx, addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) require.NoError(t, err) assert.Equal(t, 0, len(lgs)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x3"), 3, time.Now(), 0)) - lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x3"), 3, time.Now(), 0)) + lgs, err = o1.SelectIndexedLogsTopicRange(ctx, addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) } @@ -530,11 +533,12 @@ func TestORM_IndexedLogs(t *testing.T) { func TestORM_SelectIndexedLogsByTxHash(t *testing.T) { th := SetupTH(t, false, 0, 3, 2, 1000) o1 := th.ORM + ctx := testutils.Context(t) eventSig := common.HexToHash("0x1599") txHash := common.HexToHash("0x1888") addr := common.HexToAddress("0x1234") - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1"), 1, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1"), 1, time.Now(), 0)) logs := []logpoller.Log{ { EvmChainId: ubig.New(th.ChainID), @@ -583,9 +587,9 @@ func TestORM_SelectIndexedLogsByTxHash(t *testing.T) { Data: append(logpoller.EvmWord(2).Bytes(), logpoller.EvmWord(3).Bytes()...), }, } - require.NoError(t, o1.InsertLogs(logs)) + require.NoError(t, o1.InsertLogs(ctx, logs)) - retrievedLogs, err := o1.SelectIndexedLogsByTxHash(addr, eventSig, txHash) + retrievedLogs, err := o1.SelectIndexedLogsByTxHash(ctx, addr, eventSig, txHash) require.NoError(t, err) require.Equal(t, 2, len(retrievedLogs)) @@ -596,10 +600,11 @@ func TestORM_SelectIndexedLogsByTxHash(t *testing.T) { func TestORM_DataWords(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) o1 := th.ORM + ctx := testutils.Context(t) eventSig := common.HexToHash("0x1599") addr := common.HexToAddress("0x1234") - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1"), 1, time.Now(), 0)) - require.NoError(t, o1.InsertLogs([]logpoller.Log{ + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1"), 1, time.Now(), 0)) + require.NoError(t, o1.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: ubig.New(th.ChainID), LogIndex: int64(0), @@ -625,33 +630,33 @@ func TestORM_DataWords(t *testing.T) { }, })) // Outside range should fail. - lgs, err := o1.SelectLogsDataWordRange(addr, eventSig, 0, logpoller.EvmWord(2), logpoller.EvmWord(2), 0) + lgs, err := o1.SelectLogsDataWordRange(ctx, addr, eventSig, 0, logpoller.EvmWord(2), logpoller.EvmWord(2), 0) require.NoError(t, err) - assert.Equal(t, 0, len(lgs)) + require.Equal(t, 0, len(lgs)) // Range including log should succeed - lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(2), 0) + lgs, err = o1.SelectLogsDataWordRange(ctx, addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(2), 0) require.NoError(t, err) - assert.Equal(t, 1, len(lgs)) + require.Equal(t, 1, len(lgs)) // Range only covering log should succeed - lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(1), 0) + lgs, err = o1.SelectLogsDataWordRange(ctx, addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(1), 0) require.NoError(t, err) - assert.Equal(t, 1, len(lgs)) + require.Equal(t, 1, len(lgs)) // Cannot query for unconfirmed second log. - lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) + lgs, err = o1.SelectLogsDataWordRange(ctx, addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) require.NoError(t, err) - assert.Equal(t, 0, len(lgs)) + require.Equal(t, 0, len(lgs)) // Confirm it, then can query. - require.NoError(t, o1.InsertBlock(common.HexToHash("0x2"), 2, time.Now(), 0)) - lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x2"), 2, time.Now(), 0)) + lgs, err = o1.SelectLogsDataWordRange(ctx, addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) require.NoError(t, err) - assert.Equal(t, 1, len(lgs)) - assert.Equal(t, lgs[0].Data, append(logpoller.EvmWord(2).Bytes(), logpoller.EvmWord(3).Bytes()...)) + require.Equal(t, 1, len(lgs)) + require.Equal(t, lgs[0].Data, append(logpoller.EvmWord(2).Bytes(), logpoller.EvmWord(3).Bytes()...)) // Check greater than 1 yields both logs. - lgs, err = o1.SelectLogsDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), 0) + lgs, err = o1.SelectLogsDataWordGreaterThan(ctx, addr, eventSig, 0, logpoller.EvmWord(1), 0) require.NoError(t, err) assert.Equal(t, 2, len(lgs)) } @@ -659,6 +664,7 @@ func TestORM_DataWords(t *testing.T) { func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) o1 := th.ORM + ctx := testutils.Context(t) // Insert logs on different topics, should be able to read them // back using SelectLogsWithSigs and specifying @@ -734,10 +740,10 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { Data: []byte("hello6"), }, } - require.NoError(t, o1.InsertLogs(inputLogs)) + require.NoError(t, o1.InsertLogs(ctx, inputLogs)) startBlock, endBlock := int64(10), int64(15) - logs, err := o1.SelectLogsWithSigs(startBlock, endBlock, sourceAddr, []common.Hash{ + logs, err := o1.SelectLogsWithSigs(ctx, startBlock, endBlock, sourceAddr, []common.Hash{ topic, topic2, }) @@ -753,35 +759,37 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { func TestORM_DeleteBlocksBefore(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) o1 := th.ORM - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 1, time.Now(), 0)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1235"), 2, time.Now(), 0)) - require.NoError(t, o1.DeleteBlocksBefore(1)) + ctx := testutils.Context(t) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1234"), 1, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1235"), 2, time.Now(), 0)) + require.NoError(t, o1.DeleteBlocksBefore(ctx, 1)) // 1 should be gone. - _, err := o1.SelectBlockByNumber(1) + _, err := o1.SelectBlockByNumber(ctx, 1) require.Equal(t, err, sql.ErrNoRows) - b, err := o1.SelectBlockByNumber(2) + b, err := o1.SelectBlockByNumber(ctx, 2) require.NoError(t, err) assert.Equal(t, int64(2), b.BlockNumber) // Clear multiple - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1236"), 3, time.Now(), 0)) - require.NoError(t, o1.InsertBlock(common.HexToHash("0x1237"), 4, time.Now(), 0)) - require.NoError(t, o1.DeleteBlocksBefore(3)) - _, err = o1.SelectBlockByNumber(2) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1236"), 3, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1237"), 4, time.Now(), 0)) + require.NoError(t, o1.DeleteBlocksBefore(ctx, 3)) + _, err = o1.SelectBlockByNumber(ctx, 2) require.Equal(t, err, sql.ErrNoRows) - _, err = o1.SelectBlockByNumber(3) + _, err = o1.SelectBlockByNumber(ctx, 3) require.Equal(t, err, sql.ErrNoRows) } func TestLogPoller_Logs(t *testing.T) { t.Parallel() th := SetupTH(t, false, 2, 3, 2, 1000) + ctx := testutils.Context(t) event1 := EmitterABI.Events["Log1"].ID event2 := EmitterABI.Events["Log2"].ID address1 := common.HexToAddress("0x2ab9a2Dc53736b361b72d900CdF9F78F9406fbbb") address2 := common.HexToAddress("0x6E225058950f237371261C985Db6bDe26df2200E") // Block 1-3 - require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{ + require.NoError(t, th.ORM.InsertLogs(ctx, []logpoller.Log{ GenLog(th.ChainID, 1, 1, "0x3", event1[:], address1), GenLog(th.ChainID, 2, 1, "0x3", event2[:], address2), GenLog(th.ChainID, 1, 2, "0x4", event1[:], address2), @@ -791,7 +799,7 @@ func TestLogPoller_Logs(t *testing.T) { })) // Select for all Addresses - lgs, err := th.ORM.SelectLogsByBlockRange(1, 3) + lgs, err := th.ORM.SelectLogsByBlockRange(ctx, 1, 3) require.NoError(t, err) require.Equal(t, 6, len(lgs)) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000003", lgs[0].BlockHash.String()) @@ -802,7 +810,7 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000005", lgs[5].BlockHash.String()) // Filter by Address and topic - lgs, err = th.ORM.SelectLogs(1, 3, address1, event1) + lgs, err = th.ORM.SelectLogs(ctx, 1, 3, address1, event1) require.NoError(t, err) require.Equal(t, 2, len(lgs)) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000003", lgs[0].BlockHash.String()) @@ -812,7 +820,7 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, address1, lgs[1].Address) // Filter by block - lgs, err = th.ORM.SelectLogs(2, 2, address2, event1) + lgs, err = th.ORM.SelectLogs(ctx, 2, 2, address2, event1) require.NoError(t, err) require.Equal(t, 1, len(lgs)) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000004", lgs[0].BlockHash.String()) @@ -824,6 +832,7 @@ func TestLogPoller_Logs(t *testing.T) { func BenchmarkLogs(b *testing.B) { th := SetupTH(b, false, 2, 3, 2, 1000) o := th.ORM + ctx := testutils.Context(b) var lgs []logpoller.Log addr := common.HexToAddress("0x1234") for i := 0; i < 10_000; i++ { @@ -839,17 +848,20 @@ func BenchmarkLogs(b *testing.B) { Data: common.HexToHash(fmt.Sprintf("0x%d", i)).Bytes(), }) } - require.NoError(b, o.InsertLogs(lgs)) + require.NoError(b, o.InsertLogs(ctx, lgs)) b.ResetTimer() for n := 0; n < b.N; n++ { - _, err := o.SelectLogsDataWordRange(addr, EmitterABI.Events["Log1"].ID, 0, logpoller.EvmWord(8000), logpoller.EvmWord(8002), 0) + lgs, err := o.SelectLogsDataWordRange(ctx, addr, EmitterABI.Events["Log1"].ID, 0, logpoller.EvmWord(8000), logpoller.EvmWord(8002), 0) require.NoError(b, err) + // TODO: Why is SelectLogsDataWordRange not returning any logs?! + fmt.Println("len logs:", len(lgs)) } } func TestSelectLogsWithSigsExcluding(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) orm := th.ORM + ctx := testutils.Context(t) addressA := common.HexToAddress("0x11111") addressB := common.HexToAddress("0x22222") addressC := common.HexToAddress("0x33333") @@ -865,7 +877,7 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { topicD := common.HexToHash("0x000d") //Insert two logs that mimics an oracle request from 2 different addresses (matching will be on topic index 1) - require.NoError(t, orm.InsertLogs([]logpoller.Log{ + require.NoError(t, orm.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: (*ubig.Big)(th.ChainID), LogIndex: 1, @@ -891,22 +903,22 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { Data: []byte("requestID-B1"), }, })) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x1"), 1, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x1"), 1, time.Now(), 0)) //Get any requestSigA from addressA that do not have a equivalent responseSigA - logs, err := orm.SelectIndexedLogsWithSigsExcluding(requestSigA, responseSigA, 1, addressA, 0, 3, 0) + logs, err := orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigA, responseSigA, 1, addressA, 0, 3, 0) require.NoError(t, err) require.Len(t, logs, 1) require.Equal(t, logs[0].Data, []byte("requestID-A1")) //Get any requestSigB from addressB that do not have a equivalent responseSigB - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 1, addressB, 0, 3, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 1, addressB, 0, 3, 0) require.NoError(t, err) require.Len(t, logs, 1) require.Equal(t, logs[0].Data, []byte("requestID-B1")) //Insert a log that mimics response for requestID-A1 - require.NoError(t, orm.InsertLogs([]logpoller.Log{ + require.NoError(t, orm.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: (*ubig.Big)(th.ChainID), LogIndex: 3, @@ -920,21 +932,21 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { Data: []byte("responseID-A1"), }, })) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x2"), 2, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x2"), 2, time.Now(), 0)) //Should return nothing as requestID-A1 has been fulfilled - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigA, responseSigA, 1, addressA, 0, 3, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigA, responseSigA, 1, addressA, 0, 3, 0) require.NoError(t, err) require.Len(t, logs, 0) //requestID-B1 should still be unfulfilled - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 1, addressB, 0, 3, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 1, addressB, 0, 3, 0) require.NoError(t, err) require.Len(t, logs, 1) require.Equal(t, logs[0].Data, []byte("requestID-B1")) //Insert 3 request from addressC (matching will be on topic index 3) - require.NoError(t, orm.InsertLogs([]logpoller.Log{ + require.NoError(t, orm.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: (*ubig.Big)(th.ChainID), LogIndex: 5, @@ -971,10 +983,10 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { Data: []byte("requestID-C3"), }, })) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x3"), 3, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x3"), 3, time.Now(), 0)) //Get all unfulfilled requests from addressC, match on topic index 3 - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 3, addressC, 0, 4, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 3, addressC, 0, 4, 0) require.NoError(t, err) require.Len(t, logs, 3) require.Equal(t, logs[0].Data, []byte("requestID-C1")) @@ -982,7 +994,7 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { require.Equal(t, logs[2].Data, []byte("requestID-C3")) //Fulfill requestID-C2 - require.NoError(t, orm.InsertLogs([]logpoller.Log{ + require.NoError(t, orm.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: (*ubig.Big)(th.ChainID), LogIndex: 8, @@ -998,14 +1010,14 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { })) //Verify that requestID-C2 is now fulfilled (not returned) - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 3, addressC, 0, 4, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 3, addressC, 0, 4, 0) require.NoError(t, err) require.Len(t, logs, 2) require.Equal(t, logs[0].Data, []byte("requestID-C1")) require.Equal(t, logs[1].Data, []byte("requestID-C3")) //Fulfill requestID-C3 - require.NoError(t, orm.InsertLogs([]logpoller.Log{ + require.NoError(t, orm.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: (*ubig.Big)(th.ChainID), LogIndex: 9, @@ -1021,26 +1033,26 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { })) //Verify that requestID-C3 is now fulfilled (not returned) - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 3, addressC, 0, 4, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 3, addressC, 0, 4, 0) require.NoError(t, err) require.Len(t, logs, 1) require.Equal(t, logs[0].Data, []byte("requestID-C1")) //Should return no logs as the number of confirmations is not satisfied - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 3, addressC, 0, 4, 3) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 3, addressC, 0, 4, 3) require.NoError(t, err) require.Len(t, logs, 0) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x4"), 4, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x5"), 5, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x6"), 6, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x7"), 7, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x8"), 8, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x9"), 9, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x10"), 10, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x4"), 4, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x5"), 5, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x6"), 6, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x7"), 7, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x8"), 8, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x9"), 9, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x10"), 10, time.Now(), 0)) //Fulfill requestID-C3 - require.NoError(t, orm.InsertLogs([]logpoller.Log{ + require.NoError(t, orm.InsertLogs(ctx, []logpoller.Log{ { EvmChainId: (*ubig.Big)(th.ChainID), LogIndex: 10, @@ -1056,57 +1068,58 @@ func TestSelectLogsWithSigsExcluding(t *testing.T) { })) //All logs for addressC should be fulfilled, query should return 0 logs - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 3, addressC, 0, 10, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 3, addressC, 0, 10, 0) require.NoError(t, err) require.Len(t, logs, 0) //Should return 1 log as it does not satisfy the required number of confirmations - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 3, addressC, 0, 10, 3) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 3, addressC, 0, 10, 3) require.NoError(t, err) require.Len(t, logs, 1) require.Equal(t, logs[0].Data, []byte("requestID-C1")) //Insert 3 more blocks so that the requestID-C1 has enough confirmations - require.NoError(t, orm.InsertBlock(common.HexToHash("0x11"), 11, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x12"), 12, time.Now(), 0)) - require.NoError(t, orm.InsertBlock(common.HexToHash("0x13"), 13, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x11"), 11, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x12"), 12, time.Now(), 0)) + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x13"), 13, time.Now(), 0)) - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 3, addressC, 0, 10, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 3, addressC, 0, 10, 0) require.NoError(t, err) require.Len(t, logs, 0) //AddressB should still have an unfulfilled log (requestID-B1) - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 1, addressB, 0, 3, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 1, addressB, 0, 3, 0) require.NoError(t, err) require.Len(t, logs, 1) require.Equal(t, logs[0].Data, []byte("requestID-B1")) //Should return requestID-A1 as the fulfillment event is out of the block range - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigA, responseSigA, 1, addressA, 0, 1, 10) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigA, responseSigA, 1, addressA, 0, 1, 10) require.NoError(t, err) require.Len(t, logs, 1) require.Equal(t, logs[0].Data, []byte("requestID-A1")) //Should return nothing as requestID-B1 is before the block range - logs, err = orm.SelectIndexedLogsWithSigsExcluding(requestSigB, responseSigB, 1, addressB, 2, 13, 0) + logs, err = orm.SelectIndexedLogsWithSigsExcluding(ctx, requestSigB, responseSigB, 1, addressB, 2, 13, 0) require.NoError(t, err) require.Len(t, logs, 0) } func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) + ctx := testutils.Context(t) event1 := EmitterABI.Events["Log1"].ID event2 := EmitterABI.Events["Log2"].ID address1 := utils.RandomAddress() address2 := utils.RandomAddress() - require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{ + require.NoError(t, th.ORM.InsertLogs(ctx, []logpoller.Log{ GenLog(th.ChainID, 1, 1, utils.RandomAddress().String(), event1[:], address1), GenLog(th.ChainID, 2, 1, utils.RandomAddress().String(), event2[:], address2), GenLog(th.ChainID, 2, 2, utils.RandomAddress().String(), event2[:], address2), GenLog(th.ChainID, 2, 3, utils.RandomAddress().String(), event2[:], address2), })) - require.NoError(t, th.ORM.InsertBlock(utils.RandomHash(), 3, time.Now(), 1)) + require.NoError(t, th.ORM.InsertBlock(ctx, utils.RandomHash(), 3, time.Now(), 1)) tests := []struct { name string @@ -1183,7 +1196,7 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - blockNumber, err := th.ORM.SelectLatestBlockByEventSigsAddrsWithConfs(tt.fromBlock, tt.events, tt.addrs, tt.confs) + blockNumber, err := th.ORM.SelectLatestBlockByEventSigsAddrsWithConfs(ctx, tt.fromBlock, tt.events, tt.addrs, tt.confs) require.NoError(t, err) assert.Equal(t, tt.expectedBlockNumber, blockNumber) }) @@ -1192,6 +1205,7 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { func TestSelectLogsCreatedAfter(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) + ctx := testutils.Context(t) event := EmitterABI.Events["Log1"].ID address := utils.RandomAddress() @@ -1199,15 +1213,15 @@ func TestSelectLogsCreatedAfter(t *testing.T) { block2ts := time.Date(2020, 1, 1, 12, 12, 12, 0, time.UTC) block3ts := time.Date(2030, 1, 1, 12, 12, 12, 0, time.UTC) - require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{ + require.NoError(t, th.ORM.InsertLogs(ctx, []logpoller.Log{ GenLogWithTimestamp(th.ChainID, 1, 1, utils.RandomAddress().String(), event[:], address, block1ts), GenLogWithTimestamp(th.ChainID, 1, 2, utils.RandomAddress().String(), event[:], address, block2ts), GenLogWithTimestamp(th.ChainID, 2, 2, utils.RandomAddress().String(), event[:], address, block2ts), GenLogWithTimestamp(th.ChainID, 1, 3, utils.RandomAddress().String(), event[:], address, block3ts), })) - require.NoError(t, th.ORM.InsertBlock(utils.RandomHash(), 1, block1ts, 0)) - require.NoError(t, th.ORM.InsertBlock(utils.RandomHash(), 2, block2ts, 1)) - require.NoError(t, th.ORM.InsertBlock(utils.RandomHash(), 3, block3ts, 2)) + require.NoError(t, th.ORM.InsertBlock(ctx, utils.RandomHash(), 1, block1ts, 0)) + require.NoError(t, th.ORM.InsertBlock(ctx, utils.RandomHash(), 2, block2ts, 1)) + require.NoError(t, th.ORM.InsertBlock(ctx, utils.RandomHash(), 3, block3ts, 2)) type expectedLog struct { block int64 @@ -1271,7 +1285,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) { } for _, tt := range tests { t.Run("SelectLogsCreatedAfter"+tt.name, func(t *testing.T) { - logs, err := th.ORM.SelectLogsCreatedAfter(address, event, tt.after, tt.confs) + logs, err := th.ORM.SelectLogsCreatedAfter(ctx, address, event, tt.after, tt.confs) require.NoError(t, err) require.Len(t, logs, len(tt.expectedLogs)) @@ -1282,7 +1296,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) { }) t.Run("SelectIndexedLogsCreatedAfter"+tt.name, func(t *testing.T) { - logs, err := th.ORM.SelectIndexedLogsCreatedAfter(address, event, 1, []common.Hash{event}, tt.after, tt.confs) + logs, err := th.ORM.SelectIndexedLogsCreatedAfter(ctx, address, event, 1, []common.Hash{event}, tt.after, tt.confs) require.NoError(t, err) require.Len(t, logs, len(tt.expectedLogs)) @@ -1296,28 +1310,29 @@ func TestSelectLogsCreatedAfter(t *testing.T) { func TestNestedLogPollerBlocksQuery(t *testing.T) { th := SetupTH(t, false, 2, 3, 2, 1000) + ctx := testutils.Context(t) event := EmitterABI.Events["Log1"].ID address := utils.RandomAddress() - require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{ + require.NoError(t, th.ORM.InsertLogs(ctx, []logpoller.Log{ GenLog(th.ChainID, 1, 8, utils.RandomAddress().String(), event[:], address), })) // Empty logs when block are not persisted - logs, err := th.ORM.SelectIndexedLogs(address, event, 1, []common.Hash{event}, logpoller.Unconfirmed) + logs, err := th.ORM.SelectIndexedLogs(ctx, address, event, 1, []common.Hash{event}, logpoller.Unconfirmed) require.NoError(t, err) require.Len(t, logs, 0) // Persist block - require.NoError(t, th.ORM.InsertBlock(utils.RandomHash(), 10, time.Now(), 0)) + require.NoError(t, th.ORM.InsertBlock(ctx, utils.RandomHash(), 10, time.Now(), 0)) // Check if query actually works well with provided dataset - logs, err = th.ORM.SelectIndexedLogs(address, event, 1, []common.Hash{event}, logpoller.Unconfirmed) + logs, err = th.ORM.SelectIndexedLogs(ctx, address, event, 1, []common.Hash{event}, logpoller.Unconfirmed) require.NoError(t, err) require.Len(t, logs, 1) // Empty logs when number of confirmations is too deep - logs, err = th.ORM.SelectIndexedLogs(address, event, 1, []common.Hash{event}, logpoller.Confirmations(4)) + logs, err = th.ORM.SelectIndexedLogs(ctx, address, event, 1, []common.Hash{event}, logpoller.Confirmations(4)) require.NoError(t, err) require.Len(t, logs, 0) } @@ -1326,12 +1341,13 @@ func TestInsertLogsWithBlock(t *testing.T) { chainID := testutils.NewRandomEVMChainID() event := utils.RandomBytes32() address := utils.RandomAddress() + ctx := testutils.Context(t) // We need full db here, because we want to test transaction rollbacks. // Using pgtest.NewSqlxDB(t) will run all tests in TXs which is not desired for this type of test // (inner tx rollback will rollback outer tx, blocking rest of execution) _, db := heavyweight.FullTestDBV2(t, nil) - o := logpoller.NewORM(chainID, db, logger.Test(t), pgtest.NewQConfig(true)) + o := logpoller.NewORM(chainID, db, logger.Test(t)) correctLog := GenLog(chainID, 1, 1, utils.RandomAddress().String(), event[:], address) invalidLog := GenLog(chainID, -10, -10, utils.RandomAddress().String(), event[:], address) @@ -1373,11 +1389,11 @@ func TestInsertLogsWithBlock(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // clean all logs and blocks between test cases - defer func() { _ = o.DeleteLogsAndBlocksAfter(0) }() - insertError := o.InsertLogsWithBlock(tt.logs, tt.block) + defer func() { _ = o.DeleteLogsAndBlocksAfter(ctx, 0) }() + insertError := o.InsertLogsWithBlock(ctx, tt.logs, tt.block) - logs, logsErr := o.SelectLogs(0, math.MaxInt, address, event) - block, blockErr := o.SelectLatestBlock() + logs, logsErr := o.SelectLogs(ctx, 0, math.MaxInt, address, event) + block, blockErr := o.SelectLatestBlock(ctx) if tt.shouldRollback { assert.Error(t, insertError) @@ -1404,10 +1420,11 @@ func TestInsertLogsInTx(t *testing.T) { event := utils.RandomBytes32() address := utils.RandomAddress() maxLogsSize := 9000 + ctx := testutils.Context(t) // We need full db here, because we want to test transaction rollbacks. _, db := heavyweight.FullTestDBV2(t, nil) - o := logpoller.NewORM(chainID, db, logger.Test(t), pgtest.NewQConfig(true)) + o := logpoller.NewORM(chainID, db, logger.Test(t)) logs := make([]logpoller.Log, maxLogsSize, maxLogsSize+1) for i := 0; i < maxLogsSize; i++ { @@ -1437,8 +1454,8 @@ func TestInsertLogsInTx(t *testing.T) { // clean all logs and blocks between test cases defer func() { _, _ = db.Exec("truncate evm.logs") }() - insertErr := o.InsertLogs(tt.logs) - logsFromDb, err := o.SelectLogs(0, math.MaxInt, address, event) + insertErr := o.InsertLogs(ctx, tt.logs) + logsFromDb, err := o.SelectLogs(ctx, 0, math.MaxInt, address, event) assert.NoError(t, err) if tt.shouldRollback { @@ -1453,6 +1470,7 @@ func TestInsertLogsInTx(t *testing.T) { } func TestSelectLogsDataWordBetween(t *testing.T) { + ctx := testutils.Context(t) address := utils.RandomAddress() eventSig := utils.RandomBytes32() th := SetupTH(t, false, 2, 3, 2, 1000) @@ -1465,7 +1483,7 @@ func TestSelectLogsDataWordBetween(t *testing.T) { secondLogData = append(secondLogData, logpoller.EvmWord(5).Bytes()...) secondLogData = append(secondLogData, logpoller.EvmWord(20).Bytes()...) - err := th.ORM.InsertLogsWithBlock( + err := th.ORM.InsertLogsWithBlock(ctx, []logpoller.Log{ GenLogWithData(th.ChainID, address, eventSig, 1, 1, firstLogData), GenLogWithData(th.ChainID, address, eventSig, 2, 2, secondLogData), @@ -1503,7 +1521,7 @@ func TestSelectLogsDataWordBetween(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - logs, err1 := th.ORM.SelectLogsDataWordBetween(address, eventSig, 0, 1, logpoller.EvmWord(tt.wordValue), logpoller.Unconfirmed) + logs, err1 := th.ORM.SelectLogsDataWordBetween(ctx, address, eventSig, 0, 1, logpoller.EvmWord(tt.wordValue), logpoller.Unconfirmed) assert.NoError(t, err1) assert.Len(t, logs, len(tt.expectedLogs)) @@ -1517,7 +1535,8 @@ func TestSelectLogsDataWordBetween(t *testing.T) { func Benchmark_LogsDataWordBetween(b *testing.B) { chainId := big.NewInt(137) _, db := heavyweight.FullTestDBV2(b, nil) - o := logpoller.NewORM(chainId, db, logger.Test(b), pgtest.NewQConfig(false)) + o := logpoller.NewORM(chainId, db, logger.Test(b)) + ctx := testutils.Context(b) numberOfReports := 100_000 numberOfMessagesPerReport := 256 @@ -1547,13 +1566,13 @@ func Benchmark_LogsDataWordBetween(b *testing.B) { CreatedAt: time.Now(), }) } - require.NoError(b, o.InsertBlock(utils.RandomHash(), int64(numberOfReports*numberOfMessagesPerReport), time.Now(), int64(numberOfReports*numberOfMessagesPerReport))) - require.NoError(b, o.InsertLogs(dbLogs)) + require.NoError(b, o.InsertBlock(ctx, utils.RandomHash(), int64(numberOfReports*numberOfMessagesPerReport), time.Now(), int64(numberOfReports*numberOfMessagesPerReport))) + require.NoError(b, o.InsertLogs(ctx, dbLogs)) b.ResetTimer() for i := 0; i < b.N; i++ { - logs, err := o.SelectLogsDataWordBetween( + logs, err := o.SelectLogsDataWordBetween(ctx, commitStoreAddress, commitReportAccepted, 2, diff --git a/core/chains/evm/logpoller/query.go b/core/chains/evm/logpoller/query.go deleted file mode 100644 index a37b15b2b2d..00000000000 --- a/core/chains/evm/logpoller/query.go +++ /dev/null @@ -1,144 +0,0 @@ -package logpoller - -import ( - "errors" - "fmt" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/lib/pq" - - ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" -) - -type bytesProducer interface { - Bytes() []byte -} - -func concatBytes[T bytesProducer](byteSlice []T) pq.ByteaArray { - var output [][]byte - for _, b := range byteSlice { - output = append(output, b.Bytes()) - } - return output -} - -// queryArgs is a helper for building the arguments to a postgres query created by DbORM -// Besides the convenience methods, it also keeps track of arguments validation and sanitization. -type queryArgs struct { - args map[string]interface{} - err []error -} - -func newQueryArgs(chainId *big.Int) *queryArgs { - return &queryArgs{ - args: map[string]interface{}{ - "evm_chain_id": ubig.New(chainId), - }, - err: []error{}, - } -} - -func newQueryArgsForEvent(chainId *big.Int, address common.Address, eventSig common.Hash) *queryArgs { - return newQueryArgs(chainId). - withAddress(address). - withEventSig(eventSig) -} - -func (q *queryArgs) withEventSig(eventSig common.Hash) *queryArgs { - return q.withCustomHashArg("event_sig", eventSig) -} - -func (q *queryArgs) withEventSigArray(eventSigs []common.Hash) *queryArgs { - return q.withCustomArg("event_sig_array", concatBytes(eventSigs)) -} - -func (q *queryArgs) withAddress(address common.Address) *queryArgs { - return q.withCustomArg("address", address) -} - -func (q *queryArgs) withAddressArray(addresses []common.Address) *queryArgs { - return q.withCustomArg("address_array", concatBytes(addresses)) -} - -func (q *queryArgs) withStartBlock(startBlock int64) *queryArgs { - return q.withCustomArg("start_block", startBlock) -} - -func (q *queryArgs) withEndBlock(endBlock int64) *queryArgs { - return q.withCustomArg("end_block", endBlock) -} - -func (q *queryArgs) withWordIndex(wordIndex int) *queryArgs { - return q.withCustomArg("word_index", wordIndex) -} - -func (q *queryArgs) withWordValueMin(wordValueMin common.Hash) *queryArgs { - return q.withCustomHashArg("word_value_min", wordValueMin) -} - -func (q *queryArgs) withWordValueMax(wordValueMax common.Hash) *queryArgs { - return q.withCustomHashArg("word_value_max", wordValueMax) -} - -func (q *queryArgs) withWordIndexMin(wordIndex int) *queryArgs { - return q.withCustomArg("word_index_min", wordIndex) -} - -func (q *queryArgs) withWordIndexMax(wordIndex int) *queryArgs { - return q.withCustomArg("word_index_max", wordIndex) -} - -func (q *queryArgs) withWordValue(wordValue common.Hash) *queryArgs { - return q.withCustomHashArg("word_value", wordValue) -} - -func (q *queryArgs) withConfs(confs Confirmations) *queryArgs { - return q.withCustomArg("confs", confs) -} - -func (q *queryArgs) withTopicIndex(index int) *queryArgs { - // Only topicIndex 1 through 3 is valid. 0 is the event sig and only 4 total topics are allowed - if !(index == 1 || index == 2 || index == 3) { - q.err = append(q.err, fmt.Errorf("invalid index for topic: %d", index)) - } - // Add 1 since postgresql arrays are 1-indexed. - return q.withCustomArg("topic_index", index+1) -} - -func (q *queryArgs) withTopicValueMin(valueMin common.Hash) *queryArgs { - return q.withCustomHashArg("topic_value_min", valueMin) -} - -func (q *queryArgs) withTopicValueMax(valueMax common.Hash) *queryArgs { - return q.withCustomHashArg("topic_value_max", valueMax) -} - -func (q *queryArgs) withTopicValues(values []common.Hash) *queryArgs { - return q.withCustomArg("topic_values", concatBytes(values)) -} - -func (q *queryArgs) withBlockTimestampAfter(after time.Time) *queryArgs { - return q.withCustomArg("block_timestamp_after", after) -} - -func (q *queryArgs) withTxHash(hash common.Hash) *queryArgs { - return q.withCustomHashArg("tx_hash", hash) -} - -func (q *queryArgs) withCustomHashArg(name string, arg common.Hash) *queryArgs { - return q.withCustomArg(name, arg.Bytes()) -} - -func (q *queryArgs) withCustomArg(name string, arg any) *queryArgs { - q.args[name] = arg - return q -} - -func (q *queryArgs) toArgs() (map[string]interface{}, error) { - if len(q.err) > 0 { - return nil, errors.Join(q.err...) - } - return q.args, nil -} diff --git a/core/chains/evm/logpoller/query_test.go b/core/chains/evm/logpoller/query_test.go deleted file mode 100644 index 70ace713228..00000000000 --- a/core/chains/evm/logpoller/query_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package logpoller - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/lib/pq" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" -) - -func Test_QueryArgs(t *testing.T) { - tests := []struct { - name string - queryArgs *queryArgs - want map[string]interface{} - wantErr bool - }{ - { - name: "valid arguments", - queryArgs: newQueryArgs(big.NewInt(20)).withAddress(utils.ZeroAddress), - want: map[string]interface{}{ - "evm_chain_id": ubig.NewI(20), - "address": utils.ZeroAddress, - }, - }, - { - name: "invalid topic index", - queryArgs: newQueryArgs(big.NewInt(20)).withTopicIndex(0), - wantErr: true, - }, - { - name: "custom argument", - queryArgs: newEmptyArgs().withCustomArg("arg", "value"), - want: map[string]interface{}{ - "arg": "value", - }, - }, - { - name: "hash converted to bytes", - queryArgs: newEmptyArgs().withCustomHashArg("hash", common.Hash{}), - want: map[string]interface{}{ - "hash": make([]byte, 32), - }, - }, - { - name: "hash array converted to bytes array", - queryArgs: newEmptyArgs().withEventSigArray([]common.Hash{{}, {}}), - want: map[string]interface{}{ - "event_sig_array": pq.ByteaArray{make([]byte, 32), make([]byte, 32)}, - }, - }, - { - name: "topic index incremented", - queryArgs: newEmptyArgs().withTopicIndex(2), - want: map[string]interface{}{ - "topic_index": 3, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - args, err := tt.queryArgs.toArgs() - if tt.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - require.Equal(t, tt.want, args) - } - }) - } -} - -func newEmptyArgs() *queryArgs { - return &queryArgs{ - args: map[string]interface{}{}, - err: []error{}, - } -} diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 3f4b4563cbb..2d1779d5559 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -50,7 +50,7 @@ import ( func makeTestEvmTxm( t *testing.T, db *sqlx.DB, ethClient evmclient.Client, estimator gas.EvmFeeEstimator, ccfg txmgr.ChainConfig, fcfg txmgr.FeeConfig, txConfig evmconfig.Transactions, dbConfig txmgr.DatabaseConfig, listenerConfig txmgr.ListenerConfig, keyStore keystore.Eth) (txmgr.TxManager, error) { lggr := logger.Test(t) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) // logic for building components (from evm/evm_txm.go) ------- lggr.Infow("Initializing EVM transaction manager", diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 92936299cdb..f806ae3084f 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -230,7 +230,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod if !cfg.EVMRPCEnabled() { headTracker = headtracker.NullTracker } else if opts.GenHeadTracker == nil { - orm := headtracker.NewORM(db, l, cfg.Database(), *chainID) + orm := headtracker.NewORM(*chainID, db) headSaver = headtracker.NewHeadSaver(l, orm, cfg.EVM(), cfg.EVM().HeadTracker()) headTracker = headtracker.NewHeadTracker(l, client, cfg.EVM(), cfg.EVM().HeadTracker(), headBroadcaster, headSaver, opts.MailMon) } else { @@ -243,7 +243,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod logPoller = opts.GenLogPoller(chainID) } else { logPoller = logpoller.NewLogPoller( - logpoller.NewObservedORM(chainID, db, l, cfg.Database()), + logpoller.NewObservedORM(chainID, db, l), client, l, cfg.EVM().LogPollInterval(), diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go index 804dbe2d088..1b933c79b94 100644 --- a/core/internal/cltest/factories.go +++ b/core/internal/cltest/factories.go @@ -314,7 +314,7 @@ func MustGenerateRandomKeyState(_ testing.TB) ethkey.State { func MustInsertHead(t *testing.T, db *sqlx.DB, cfg pg.QConfig, number int64) evmtypes.Head { h := evmtypes.NewHead(big.NewInt(number), evmutils.NewHash(), evmutils.NewHash(), 0, ubig.New(&FixtureChainID)) - horm := headtracker.NewORM(db, logger.TestLogger(t), cfg, FixtureChainID) + horm := headtracker.NewORM(FixtureChainID, db) err := horm.IdempotentInsertHead(testutils.Context(t), &h) require.NoError(t, err) diff --git a/core/services/blockhashstore/coordinators.go b/core/services/blockhashstore/coordinators.go index 4cb58bab6fd..7e4a0c5dc02 100644 --- a/core/services/blockhashstore/coordinators.go +++ b/core/services/blockhashstore/coordinators.go @@ -12,7 +12,6 @@ import ( v1 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" v2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" v2plus "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -72,7 +71,7 @@ type V1Coordinator struct { // NewV1Coordinator creates a new V1Coordinator from the given contract. func NewV1Coordinator(c v1.VRFCoordinatorInterface, lp logpoller.LogPoller) (*V1Coordinator, error) { - err := lp.RegisterFilter(logpoller.Filter{ + err := lp.RegisterFilter(context.Background(), logpoller.Filter{ Name: logpoller.FilterName("VRFv1CoordinatorFeeder", c.Address()), EventSigs: []common.Hash{ v1.VRFCoordinatorRandomnessRequest{}.Topic(), @@ -92,13 +91,13 @@ func (v *V1Coordinator) Requests( toBlock uint64, ) ([]Event, error) { logs, err := v.lp.LogsWithSigs( + ctx, int64(fromBlock), int64(toBlock), []common.Hash{ v1.VRFCoordinatorRandomnessRequest{}.Topic(), }, - v.c.Address(), - pg.WithParentCtx(ctx)) + v.c.Address()) if err != nil { return nil, errors.Wrap(err, "filter v1 requests") } @@ -121,19 +120,19 @@ func (v *V1Coordinator) Requests( // Fulfillments satisfies the Coordinator interface. func (v *V1Coordinator) Fulfillments(ctx context.Context, fromBlock uint64) ([]Event, error) { - toBlock, err := v.lp.LatestBlock(pg.WithParentCtx(ctx)) + toBlock, err := v.lp.LatestBlock(ctx) if err != nil { return nil, errors.Wrap(err, "fetching latest block") } logs, err := v.lp.LogsWithSigs( + ctx, int64(fromBlock), toBlock.BlockNumber, []common.Hash{ v1.VRFCoordinatorRandomnessRequestFulfilled{}.Topic(), }, - v.c.Address(), - pg.WithParentCtx(ctx)) + v.c.Address()) if err != nil { return nil, errors.Wrap(err, "filter v1 fulfillments") } @@ -161,7 +160,7 @@ type V2Coordinator struct { // NewV2Coordinator creates a new V2Coordinator from the given contract. func NewV2Coordinator(c v2.VRFCoordinatorV2Interface, lp logpoller.LogPoller) (*V2Coordinator, error) { - err := lp.RegisterFilter(logpoller.Filter{ + err := lp.RegisterFilter(context.Background(), logpoller.Filter{ Name: logpoller.FilterName("VRFv2CoordinatorFeeder", c.Address()), EventSigs: []common.Hash{ v2.VRFCoordinatorV2RandomWordsRequested{}.Topic(), @@ -183,13 +182,13 @@ func (v *V2Coordinator) Requests( toBlock uint64, ) ([]Event, error) { logs, err := v.lp.LogsWithSigs( + ctx, int64(fromBlock), int64(toBlock), []common.Hash{ v2.VRFCoordinatorV2RandomWordsRequested{}.Topic(), }, - v.c.Address(), - pg.WithParentCtx(ctx)) + v.c.Address()) if err != nil { return nil, errors.Wrap(err, "filter v2 requests") } @@ -212,19 +211,19 @@ func (v *V2Coordinator) Requests( // Fulfillments satisfies the Coordinator interface. func (v *V2Coordinator) Fulfillments(ctx context.Context, fromBlock uint64) ([]Event, error) { - toBlock, err := v.lp.LatestBlock(pg.WithParentCtx(ctx)) + toBlock, err := v.lp.LatestBlock(ctx) if err != nil { return nil, errors.Wrap(err, "fetching latest block") } logs, err := v.lp.LogsWithSigs( + ctx, int64(fromBlock), toBlock.BlockNumber, []common.Hash{ v2.VRFCoordinatorV2RandomWordsFulfilled{}.Topic(), }, - v.c.Address(), - pg.WithParentCtx(ctx)) + v.c.Address()) if err != nil { return nil, errors.Wrap(err, "filter v2 fulfillments") } @@ -252,7 +251,7 @@ type V2PlusCoordinator struct { // NewV2Coordinator creates a new V2Coordinator from the given contract. func NewV2PlusCoordinator(c v2plus.IVRFCoordinatorV2PlusInternalInterface, lp logpoller.LogPoller) (*V2PlusCoordinator, error) { - err := lp.RegisterFilter(logpoller.Filter{ + err := lp.RegisterFilter(context.Background(), logpoller.Filter{ Name: logpoller.FilterName("VRFv2PlusCoordinatorFeeder", c.Address()), EventSigs: []common.Hash{ v2plus.IVRFCoordinatorV2PlusInternalRandomWordsRequested{}.Topic(), @@ -274,13 +273,13 @@ func (v *V2PlusCoordinator) Requests( toBlock uint64, ) ([]Event, error) { logs, err := v.lp.LogsWithSigs( + ctx, int64(fromBlock), int64(toBlock), []common.Hash{ v2plus.IVRFCoordinatorV2PlusInternalRandomWordsRequested{}.Topic(), }, - v.c.Address(), - pg.WithParentCtx(ctx)) + v.c.Address()) if err != nil { return nil, errors.Wrap(err, "filter v2 requests") } @@ -303,19 +302,19 @@ func (v *V2PlusCoordinator) Requests( // Fulfillments satisfies the Coordinator interface. func (v *V2PlusCoordinator) Fulfillments(ctx context.Context, fromBlock uint64) ([]Event, error) { - toBlock, err := v.lp.LatestBlock(pg.WithParentCtx(ctx)) + toBlock, err := v.lp.LatestBlock(ctx) if err != nil { return nil, errors.Wrap(err, "fetching latest block") } logs, err := v.lp.LogsWithSigs( + ctx, int64(fromBlock), toBlock.BlockNumber, []common.Hash{ v2plus.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled{}.Topic(), }, - v.c.Address(), - pg.WithParentCtx(ctx)) + v.c.Address()) if err != nil { return nil, errors.Wrap(err, "filter v2 fulfillments") } diff --git a/core/services/blockhashstore/delegate.go b/core/services/blockhashstore/delegate.go index d6c27acd0b5..e1fa76f639d 100644 --- a/core/services/blockhashstore/delegate.go +++ b/core/services/blockhashstore/delegate.go @@ -169,7 +169,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { int(jb.BlockhashStoreSpec.LookbackBlocks), jb.BlockhashStoreSpec.HeartbeatPeriod, func(ctx context.Context) (uint64, error) { - head, err := lp.LatestBlock(pg.WithParentCtx(ctx)) + head, err := lp.LatestBlock(ctx) if err != nil { return 0, errors.Wrap(err, "getting chain head") } diff --git a/core/services/blockhashstore/feeder_test.go b/core/services/blockhashstore/feeder_test.go index 3266b7d92ea..fabde77c786 100644 --- a/core/services/blockhashstore/feeder_test.go +++ b/core/services/blockhashstore/feeder_test.go @@ -410,7 +410,7 @@ func (test testCase) testFeederWithLogPollerVRFv1(t *testing.T) { // Instantiate log poller & coordinator. lp := &mocklp.LogPoller{} - lp.On("RegisterFilter", mock.Anything).Return(nil) + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) c, err := solidity_vrf_coordinator_interface.NewVRFCoordinator(coordinatorAddress, nil) require.NoError(t, err) coordinator := &V1Coordinator{ @@ -449,6 +449,7 @@ func (test testCase) testFeederWithLogPollerVRFv1(t *testing.T) { Return(logpoller.LogPollerBlock{BlockNumber: latest}, nil) lp.On( "LogsWithSigs", + mock.Anything, fromBlock, toBlock, []common.Hash{ @@ -458,6 +459,7 @@ func (test testCase) testFeederWithLogPollerVRFv1(t *testing.T) { mock.Anything, ).Return(requestLogs, nil) lp.On( + mock.Anything, "LogsWithSigs", fromBlock, latest, @@ -504,7 +506,7 @@ func (test testCase) testFeederWithLogPollerVRFv2(t *testing.T) { // Instantiate log poller & coordinator. lp := &mocklp.LogPoller{} - lp.On("RegisterFilter", mock.Anything).Return(nil) + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) c, err := vrf_coordinator_v2.NewVRFCoordinatorV2(coordinatorAddress, nil) require.NoError(t, err) coordinator := &V2Coordinator{ @@ -547,6 +549,7 @@ func (test testCase) testFeederWithLogPollerVRFv2(t *testing.T) { Return(logpoller.LogPollerBlock{BlockNumber: latest}, nil) lp.On( "LogsWithSigs", + mock.Anything, fromBlock, toBlock, []common.Hash{ @@ -557,6 +560,7 @@ func (test testCase) testFeederWithLogPollerVRFv2(t *testing.T) { ).Return(requestLogs, nil) lp.On( "LogsWithSigs", + mock.Anything, fromBlock, latest, []common.Hash{ @@ -602,7 +606,7 @@ func (test testCase) testFeederWithLogPollerVRFv2Plus(t *testing.T) { // Instantiate log poller & coordinator. lp := &mocklp.LogPoller{} - lp.On("RegisterFilter", mock.Anything).Return(nil) + lp.On("RegisterFilter", mock.Anything, mock.Anything).Return(nil) c, err := vrf_coordinator_v2plus_interface.NewIVRFCoordinatorV2PlusInternal(coordinatorAddress, nil) require.NoError(t, err) coordinator := &V2PlusCoordinator{ @@ -655,6 +659,7 @@ func (test testCase) testFeederWithLogPollerVRFv2Plus(t *testing.T) { ).Return(requestLogs, nil) lp.On( "LogsWithSigs", + mock.Anything, fromBlock, latest, []common.Hash{ diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 754f48013bd..9442dbc6a18 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -332,10 +332,11 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error } filters = append(filters, relayFilters...) - + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() for _, filter := range filters { d.lggr.Debugf("Unregistering %s filter", filter) - err = lp.UnregisterFilter(filter, pg.WithQueryer(q)) + err = lp.UnregisterFilter(ctx, filter) if err != nil { return errors.Wrapf(err, "Failed to unregister filter %s", filter) } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/log_provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/log_provider.go index 45884d2f726..f7f3fcd65b0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/log_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/log_provider.go @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" registry "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type TransmitUnpacker interface { @@ -69,7 +68,9 @@ func NewLogProvider( // Add log filters for the log poller so that it can poll and find the logs that // we need. - err = logPoller.RegisterFilter(logpoller.Filter{ + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = logPoller.RegisterFilter(ctx, logpoller.Filter{ Name: LogProviderFilterName(contract.Address()), EventSigs: []common.Hash{ registry.KeeperRegistryUpkeepPerformed{}.Topic(), @@ -144,7 +145,7 @@ func (c *LogProvider) HealthReport() map[string]error { } func (c *LogProvider) PerformLogs(ctx context.Context) ([]ocr2keepers.PerformLog, error) { - end, err := c.logPoller.LatestBlock(pg.WithParentCtx(ctx)) + end, err := c.logPoller.LatestBlock(ctx) if err != nil { return nil, fmt.Errorf("%w: failed to get latest block from log poller", err) } @@ -152,13 +153,13 @@ func (c *LogProvider) PerformLogs(ctx context.Context) ([]ocr2keepers.PerformLog // always check the last lookback number of blocks and rebroadcast // this allows the plugin to make decisions based on event confirmations logs, err := c.logPoller.LogsWithSigs( + ctx, end.BlockNumber-c.lookbackBlocks, end.BlockNumber, []common.Hash{ registry.KeeperRegistryUpkeepPerformed{}.Topic(), }, c.registryAddress, - pg.WithParentCtx(ctx), ) if err != nil { return nil, fmt.Errorf("%w: failed to collect logs from log poller", err) @@ -185,7 +186,7 @@ func (c *LogProvider) PerformLogs(ctx context.Context) ([]ocr2keepers.PerformLog } func (c *LogProvider) StaleReportLogs(ctx context.Context) ([]ocr2keepers.StaleReportLog, error) { - end, err := c.logPoller.LatestBlock(pg.WithParentCtx(ctx)) + end, err := c.logPoller.LatestBlock(ctx) if err != nil { return nil, fmt.Errorf("%w: failed to get latest block from log poller", err) } @@ -195,13 +196,13 @@ func (c *LogProvider) StaleReportLogs(ctx context.Context) ([]ocr2keepers.StaleR // ReorgedUpkeepReportLogs logs, err := c.logPoller.LogsWithSigs( + ctx, end.BlockNumber-c.lookbackBlocks, end.BlockNumber, []common.Hash{ registry.KeeperRegistryReorgedUpkeepReport{}.Topic(), }, c.registryAddress, - pg.WithParentCtx(ctx), ) if err != nil { return nil, fmt.Errorf("%w: failed to collect logs from log poller", err) @@ -213,13 +214,13 @@ func (c *LogProvider) StaleReportLogs(ctx context.Context) ([]ocr2keepers.StaleR // StaleUpkeepReportLogs logs, err = c.logPoller.LogsWithSigs( + ctx, end.BlockNumber-c.lookbackBlocks, end.BlockNumber, []common.Hash{ registry.KeeperRegistryStaleUpkeepReport{}.Topic(), }, c.registryAddress, - pg.WithParentCtx(ctx), ) if err != nil { return nil, fmt.Errorf("%w: failed to collect logs from log poller", err) @@ -231,13 +232,13 @@ func (c *LogProvider) StaleReportLogs(ctx context.Context) ([]ocr2keepers.StaleR // InsufficientFundsUpkeepReportLogs logs, err = c.logPoller.LogsWithSigs( + ctx, end.BlockNumber-c.lookbackBlocks, end.BlockNumber, []common.Hash{ registry.KeeperRegistryInsufficientFundsUpkeepReport{}.Topic(), }, c.registryAddress, - pg.WithParentCtx(ctx), ) if err != nil { return nil, fmt.Errorf("%w: failed to collect logs from log poller", err) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go index a6a2f40f855..71d45fcb203 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go @@ -27,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) const ( @@ -351,7 +350,7 @@ func (r *EvmRegistry) pollLogs() error { var end logpoller.LogPollerBlock var err error - if end, err = r.poller.LatestBlock(pg.WithParentCtx(r.ctx)); err != nil { + if end, err = r.poller.LatestBlock(r.ctx); err != nil { return fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } @@ -368,12 +367,14 @@ func (r *EvmRegistry) pollLogs() error { { var logs []logpoller.Log + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() if logs, err = r.poller.LogsWithSigs( + ctx, end.BlockNumber-logEventLookback, end.BlockNumber, upkeepStateEvents, r.addr, - pg.WithParentCtx(r.ctx), ); err != nil { return fmt.Errorf("%w: %s", ErrLogReadFailure, err) } @@ -393,7 +394,9 @@ func UpkeepFilterName(addr common.Address) string { func (r *EvmRegistry) registerEvents(chainID uint64, addr common.Address) error { // Add log filters for the log poller so that it can poll and find the logs that // we need - return r.poller.RegisterFilter(logpoller.Filter{ + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + return r.poller.RegisterFilter(ctx, logpoller.Filter{ Name: UpkeepFilterName(addr), EventSigs: append(upkeepStateEvents, upkeepActiveEvents...), Addresses: []common.Address{addr}, diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go index 9ae17c08ee3..3a7d329ac02 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/block_subscriber.go @@ -17,7 +17,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -80,7 +79,7 @@ func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, fina } func (bs *BlockSubscriber) getBlockRange(ctx context.Context) ([]uint64, error) { - h, err := bs.lp.LatestBlock(pg.WithParentCtx(ctx)) + h, err := bs.lp.LatestBlock(ctx) if err != nil { return nil, err } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/block_time.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/block_time.go index 814ed29d900..9dd442f2e8d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/block_time.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/block_time.go @@ -7,7 +7,6 @@ import ( "time" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -30,7 +29,7 @@ func (r *blockTimeResolver) BlockTime(ctx context.Context, blockSampleSize int64 blockSampleSize = defaultSampleSize } - latest, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := r.poller.LatestBlock(ctx) if err != nil { return 0, fmt.Errorf("failed to get latest block from poller: %w", err) } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go index 5ef06f1bd08..355ec529b8e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go @@ -30,12 +30,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" evmregistry21 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) func TestIntegration_LogEventProvider(t *testing.T) { @@ -315,7 +313,7 @@ func TestIntegration_LogEventProvider_RateLimit(t *testing.T) { { // total block history at this point should be 566 var minimumBlockCount int64 = 500 - latestBlock, _ := lp.LatestBlock() + latestBlock, _ := lp.LatestBlock(ctx) assert.GreaterOrEqual(t, latestBlock.BlockNumber, minimumBlockCount, "to ensure the integrety of the test, the minimum block count before the test should be %d but got %d", minimumBlockCount, latestBlock) } @@ -562,7 +560,7 @@ func waitLogPoller(ctx context.Context, t *testing.T, backend *backends.Simulate require.NoError(t, err) latestBlock := b.Number().Int64() for { - latestPolled, lberr := lp.LatestBlock(pg.WithParentCtx(ctx)) + latestPolled, lberr := lp.LatestBlock(ctx) require.NoError(t, lberr) if latestPolled.BlockNumber >= latestBlock { break @@ -660,7 +658,7 @@ func setupDependencies(t *testing.T, db *sqlx.DB, backend *backends.SimulatedBac ethClient := evmclient.NewSimulatedBackendClient(t, backend, big.NewInt(1337)) pollerLggr := logger.TestLogger(t) pollerLggr.SetLogLevel(zapcore.WarnLevel) - lorm := logpoller.NewORM(big.NewInt(1337), db, pollerLggr, pgtest.NewQConfig(false)) + lorm := logpoller.NewORM(big.NewInt(1337), db, pollerLggr) lp := logpoller.NewLogPoller(lorm, ethClient, pollerLggr, 100*time.Millisecond, false, 1, 2, 2, 1000) return lp, ethClient } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go index d1360faaf6d..14b640c870a 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go @@ -24,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -158,7 +157,7 @@ func (p *logEventProvider) HealthReport() map[string]error { } func (p *logEventProvider) GetLatestPayloads(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { - latest, err := p.poller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := p.poller.LatestBlock(ctx) if err != nil { return nil, fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } @@ -196,7 +195,7 @@ func (p *logEventProvider) ReadLogs(pctx context.Context, ids ...*big.Int) error ctx, cancel := context.WithTimeout(pctx, readLogsTimeout) defer cancel() - latest, err := p.poller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := p.poller.LatestBlock(ctx) if err != nil { return fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } @@ -378,7 +377,7 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [ start = configUpdateBlock } // query logs based on contract address, event sig, and blocks - logs, err := p.poller.LogsWithSigs(start, latest, []common.Hash{filter.topics[0]}, common.BytesToAddress(filter.addr), pg.WithParentCtx(ctx)) + logs, err := p.poller.LogsWithSigs(ctx, start, latest, []common.Hash{filter.topics[0]}, common.BytesToAddress(filter.addr)) if err != nil { // cancel limit reservation as we failed to get logs resv.Cancel() diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go index 69a4872351d..9109890392f 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider_life_cycle.go @@ -12,7 +12,6 @@ import ( "golang.org/x/time/rate" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -105,7 +104,7 @@ func (p *logEventProvider) RegisterFilter(ctx context.Context, opts FilterOption // register registers the upkeep filter with the log poller and adds it to the filter store. func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filter, ufilter upkeepFilter) error { - latest, err := p.poller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := p.poller.LatestBlock(ctx) if err != nil { return fmt.Errorf("failed to get latest block while registering filter: %w", err) } @@ -115,12 +114,12 @@ func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filt if filterStoreHasFilter { // removing filter in case of an update so we can recreate it with updated values lggr.Debugw("Upserting upkeep filter") - err := p.poller.UnregisterFilter(lpFilter.Name) + err := p.poller.UnregisterFilter(ctx, lpFilter.Name) if err != nil { return fmt.Errorf("failed to upsert (unregister) upkeep filter %s: %w", ufilter.upkeepID.String(), err) } } - if err := p.poller.RegisterFilter(lpFilter); err != nil { + if err := p.poller.RegisterFilter(ctx, lpFilter); err != nil { return err } p.filterStore.AddActiveUpkeeps(ufilter) @@ -147,7 +146,9 @@ func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filt func (p *logEventProvider) UnregisterFilter(upkeepID *big.Int) error { // Filter might have been unregistered already, only try to unregister if it exists if p.poller.HasFilter(p.filterName(upkeepID)) { - if err := p.poller.UnregisterFilter(p.filterName(upkeepID)); err != nil { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := p.poller.UnregisterFilter(ctx, p.filterName(upkeepID)); err != nil { return fmt.Errorf("failed to unregister upkeep filter %s: %w", upkeepID.String(), err) } } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go index 13b8bb17245..a63499152c1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer.go @@ -27,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -206,7 +205,7 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2 if !r.filterStore.Has(proposal.UpkeepID.BigInt()) { return nil, fmt.Errorf("filter not found for upkeep %v", proposal.UpkeepID) } - latest, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := r.poller.LatestBlock(ctx) if err != nil { return nil, err } @@ -260,7 +259,7 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2 return nil, fmt.Errorf("log block %d is before the filter configUpdateBlock %d for upkeepID %s", logBlock, filter.configUpdateBlock, proposal.UpkeepID.String()) } - logs, err := r.poller.LogsWithSigs(logBlock-1, logBlock+1, filter.topics, common.BytesToAddress(filter.addr), pg.WithParentCtx(ctx)) + logs, err := r.poller.LogsWithSigs(ctx, logBlock-1, logBlock+1, filter.topics, common.BytesToAddress(filter.addr)) if err != nil { return nil, fmt.Errorf("could not read logs: %w", err) } @@ -285,7 +284,7 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2 } func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) { - latestBlock, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + latestBlock, err := r.poller.LatestBlock(ctx) if err != nil { return nil, fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } @@ -328,7 +327,7 @@ func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers. } func (r *logRecoverer) recover(ctx context.Context) error { - latest, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := r.poller.LatestBlock(ctx) if err != nil { return fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } @@ -387,7 +386,7 @@ func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startB end = offsetBlock } // we expect start to be > offsetBlock in any case - logs, err := r.poller.LogsWithSigs(start, end, f.topics, common.BytesToAddress(f.addr), pg.WithParentCtx(ctx)) + logs, err := r.poller.LogsWithSigs(ctx, start, end, f.topics, common.BytesToAddress(f.addr)) if err != nil { return fmt.Errorf("could not read logs: %w", err) } @@ -602,7 +601,7 @@ func (r *logRecoverer) clean(ctx context.Context) { } func (r *logRecoverer) tryExpire(ctx context.Context, ids ...string) error { - latestBlock, err := r.poller.LatestBlock(pg.WithParentCtx(ctx)) + latestBlock, err := r.poller.LatestBlock(ctx) if err != nil { return fmt.Errorf("failed to get latest block: %w", err) } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer_test.go index eadd0446da8..54338207190 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/recoverer_test.go @@ -28,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) func TestLogRecoverer_GetRecoverables(t *testing.T) { @@ -607,7 +606,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 0, errors.New("latest block boom") }, }, @@ -630,7 +629,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 100, nil }, }, @@ -658,7 +657,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 100, nil }, }, @@ -686,7 +685,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 100, nil }, }, @@ -716,7 +715,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 100, nil }, }, @@ -747,7 +746,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 100, nil }, }, @@ -778,7 +777,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 300, nil }, }, @@ -813,7 +812,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 300, nil }, }, @@ -853,7 +852,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 300, nil }, }, @@ -885,10 +884,10 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 300, nil }, - LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + LogsWithSigsFn: func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { return nil, errors.New("logs with sigs boom") }, }, @@ -920,10 +919,10 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { }, }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 300, nil }, - LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + LogsWithSigsFn: func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { return []logpoller.Log{ { BlockNumber: 80, @@ -968,10 +967,10 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { WorkID: "7f775793422d178c90e99c3bbdf05181bc6bb6ce13170e87c92ac396bb7ddda0", }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 300, nil }, - LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + LogsWithSigsFn: func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { return []logpoller.Log{ { BlockNumber: 80, @@ -1019,10 +1018,10 @@ func TestLogRecoverer_GetProposalData(t *testing.T) { WorkID: "7f775793422d178c90e99c3bbdf05181bc6bb6ce13170e87c92ac396bb7ddda0", }, logPoller: &mockLogPoller{ - LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) { + LatestBlockFn: func(ctx context.Context) (int64, error) { return 300, nil }, - LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { + LogsWithSigsFn: func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { return []logpoller.Log{ { EvmChainId: ubig.New(big.NewInt(1)), @@ -1200,15 +1199,15 @@ func (s *mockFilterStore) Has(id *big.Int) bool { type mockLogPoller struct { logpoller.LogPoller - LatestBlockFn func(qopts ...pg.QOpt) (int64, error) - LogsWithSigsFn func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) + LatestBlockFn func(ctx context.Context) (int64, error) + LogsWithSigsFn func(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) } -func (p *mockLogPoller) LogsWithSigs(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) { - return p.LogsWithSigsFn(start, end, eventSigs, address, qopts...) +func (p *mockLogPoller) LogsWithSigs(ctx context.Context, start, end int64, eventSigs []common.Hash, address common.Address) ([]logpoller.Log, error) { + return p.LogsWithSigsFn(ctx, start, end, eventSigs, address) } -func (p *mockLogPoller) LatestBlock(qopts ...pg.QOpt) (logpoller.LogPollerBlock, error) { - block, err := p.LatestBlockFn(qopts...) +func (p *mockLogPoller) LatestBlock(ctx context.Context) (logpoller.LogPollerBlock, error) { + block, err := p.LatestBlockFn(ctx) return logpoller.LogPollerBlock{BlockNumber: block}, err } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go index fd7bfa91d7f..100acdc5dd3 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go @@ -35,7 +35,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -339,11 +338,13 @@ func (r *EvmRegistry) refreshLogTriggerUpkeepsBatch(logTriggerIDs []*big.Int) er logTriggerHashes = append(logTriggerHashes, common.BigToHash(id)) } - unpausedLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic(), r.addr, 1, logTriggerHashes, logpoller.Confirmations(r.finalityDepth), pg.WithParentCtx(r.ctx)) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + unpausedLogs, err := r.poller.IndexedLogs(ctx, iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic(), r.addr, 1, logTriggerHashes, logpoller.Confirmations(r.finalityDepth)) if err != nil { return err } - configSetLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic(), r.addr, 1, logTriggerHashes, logpoller.Confirmations(r.finalityDepth), pg.WithParentCtx(r.ctx)) + configSetLogs, err := r.poller.IndexedLogs(ctx, iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic(), r.addr, 1, logTriggerHashes, logpoller.Confirmations(r.finalityDepth)) if err != nil { return err } @@ -406,7 +407,7 @@ func (r *EvmRegistry) pollUpkeepStateLogs() error { var end logpoller.LogPollerBlock var err error - if end, err = r.poller.LatestBlock(pg.WithParentCtx(r.ctx)); err != nil { + if end, err = r.poller.LatestBlock(r.ctx); err != nil { return fmt.Errorf("%w: %s", ErrHeadNotAvailable, err) } @@ -421,12 +422,14 @@ func (r *EvmRegistry) pollUpkeepStateLogs() error { } var logs []logpoller.Log + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() if logs, err = r.poller.LogsWithSigs( + ctx, end.BlockNumber-logEventLookback, end.BlockNumber, upkeepStateEvents, r.addr, - pg.WithParentCtx(r.ctx), ); err != nil { return fmt.Errorf("%w: %s", ErrLogReadFailure, err) } @@ -505,7 +508,9 @@ func RegistryUpkeepFilterName(addr common.Address) string { // registerEvents registers upkeep state events from keeper registry on log poller func (r *EvmRegistry) registerEvents(_ uint64, addr common.Address) error { // Add log filters for the log poller so that it can poll and find the logs that we need - return r.poller.RegisterFilter(logpoller.Filter{ + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + return r.poller.RegisterFilter(ctx, logpoller.Filter{ Name: RegistryUpkeepFilterName(addr), EventSigs: upkeepStateEvents, Addresses: []common.Address{addr}, diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go index e6b61be8d0a..ea548249648 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline_test.go @@ -32,7 +32,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) func TestRegistry_GetBlockAndUpkeepId(t *testing.T) { @@ -109,7 +108,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { WorkID: "work", }, poller: &mockLogPoller{ - GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { + GetBlocksRangeFn: func(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) { return []logpoller.LogPollerBlock{ { BlockHash: common.HexToHash("abcdef"), @@ -133,7 +132,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { WorkID: "work", }, poller: &mockLogPoller{ - GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { + GetBlocksRangeFn: func(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) { return []logpoller.LogPollerBlock{ { BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), @@ -157,7 +156,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { WorkID: "work", }, poller: &mockLogPoller{ - GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { + GetBlocksRangeFn: func(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) { return []logpoller.LogPollerBlock{ { BlockHash: common.HexToHash("0xcba5cf9e2bb32373c76015384e1098912d9510a72481c78057fcb088209167de"), @@ -215,16 +214,16 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { type mockLogPoller struct { logpoller.LogPoller - GetBlocksRangeFn func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) - IndexedLogsFn func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) + GetBlocksRangeFn func(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) + IndexedLogsFn func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) } -func (p *mockLogPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { - return p.GetBlocksRangeFn(ctx, numbers, qopts...) +func (p *mockLogPoller) GetBlocksRange(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) { + return p.GetBlocksRangeFn(ctx, numbers) } -func (p *mockLogPoller) IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { - return p.IndexedLogsFn(eventSig, address, topicIndex, topicValues, confs, qopts...) +func (p *mockLogPoller) IndexedLogs(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { + return p.IndexedLogsFn(ctx, eventSig, address, topicIndex, topicValues, confs) } func TestRegistry_VerifyLogExists(t *testing.T) { @@ -486,7 +485,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { }, receipts: map[string]*types.Receipt{}, poller: &mockLogPoller{ - GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) { + GetBlocksRangeFn: func(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) { return []logpoller.LogPollerBlock{ { BlockHash: common.HexToHash("0xcba5cf9e2bb32373c76015384e1098912d9510a72481c78057fcb088209167de"), diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go index dc48c3d75f6..2ffb14b61ca 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_test.go @@ -27,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) func TestPollLogs(t *testing.T) { @@ -221,7 +220,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { }, }, poller: &mockLogPoller{ - IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { + IndexedLogsFn: func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { if eventSig == (iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic()) { return nil, errors.New("indexed logs boom") } @@ -246,7 +245,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { }, }, poller: &mockLogPoller{ - IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { + IndexedLogsFn: func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { if eventSig == (iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic()) { return nil, errors.New("indexed logs boom") } @@ -271,7 +270,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { }, }, poller: &mockLogPoller{ - IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { + IndexedLogsFn: func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { return []logpoller.Log{ {}, }, nil @@ -303,7 +302,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { }, }, poller: &mockLogPoller{ - IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { + IndexedLogsFn: func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { return []logpoller.Log{ { BlockNumber: 1, @@ -357,7 +356,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { }, }, poller: &mockLogPoller{ - IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { + IndexedLogsFn: func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { return []logpoller.Log{ { BlockNumber: 2, @@ -409,7 +408,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { }, }, poller: &mockLogPoller{ - IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { + IndexedLogsFn: func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { return []logpoller.Log{ { BlockNumber: 2, @@ -463,7 +462,7 @@ func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) { }, }, poller: &mockLogPoller{ - IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations, qopts ...pg.QOpt) ([]logpoller.Log, error) { + IndexedLogsFn: func(ctx context.Context, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs logpoller.Confirmations) ([]logpoller.Log, error) { return []logpoller.Log{ { BlockNumber: 2, diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go index eb8dc1793c1..a627fdd0b1e 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit/event_provider.go @@ -19,7 +19,6 @@ import ( iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var _ types.TransmitEventProvider = &EventProvider{} @@ -61,7 +60,9 @@ func NewTransmitEventProvider( if err != nil { return nil, err } - err = logPoller.RegisterFilter(logpoller.Filter{ + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = logPoller.RegisterFilter(ctx, logpoller.Filter{ Name: EventProviderFilterName(contract.Address()), EventSigs: []common.Hash{ // These are the events that are emitted when a node transmits a report @@ -136,7 +137,7 @@ func (c *EventProvider) HealthReport() map[string]error { } func (c *EventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.TransmitEvent, error) { - end, err := c.logPoller.LatestBlock(pg.WithParentCtx(ctx)) + end, err := c.logPoller.LatestBlock(ctx) if err != nil { return nil, fmt.Errorf("%w: failed to get latest block from log poller", err) } @@ -144,6 +145,7 @@ func (c *EventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.Tran // always check the last lookback number of blocks and rebroadcast // this allows the plugin to make decisions based on event confirmations logs, err := c.logPoller.LogsWithSigs( + ctx, end.BlockNumber-c.lookbackBlocks, end.BlockNumber, []common.Hash{ @@ -153,7 +155,6 @@ func (c *EventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.Tran iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), }, c.registryAddress, - pg.WithParentCtx(ctx), ) if err != nil { return nil, fmt.Errorf("%w: failed to collect logs from log poller", err) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go index 30a50977d17..5d7b8d73d30 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate/scanner.go @@ -12,7 +12,6 @@ import ( iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -50,8 +49,8 @@ func NewPerformedEventsScanner( } } -func (s *performedEventsScanner) Start(_ context.Context) error { - return s.poller.RegisterFilter(logpoller.Filter{ +func (s *performedEventsScanner) Start(ctx context.Context) error { + return s.poller.RegisterFilter(ctx, logpoller.Filter{ Name: dedupFilterName(s.registryAddress), EventSigs: []common.Hash{ // listening to dedup key added event @@ -79,7 +78,7 @@ func (s *performedEventsScanner) ScanWorkIDs(ctx context.Context, workID ...stri end = len(ids) } batch := ids[i:end] - batchLogs, err := s.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), s.registryAddress, 1, batch, logpoller.Confirmations(s.finalityDepth), pg.WithParentCtx(ctx)) + batchLogs, err := s.poller.IndexedLogs(ctx, iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), s.registryAddress, 1, batch, logpoller.Confirmations(s.finalityDepth)) if err != nil { return nil, fmt.Errorf("error fetching logs: %w", err) } diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go index 803ed3450be..8c62872c6c8 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go @@ -39,7 +39,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" ocr2vrfconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/config" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var _ ocr2vrftypes.CoordinatorInterface = &coordinator{} @@ -183,7 +182,9 @@ func New( // Add log filters for the log poller so that it can poll and find the logs that // we need. - err = logPoller.RegisterFilter(logpoller.Filter{ + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = logPoller.RegisterFilter(ctx, logpoller.Filter{ Name: filterName(beaconAddress, coordinatorAddress, dkgAddress), EventSigs: []common.Hash{ t.randomnessRequestedTopic, @@ -226,7 +227,7 @@ func New( } func (c *coordinator) CurrentChainHeight(ctx context.Context) (uint64, error) { - head, err := c.lp.LatestBlock(pg.WithParentCtx(ctx)) + head, err := c.lp.LatestBlock(ctx) if err != nil { return 0, err } @@ -257,14 +258,14 @@ func (c *coordinator) ReportIsOnchain( c.lggr.Info(fmt.Sprintf("epoch and round: %s %s", epochAndRound.String(), enrTopic.String())) logs, err := c.lp.IndexedLogs( + ctx, c.topics.newTransmissionTopic, c.beaconAddress, 2, []common.Hash{ enrTopic, }, - 1, - pg.WithParentCtx(ctx)) + 1) if err != nil { return false, errors.Wrap(err, "log poller IndexedLogs") } @@ -342,6 +343,7 @@ func (c *coordinator) ReportBlocks( c.lggr.Infow("current chain height", "currentHeight", currentHeight) logs, err := c.lp.LogsWithSigs( + ctx, int64(currentHeight-c.coordinatorConfig.LookbackBlocks), int64(currentHeight), []common.Hash{ @@ -350,8 +352,7 @@ func (c *coordinator) ReportBlocks( c.randomWordsFulfilledTopic, c.outputsServedTopic, }, - c.coordinatorAddress, - pg.WithParentCtx(ctx)) + c.coordinatorAddress) if err != nil { err = errors.Wrapf(err, "logs with topics. address: %s", c.coordinatorAddress) return @@ -547,7 +548,7 @@ func (c *coordinator) getBlockhashesMapping( return blockNumbers[a] < blockNumbers[b] }) - heads, err := c.lp.GetBlocksRange(ctx, blockNumbers, pg.WithParentCtx(ctx)) + heads, err := c.lp.GetBlocksRange(ctx, blockNumbers) if err != nil { return nil, errors.Wrap(err, "logpoller.GetBlocks") } @@ -911,10 +912,10 @@ func (c *coordinator) DKGVRFCommittees(ctx context.Context) (dkgCommittee, vrfCo defer c.logAndEmitFunctionDuration("DKGVRFCommittees", startTime) latestVRF, err := c.lp.LatestLogByEventSigWithConfs( + ctx, c.configSetTopic, c.beaconAddress, logpoller.Confirmations(c.finalityDepth), - pg.WithParentCtx(ctx), ) if err != nil { err = errors.Wrap(err, "latest vrf ConfigSet by sig with confs") @@ -922,10 +923,10 @@ func (c *coordinator) DKGVRFCommittees(ctx context.Context) (dkgCommittee, vrfCo } latestDKG, err := c.lp.LatestLogByEventSigWithConfs( + ctx, c.configSetTopic, c.dkgAddress, logpoller.Confirmations(c.finalityDepth), - pg.WithParentCtx(ctx), ) if err != nil { err = errors.Wrap(err, "latest dkg ConfigSet by sig with confs") diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/promreporter/prom_reporter_test.go index 60d6d9388fa..a64c52aceaa 100644 --- a/core/services/promreporter/prom_reporter_test.go +++ b/core/services/promreporter/prom_reporter_test.go @@ -38,7 +38,7 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon ethClient := evmtest.NewEthClientMockWithDefaultChain(t) estimator := gas.NewEstimator(logger.TestLogger(t), ethClient, config, evmConfig.GasEstimator()) lggr := logger.TestLogger(t) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr, pgtest.NewQConfig(true)), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, 100*time.Millisecond, false, 2, 3, 2, 1000) txm, err := txmgr.NewTxm( db, diff --git a/core/services/relay/evm/chain_reader_test.go b/core/services/relay/evm/chain_reader_test.go index 02e9d4e3f6a..aaa636051ed 100644 --- a/core/services/relay/evm/chain_reader_test.go +++ b/core/services/relay/evm/chain_reader_test.go @@ -257,7 +257,7 @@ func (it *chainReaderInterfaceTester) GetChainReader(t *testing.T) clcommontypes lggr := logger.NullLogger db := pgtest.NewSqlxDB(t) - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr, pgtest.NewQConfig(true)), it.chain.Client(), lggr, time.Millisecond, false, 0, 1, 1, 10000) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr), it.chain.Client(), lggr, time.Millisecond, false, 0, 1, 1, 10000) require.NoError(t, lp.Start(ctx)) it.chain.On("LogPoller").Return(lp) cr, err := evm.NewChainReaderService(lggr, lp, it.chain, it.chainConfig) diff --git a/core/services/relay/evm/config_poller.go b/core/services/relay/evm/config_poller.go index bb962fc6ed5..63977295248 100644 --- a/core/services/relay/evm/config_poller.go +++ b/core/services/relay/evm/config_poller.go @@ -20,7 +20,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -76,7 +75,9 @@ func NewConfigPoller(lggr logger.Logger, cfg CPConfig) (evmRelayTypes.ConfigPoll } func newConfigPoller(lggr logger.Logger, client client.Client, destChainPoller logpoller.LogPoller, aggregatorContractAddr common.Address, configStoreAddr *common.Address, ld LogDecoder) (*configPoller, error) { - err := destChainPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(aggregatorContractAddr), EventSigs: []common.Hash{ld.EventSig()}, Addresses: []common.Address{aggregatorContractAddr}}) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := destChainPoller.RegisterFilter(ctx, logpoller.Filter{Name: configPollerFilterName(aggregatorContractAddr), EventSigs: []common.Hash{ld.EventSig()}, Addresses: []common.Address{aggregatorContractAddr}}) if err != nil { return nil, err } @@ -125,7 +126,7 @@ func (cp *configPoller) Replay(ctx context.Context, fromBlock int64) error { // LatestConfigDetails returns the latest config details from the logs func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { - latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(cp.ld.EventSig(), cp.aggregatorContractAddr, 1, pg.WithParentCtx(ctx)) + latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(ctx, cp.ld.EventSig(), cp.aggregatorContractAddr, 1) if err != nil { if errors.Is(err, sql.ErrNoRows) { if cp.isConfigStoreAvailable() { @@ -146,7 +147,7 @@ func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock // LatestConfig returns the latest config from the logs on a certain block func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) (ocrtypes.ContractConfig, error) { - lgs, err := cp.destChainLogPoller.Logs(int64(changedInBlock), int64(changedInBlock), cp.ld.EventSig(), cp.aggregatorContractAddr, pg.WithParentCtx(ctx)) + lgs, err := cp.destChainLogPoller.Logs(ctx, int64(changedInBlock), int64(changedInBlock), cp.ld.EventSig(), cp.aggregatorContractAddr) if err != nil { return ocrtypes.ContractConfig{}, err } @@ -167,7 +168,7 @@ func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) // LatestBlockHeight returns the latest block height from the logs func (cp *configPoller) LatestBlockHeight(ctx context.Context) (blockHeight uint64, err error) { - latest, err := cp.destChainLogPoller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := cp.destChainLogPoller.LatestBlock(ctx) if err != nil { if errors.Is(err, sql.ErrNoRows) { return 0, nil diff --git a/core/services/relay/evm/config_poller_test.go b/core/services/relay/evm/config_poller_test.go index cd66e5479bf..9caf09612e6 100644 --- a/core/services/relay/evm/config_poller_test.go +++ b/core/services/relay/evm/config_poller_test.go @@ -86,9 +86,8 @@ func TestConfigPoller(t *testing.T) { b.Commit() db := pgtest.NewSqlxDB(t) - cfg := pgtest.NewQConfig(false) ethClient = evmclient.NewSimulatedBackendClient(t, b, testutils.SimulatedChainID) - lorm := logpoller.NewORM(testutils.SimulatedChainID, db, lggr, cfg) + lorm := logpoller.NewORM(testutils.SimulatedChainID, db, lggr) lp = logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000) servicetest.Run(t, lp) } diff --git a/core/services/relay/evm/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go index 76360e34e1a..ad673236f65 100644 --- a/core/services/relay/evm/contract_transmitter.go +++ b/core/services/relay/evm/contract_transmitter.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type ContractTransmitter interface { @@ -69,7 +68,9 @@ func NewOCRContractTransmitter( return nil, errors.New("invalid ABI, missing transmitted") } - err := lp.RegisterFilter(logpoller.Filter{Name: transmitterFilterName(address), EventSigs: []common.Hash{transmitted.ID}, Addresses: []common.Address{address}}) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := lp.RegisterFilter(ctx, logpoller.Filter{Name: transmitterFilterName(address), EventSigs: []common.Hash{transmitted.ID}, Addresses: []common.Address{address}}) if err != nil { return nil, err } @@ -181,8 +182,7 @@ func (oc *contractTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) ( if err != nil { return ocrtypes.ConfigDigest{}, 0, err } - latest, err := oc.lp.LatestLogByEventSigWithConfs( - oc.transmittedEventSig, oc.contractAddress, 1, pg.WithParentCtx(ctx)) + latest, err := oc.lp.LatestLogByEventSigWithConfs(ctx, oc.transmittedEventSig, oc.contractAddress, 1) if err != nil { if errors.Is(err, sql.ErrNoRows) { // No transmissions yet diff --git a/core/services/relay/evm/event_binding.go b/core/services/relay/evm/event_binding.go index b7148348e4b..6124df55475 100644 --- a/core/services/relay/evm/event_binding.go +++ b/core/services/relay/evm/event_binding.go @@ -52,7 +52,9 @@ func (e *eventBinding) Register() error { return nil } - if err := e.lp.RegisterFilter(logpoller.Filter{ + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := e.lp.RegisterFilter(ctx, logpoller.Filter{ Name: e.id, EventSigs: evmtypes.HashArray{e.hash}, Addresses: evmtypes.AddressArray{e.address}, @@ -70,7 +72,9 @@ func (e *eventBinding) Unregister() error { return nil } - if err := e.lp.UnregisterFilter(e.id); err != nil { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := e.lp.UnregisterFilter(ctx, e.id); err != nil { return fmt.Errorf("%w: %w", commontypes.ErrInternal, err) } return nil @@ -109,7 +113,7 @@ func (e *eventBinding) Bind(binding commontypes.BoundContract) error { } func (e *eventBinding) getLatestValueWithoutFilters(ctx context.Context, confs logpoller.Confirmations, into any) error { - log, err := e.lp.LatestLogByEventSigWithConfs(e.hash, e.address, confs) + log, err := e.lp.LatestLogByEventSigWithConfs(ctx, e.hash, e.address, confs) if err = wrapInternalErr(err); err != nil { return err } @@ -142,7 +146,7 @@ func (e *eventBinding) getLatestValueWithFilters( fai := filtersAndIndices[0] remainingFilters := filtersAndIndices[1:] - logs, err := e.lp.IndexedLogs(e.hash, e.address, 1, []common.Hash{fai}, confs) + logs, err := e.lp.IndexedLogs(ctx, e.hash, e.address, 1, []common.Hash{fai}, confs) if err != nil { return wrapInternalErr(err) } diff --git a/core/services/relay/evm/functions/config_poller.go b/core/services/relay/evm/functions/config_poller.go index 7a59d499898..8d2d7257db3 100644 --- a/core/services/relay/evm/functions/config_poller.go +++ b/core/services/relay/evm/functions/config_poller.go @@ -15,7 +15,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -136,7 +135,7 @@ func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock return 0, ocrtypes.ConfigDigest{}, nil } - latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(ConfigSet, *contractAddr, 1, pg.WithParentCtx(ctx)) + latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(ctx, ConfigSet, *contractAddr, 1) if err != nil { if errors.Is(err, sql.ErrNoRows) { return 0, ocrtypes.ConfigDigest{}, nil @@ -158,7 +157,7 @@ func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) return ocrtypes.ContractConfig{}, errors.New("no target contract address set yet") } - lgs, err := cp.destChainLogPoller.Logs(int64(changedInBlock), int64(changedInBlock), ConfigSet, *contractAddr, pg.WithParentCtx(ctx)) + lgs, err := cp.destChainLogPoller.Logs(ctx, int64(changedInBlock), int64(changedInBlock), ConfigSet, *contractAddr) if err != nil { return ocrtypes.ContractConfig{}, err } @@ -174,7 +173,7 @@ func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) } func (cp *configPoller) LatestBlockHeight(ctx context.Context) (blockHeight uint64, err error) { - latest, err := cp.destChainLogPoller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := cp.destChainLogPoller.LatestBlock(ctx) if err != nil { if errors.Is(err, sql.ErrNoRows) { return 0, nil @@ -188,11 +187,13 @@ func (cp *configPoller) LatestBlockHeight(ctx context.Context) (blockHeight uint func (cp *configPoller) UpdateRoutes(activeCoordinator common.Address, proposedCoordinator common.Address) error { cp.targetContract.Store(&activeCoordinator) // Register filters for both active and proposed - err := cp.destChainLogPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(activeCoordinator), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{activeCoordinator}}) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := cp.destChainLogPoller.RegisterFilter(ctx, logpoller.Filter{Name: configPollerFilterName(activeCoordinator), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{activeCoordinator}}) if err != nil { return err } - err = cp.destChainLogPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(proposedCoordinator), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{activeCoordinator}}) + err = cp.destChainLogPoller.RegisterFilter(ctx, logpoller.Filter{Name: configPollerFilterName(proposedCoordinator), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{activeCoordinator}}) if err != nil { return err } diff --git a/core/services/relay/evm/functions/config_poller_test.go b/core/services/relay/evm/functions/config_poller_test.go index 2cf373d2e86..ef49f7bec42 100644 --- a/core/services/relay/evm/functions/config_poller_test.go +++ b/core/services/relay/evm/functions/config_poller_test.go @@ -76,11 +76,10 @@ func runTest(t *testing.T, pluginType functions.FunctionsPluginType, expectedDig b.Commit() db := pgtest.NewSqlxDB(t) defer db.Close() - cfg := pgtest.NewQConfig(false) ethClient := evmclient.NewSimulatedBackendClient(t, b, big.NewInt(1337)) defer ethClient.Close() lggr := logger.TestLogger(t) - lorm := logpoller.NewORM(big.NewInt(1337), db, lggr, cfg) + lorm := logpoller.NewORM(big.NewInt(1337), db, lggr) lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000) servicetest.Run(t, lp) configPoller, err := functions.NewFunctionsConfigPoller(pluginType, lp, lggr) diff --git a/core/services/relay/evm/functions/contract_transmitter.go b/core/services/relay/evm/functions/contract_transmitter.go index 78a5ff39bb7..352240233b8 100644 --- a/core/services/relay/evm/functions/contract_transmitter.go +++ b/core/services/relay/evm/functions/contract_transmitter.go @@ -22,7 +22,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/encoding" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -228,8 +227,7 @@ func (oc *contractTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) ( if err != nil { return ocrtypes.ConfigDigest{}, 0, err } - latest, err := oc.lp.LatestLogByEventSigWithConfs( - oc.transmittedEventSig, *contractAddr, 1, pg.WithParentCtx(ctx)) + latest, err := oc.lp.LatestLogByEventSigWithConfs(ctx, oc.transmittedEventSig, *contractAddr, 1) if err != nil { if errors.Is(err, sql.ErrNoRows) { // No transmissions yet @@ -262,7 +260,9 @@ func (oc *contractTransmitter) UpdateRoutes(activeCoordinator common.Address, pr return nil } oc.lggr.Debugw("FunctionsContractTransmitter: updating routes", "previousContract", previousContract, "activeCoordinator", activeCoordinator) - err := oc.lp.RegisterFilter(logpoller.Filter{Name: transmitterFilterName(activeCoordinator), EventSigs: []common.Hash{oc.transmittedEventSig}, Addresses: []common.Address{activeCoordinator}}) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := oc.lp.RegisterFilter(ctx, logpoller.Filter{Name: transmitterFilterName(activeCoordinator), EventSigs: []common.Hash{oc.transmittedEventSig}, Addresses: []common.Address{activeCoordinator}}) if err != nil { return err } diff --git a/core/services/relay/evm/functions/logpoller_wrapper.go b/core/services/relay/evm/functions/logpoller_wrapper.go index f11b6bee1e0..687d44c3578 100644 --- a/core/services/relay/evm/functions/logpoller_wrapper.go +++ b/core/services/relay/evm/functions/logpoller_wrapper.go @@ -151,7 +151,7 @@ func (l *logPollerWrapper) LatestEvents() ([]evmRelayTypes.OracleRequest, []evmR if l.proposedCoordinator != (common.Address{}) && l.activeCoordinator != l.proposedCoordinator { coordinators = append(coordinators, l.proposedCoordinator) } - latest, err := l.logPoller.LatestBlock() + latest, err := l.logPoller.LatestBlock(context.Background()) if err != nil { l.mu.Unlock() return nil, nil, err @@ -171,9 +171,12 @@ func (l *logPollerWrapper) LatestEvents() ([]evmRelayTypes.OracleRequest, []evmR return resultsReq, resultsResp, errors.New("no non-zero coordinators to check") } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + for _, coordinator := range coordinators { requestEndBlock := latestBlockNum - l.requestBlockOffset - requestLogs, err := l.logPoller.Logs(startBlockNum, requestEndBlock, functions_coordinator.FunctionsCoordinatorOracleRequest{}.Topic(), coordinator) + requestLogs, err := l.logPoller.Logs(ctx, startBlockNum, requestEndBlock, functions_coordinator.FunctionsCoordinatorOracleRequest{}.Topic(), coordinator) if err != nil { l.lggr.Errorw("LatestEvents: fetching request logs from LogPoller failed", "startBlock", startBlockNum, "endBlock", requestEndBlock) return nil, nil, err @@ -181,7 +184,7 @@ func (l *logPollerWrapper) LatestEvents() ([]evmRelayTypes.OracleRequest, []evmR l.lggr.Debugw("LatestEvents: fetched request logs", "nRequestLogs", len(requestLogs), "latestBlock", latest, "startBlock", startBlockNum, "endBlock", requestEndBlock) requestLogs = l.filterPreviouslyDetectedEvents(requestLogs, &l.detectedRequests, "requests") responseEndBlock := latestBlockNum - l.responseBlockOffset - responseLogs, err := l.logPoller.Logs(startBlockNum, responseEndBlock, functions_coordinator.FunctionsCoordinatorOracleResponse{}.Topic(), coordinator) + responseLogs, err := l.logPoller.Logs(ctx, startBlockNum, responseEndBlock, functions_coordinator.FunctionsCoordinatorOracleResponse{}.Topic(), coordinator) if err != nil { l.lggr.Errorw("LatestEvents: fetching response logs from LogPoller failed", "startBlock", startBlockNum, "endBlock", responseEndBlock) return nil, nil, err @@ -428,7 +431,10 @@ func (l *logPollerWrapper) registerFilters(coordinatorAddress common.Address) er if (coordinatorAddress == common.Address{}) { return nil } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() return l.logPoller.RegisterFilter( + ctx, logpoller.Filter{ Name: filterName(coordinatorAddress), EventSigs: []common.Hash{ diff --git a/core/services/relay/evm/functions/logpoller_wrapper_test.go b/core/services/relay/evm/functions/logpoller_wrapper_test.go index 9df285b4c25..c8c41bf4d4b 100644 --- a/core/services/relay/evm/functions/logpoller_wrapper_test.go +++ b/core/services/relay/evm/functions/logpoller_wrapper_test.go @@ -86,7 +86,7 @@ func getMockedRequestLog(t *testing.T) logpoller.Log { func TestLogPollerWrapper_SingleSubscriberEmptyEvents(t *testing.T) { t.Parallel() lp, lpWrapper, client := setUp(t, 100_000) // check only once - lp.On("LatestBlock").Return(logpoller.LogPollerBlock{BlockNumber: int64(100)}, nil) + lp.On("LatestBlock", mock.Anything).Return(logpoller.LogPollerBlock{BlockNumber: int64(100)}, nil) lp.On("Logs", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{}, nil) client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(addr(t, "01"), nil) @@ -106,7 +106,7 @@ func TestLogPollerWrapper_SingleSubscriberEmptyEvents(t *testing.T) { func TestLogPollerWrapper_ErrorOnZeroAddresses(t *testing.T) { t.Parallel() lp, lpWrapper, client := setUp(t, 100_000) // check only once - lp.On("LatestBlock").Return(logpoller.LogPollerBlock{BlockNumber: int64(100)}, nil) + lp.On("LatestBlock", mock.Anything).Return(logpoller.LogPollerBlock{BlockNumber: int64(100)}, nil) client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(addr(t, "00"), nil) @@ -118,7 +118,7 @@ func TestLogPollerWrapper_ErrorOnZeroAddresses(t *testing.T) { func TestLogPollerWrapper_LatestEvents_ReorgHandling(t *testing.T) { t.Parallel() lp, lpWrapper, client := setUp(t, 100_000) - lp.On("LatestBlock").Return(logpoller.LogPollerBlock{BlockNumber: int64(100)}, nil) + lp.On("LatestBlock", mock.Anything).Return(logpoller.LogPollerBlock{BlockNumber: int64(100)}, nil) client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(addr(t, "01"), nil) lp.On("RegisterFilter", mock.Anything).Return(nil) subscriber := newSubscriber(1) diff --git a/core/services/relay/evm/mercury/config_poller.go b/core/services/relay/evm/mercury/config_poller.go index 98ef78020c7..1501db1337a 100644 --- a/core/services/relay/evm/mercury/config_poller.go +++ b/core/services/relay/evm/mercury/config_poller.go @@ -14,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" ) @@ -99,7 +98,9 @@ func FilterName(addr common.Address, feedID common.Hash) string { // NewConfigPoller creates a new Mercury ConfigPoller func NewConfigPoller(lggr logger.Logger, destChainPoller logpoller.LogPoller, addr common.Address, feedId common.Hash) (*ConfigPoller, error) { - err := destChainPoller.RegisterFilter(logpoller.Filter{Name: FilterName(addr, feedId), EventSigs: []common.Hash{FeedScopedConfigSet}, Addresses: []common.Address{addr}}) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := destChainPoller.RegisterFilter(ctx, logpoller.Filter{Name: FilterName(addr, feedId), EventSigs: []common.Hash{FeedScopedConfigSet}, Addresses: []common.Address{addr}}) if err != nil { return nil, err } @@ -132,7 +133,7 @@ func (cp *ConfigPoller) Replay(ctx context.Context, fromBlock int64) error { // LatestConfigDetails returns the latest config details from the logs func (cp *ConfigPoller) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { cp.lggr.Debugw("LatestConfigDetails", "eventSig", FeedScopedConfigSet, "addr", cp.addr, "topicIndex", feedIdTopicIndex, "feedID", cp.feedId) - logs, err := cp.destChainLogPoller.IndexedLogs(FeedScopedConfigSet, cp.addr, feedIdTopicIndex, []common.Hash{cp.feedId}, 1, pg.WithParentCtx(ctx)) + logs, err := cp.destChainLogPoller.IndexedLogs(ctx, FeedScopedConfigSet, cp.addr, feedIdTopicIndex, []common.Hash{cp.feedId}, 1) if err != nil { return 0, ocrtypes.ConfigDigest{}, err } @@ -149,7 +150,7 @@ func (cp *ConfigPoller) LatestConfigDetails(ctx context.Context) (changedInBlock // LatestConfig returns the latest config from the logs on a certain block func (cp *ConfigPoller) LatestConfig(ctx context.Context, changedInBlock uint64) (ocrtypes.ContractConfig, error) { - lgs, err := cp.destChainLogPoller.IndexedLogsByBlockRange(int64(changedInBlock), int64(changedInBlock), FeedScopedConfigSet, cp.addr, feedIdTopicIndex, []common.Hash{cp.feedId}, pg.WithParentCtx(ctx)) + lgs, err := cp.destChainLogPoller.IndexedLogsByBlockRange(ctx, int64(changedInBlock), int64(changedInBlock), FeedScopedConfigSet, cp.addr, feedIdTopicIndex, []common.Hash{cp.feedId}) if err != nil { return ocrtypes.ContractConfig{}, err } @@ -166,7 +167,7 @@ func (cp *ConfigPoller) LatestConfig(ctx context.Context, changedInBlock uint64) // LatestBlockHeight returns the latest block height from the logs func (cp *ConfigPoller) LatestBlockHeight(ctx context.Context) (blockHeight uint64, err error) { - latest, err := cp.destChainLogPoller.LatestBlock(pg.WithParentCtx(ctx)) + latest, err := cp.destChainLogPoller.LatestBlock(ctx) if err != nil { if errors.Is(err, sql.ErrNoRows) { return 0, nil diff --git a/core/services/relay/evm/mercury/helpers_test.go b/core/services/relay/evm/mercury/helpers_test.go index f1686ee00c8..86645b78f6b 100644 --- a/core/services/relay/evm/mercury/helpers_test.go +++ b/core/services/relay/evm/mercury/helpers_test.go @@ -163,10 +163,9 @@ func SetupTH(t *testing.T, feedID common.Hash) TestHarness { b.Commit() db := pgtest.NewSqlxDB(t) - cfg := pgtest.NewQConfig(false) ethClient := evmclient.NewSimulatedBackendClient(t, b, big.NewInt(1337)) lggr := logger.TestLogger(t) - lorm := logpoller.NewORM(big.NewInt(1337), db, lggr, cfg) + lorm := logpoller.NewORM(big.NewInt(1337), db, lggr) lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, false, 1, 2, 2, 1000) servicetest.Run(t, lp) diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go index 8ad88d7b73b..66a3dd71ab3 100644 --- a/core/services/vrf/delegate_test.go +++ b/core/services/vrf/delegate_test.go @@ -83,7 +83,7 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv ks := keystore.NewInMemory(db, utils.FastScryptParams, lggr, cfg.Database()) _, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) txm, err := txmgr.NewTxm(db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil) - orm := headtracker.NewORM(db, lggr, cfg.Database(), *testutils.FixtureChainID) + orm := headtracker.NewORM(*testutils.FixtureChainID, db) require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), cltest.Head(51))) jrm := job.NewORM(db, prm, btORM, ks, lggr, cfg.Database()) t.Cleanup(func() { assert.NoError(t, jrm.Close()) }) diff --git a/core/services/vrf/v2/listener_v2_log_listener.go b/core/services/vrf/v2/listener_v2_log_listener.go index 07b4c2c3800..e495eac5d8b 100644 --- a/core/services/vrf/v2/listener_v2_log_listener.go +++ b/core/services/vrf/v2/listener_v2_log_listener.go @@ -14,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" ) @@ -41,7 +40,7 @@ func (lsn *listenerV2) runLogListener( lsn.l.Debugw("log listener loop") // Filter registration is idempotent, so we can just call it every time // and retry on errors using the ticker. - err := lsn.chain.LogPoller().RegisterFilter(logpoller.Filter{ + err := lsn.chain.LogPoller().RegisterFilter(ctx, logpoller.Filter{ Name: logpoller.FilterName( "VRFListener", "version", lsn.coordinator.Version(), @@ -107,7 +106,7 @@ func (lsn *listenerV2) initializeLastProcessedBlock(ctx context.Context) (lastPr start := time.Now() // will retry on error in the runLogListener loop - latestBlock, err := lp.LatestBlock() + latestBlock, err := lp.LatestBlock(ctx) if err != nil { return 0, fmt.Errorf("LogPoller.LatestBlock(): %w", err) } @@ -131,6 +130,7 @@ func (lsn *listenerV2) initializeLastProcessedBlock(ctx context.Context) (lastPr // get randomness requested logs with the appropriate keyhash // keyhash is specified in topic1 requests, err := lp.IndexedLogsCreatedAfter( + ctx, lsn.coordinator.RandomWordsRequestedTopic(), // event sig lsn.coordinator.Address(), // address 1, // topic index @@ -145,6 +145,7 @@ func (lsn *listenerV2) initializeLastProcessedBlock(ctx context.Context) (lastPr // fulfillments don't have keyhash indexed, we'll have to get all of them // TODO: can we instead write a single query that joins on request id's somehow? fulfillments, err := lp.LogsCreatedAfter( + ctx, lsn.coordinator.RandomWordsFulfilledTopic(), // event sig lsn.coordinator.Address(), // address fromTimestamp, // from time @@ -172,7 +173,7 @@ func (lsn *listenerV2) updateLastProcessedBlock(ctx context.Context, currLastPro lp := lsn.chain.LogPoller() start := time.Now() - latestBlock, err := lp.LatestBlock(pg.WithParentCtx(ctx)) + latestBlock, err := lp.LatestBlock(ctx) if err != nil { lsn.l.Errorw("error getting latest block", "err", err) return 0, fmt.Errorf("LogPoller.LatestBlock(): %w", err) @@ -187,11 +188,11 @@ func (lsn *listenerV2) updateLastProcessedBlock(ctx context.Context, currLastPro }() logs, err := lp.LogsWithSigs( + ctx, currLastProcessedBlock, latestBlock.FinalizedBlockNumber, []common.Hash{lsn.coordinator.RandomWordsFulfilledTopic(), lsn.coordinator.RandomWordsRequestedTopic()}, lsn.coordinator.Address(), - pg.WithParentCtx(ctx), ) if err != nil { return currLastProcessedBlock, fmt.Errorf("LogPoller.LogsWithSigs: %w", err) @@ -228,7 +229,7 @@ func (lsn *listenerV2) pollLogs(ctx context.Context, minConfs uint32, lastProces // latest unfinalized block used on purpose to get bleeding edge logs // we don't really have the luxury to wait for finalization on most chains // if we want to fulfill on time. - latestBlock, err := lp.LatestBlock() + latestBlock, err := lp.LatestBlock(ctx) if err != nil { return nil, fmt.Errorf("LogPoller.LatestBlock(): %w", err) } @@ -246,11 +247,11 @@ func (lsn *listenerV2) pollLogs(ctx context.Context, minConfs uint32, lastProces // We don't specify confs because each request can have a different conf above // the minimum. So we do all conf handling in getConfirmedAt. logs, err := lp.LogsWithSigs( + ctx, lastProcessedBlock, latestBlock.BlockNumber, []common.Hash{lsn.coordinator.RandomWordsFulfilledTopic(), lsn.coordinator.RandomWordsRequestedTopic()}, lsn.coordinator.Address(), - pg.WithParentCtx(ctx), ) if err != nil { return nil, fmt.Errorf("LogPoller.LogsWithSigs: %w", err) diff --git a/core/services/vrf/v2/listener_v2_log_listener_test.go b/core/services/vrf/v2/listener_v2_log_listener_test.go index 6f5177c230a..9aeaa5a7ed6 100644 --- a/core/services/vrf/v2/listener_v2_log_listener_test.go +++ b/core/services/vrf/v2/listener_v2_log_listener_test.go @@ -30,7 +30,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -68,7 +67,7 @@ func setupVRFLogPollerListenerTH(t *testing.T, chainID := testutils.NewRandomEVMChainID() db := pgtest.NewSqlxDB(t) - o := logpoller.NewORM(chainID, db, lggr, pgtest.NewQConfig(true)) + o := logpoller.NewORM(chainID, db, lggr) owner := testutils.MustNewSimTransactor(t) ethDB := rawdb.NewMemoryDatabase() ec := backends.NewSimulatedBackendWithDatabase(ethDB, map[common.Address]core.GenesisAccount{ @@ -126,7 +125,7 @@ func setupVRFLogPollerListenerTH(t *testing.T, // Filter registration is idempotent, so we can just call it every time // and retry on errors using the ticker. - err = lp.RegisterFilter(logpoller.Filter{ + err = lp.RegisterFilter(ctx, logpoller.Filter{ Name: fmt.Sprintf("vrf_%s_keyhash_%s_job_%d", "v2", listener.job.VRFSpec.PublicKey.MustHash().String(), listener.job.ID), EventSigs: evmtypes.HashArray{ vrf_log_emitter.VRFLogEmitterRandomWordsRequested{}.Topic(), @@ -138,7 +137,7 @@ func setupVRFLogPollerListenerTH(t *testing.T, }, }) require.Nil(t, err) - require.NoError(t, lp.RegisterFilter(logpoller.Filter{ + require.NoError(t, lp.RegisterFilter(ctx, logpoller.Filter{ Name: "Integration test", EventSigs: []common.Hash{emitterABI.Events["Log1"].ID}, Addresses: []common.Address{emitterAddress1}, @@ -211,8 +210,7 @@ func TestInitProcessedBlock_NoVRFReqs(t *testing.T) { require.NoError(t, th.LogPoller.Replay(testutils.Context(t), 4)) // Should return logs from block 5 to 7 (inclusive) - logs, err := th.LogPoller.Logs(4, 7, emitterABI.Events["Log1"].ID, th.EmitterAddress, - pg.WithParentCtx(testutils.Context(t))) + logs, err := th.LogPoller.Logs(testutils.Context(t), 4, 7, emitterABI.Events["Log1"].ID, th.EmitterAddress) require.NoError(t, err) require.Equal(t, 3, len(logs)) diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go index 56d1fe41eb5..70bc651fa0a 100644 --- a/core/store/migrate/migrate_test.go +++ b/core/store/migrate/migrate_test.go @@ -445,21 +445,22 @@ func TestSetMigrationENVVars(t *testing.T) { func TestDatabaseBackFillWithMigration202(t *testing.T) { _, db := heavyweight.FullTestDBEmptyV2(t, nil) + ctx := testutils.Context(t) err := goose.UpTo(db.DB, migrationDir, 201) require.NoError(t, err) - simulatedOrm := logpoller.NewORM(testutils.SimulatedChainID, db, logger.TestLogger(t), pgtest.NewQConfig(true)) - require.NoError(t, simulatedOrm.InsertBlock(testutils.Random32Byte(), 10, time.Now(), 0), err) - require.NoError(t, simulatedOrm.InsertBlock(testutils.Random32Byte(), 51, time.Now(), 0), err) - require.NoError(t, simulatedOrm.InsertBlock(testutils.Random32Byte(), 90, time.Now(), 0), err) - require.NoError(t, simulatedOrm.InsertBlock(testutils.Random32Byte(), 120, time.Now(), 23), err) + simulatedOrm := logpoller.NewORM(testutils.SimulatedChainID, db, logger.TestLogger(t)) + require.NoError(t, simulatedOrm.InsertBlock(ctx, testutils.Random32Byte(), 10, time.Now(), 0), err) + require.NoError(t, simulatedOrm.InsertBlock(ctx, testutils.Random32Byte(), 51, time.Now(), 0), err) + require.NoError(t, simulatedOrm.InsertBlock(ctx, testutils.Random32Byte(), 90, time.Now(), 0), err) + require.NoError(t, simulatedOrm.InsertBlock(ctx, testutils.Random32Byte(), 120, time.Now(), 23), err) - baseOrm := logpoller.NewORM(big.NewInt(int64(84531)), db, logger.TestLogger(t), pgtest.NewQConfig(true)) - require.NoError(t, baseOrm.InsertBlock(testutils.Random32Byte(), 400, time.Now(), 0), err) + baseOrm := logpoller.NewORM(big.NewInt(int64(84531)), db, logger.TestLogger(t)) + require.NoError(t, baseOrm.InsertBlock(ctx, testutils.Random32Byte(), 400, time.Now(), 0), err) - klaytnOrm := logpoller.NewORM(big.NewInt(int64(1001)), db, logger.TestLogger(t), pgtest.NewQConfig(true)) - require.NoError(t, klaytnOrm.InsertBlock(testutils.Random32Byte(), 100, time.Now(), 0), err) + klaytnOrm := logpoller.NewORM(big.NewInt(int64(1001)), db, logger.TestLogger(t)) + require.NoError(t, klaytnOrm.InsertBlock(ctx, testutils.Random32Byte(), 100, time.Now(), 0), err) err = goose.UpTo(db.DB, migrationDir, 202) require.NoError(t, err) @@ -509,7 +510,7 @@ func TestDatabaseBackFillWithMigration202(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - block, err := tt.orm.SelectBlockByNumber(tt.blockNumber) + block, err := tt.orm.SelectBlockByNumber(ctx, tt.blockNumber) require.NoError(t, err) require.Equal(t, tt.expectedFinalizedBlock, block.FinalizedBlockNumber) }) diff --git a/core/web/evm_forwarders_controller.go b/core/web/evm_forwarders_controller.go index 8bfa26d8470..d6cd5587ae5 100644 --- a/core/web/evm_forwarders_controller.go +++ b/core/web/evm_forwarders_controller.go @@ -97,7 +97,9 @@ func (cc *EVMForwardersController) Delete(c *gin.Context) { // handle same as non-existent chain id return nil } - return chain.LogPoller().UnregisterFilter(forwarders.FilterName(addr)) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + return chain.LogPoller().UnregisterFilter(ctx, forwarders.FilterName(addr)) } orm := forwarders.NewORM(cc.App.GetSqlxDB()) diff --git a/integration-tests/universal/log_poller/helpers.go b/integration-tests/universal/log_poller/helpers.go index db7eaee625b..0624759732e 100644 --- a/integration-tests/universal/log_poller/helpers.go +++ b/integration-tests/universal/log_poller/helpers.go @@ -36,6 +36,8 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + lp_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/log_poller" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -43,10 +45,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1" le "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_emitter" core_logger "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" - - tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" - lp_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/log_poller" ) var ( @@ -147,7 +145,7 @@ func NewOrm(logger core_logger.SugaredLogger, chainID *big.Int, postgresDb *ctf_ } db.MapperFunc(reflectx.CamelToSnakeASCII) - return logpoller.NewORM(chainID, db, logger, pg.NewQConfig(false)), db, nil + return logpoller.NewORM(chainID, db, logger), db, nil } type ExpectedFilter struct { @@ -178,7 +176,7 @@ func NodeHasExpectedFilters(expectedFilters []ExpectedFilter, logger core_logger } defer db.Close() - knownFilters, err := orm.LoadFilters() + knownFilters, err := orm.LoadFilters(context.Background()) if err != nil { return false, "", err } @@ -318,7 +316,7 @@ func LogPollerHasFinalisedEndBlock(endBlock int64, chainID *big.Int, l zerolog.L defer db.Close() - latestBlock, err := orm.SelectLatestBlock() + latestBlock, err := orm.SelectLatestBlock(ctx) if err != nil { r <- boolQueryResult{ nodeName: clNode.ContainerName, @@ -415,7 +413,7 @@ func ClNodesHaveExpectedLogCount(startBlock, endBlock int64, chainID *big.Int, e foundLogsCount := 0 for _, filter := range expectedFilters { - logs, err := orm.SelectLogs(startBlock, endBlock, filter.emitterAddress, filter.topic) + logs, err := orm.SelectLogs(ctx, startBlock, endBlock, filter.emitterAddress, filter.topic) if err != nil { resultChan <- logQueryResult{ nodeName: clNode.ContainerName, @@ -541,7 +539,7 @@ func GetMissingLogs(startBlock, endBlock int64, logEmitters []*contracts.LogEmit for _, event := range cfg.General.EventsToEmit { l.Trace().Str("Event name", event.Name).Str("Emitter address", address.String()).Msg("Fetching single emitter's logs") - result, err := orm.SelectLogs(startBlock, endBlock, address, event.ID) + result, err := orm.SelectLogs(ctx, startBlock, endBlock, address, event.ID) if err != nil { r <- dbQueryResult{ err: err,