From 0d051fe8f868dc606028a1616b90ee1d7f11fca4 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 3 Feb 2025 07:36:15 -0600 Subject: [PATCH] core/chains/evm: simpler evm config (#16187) --- core/chains/evm/log/helpers_internal_test.go | 22 - core/chains/evm/log/helpers_test.go | 400 +----------------- core/chains/evm/log/integration_test.go | 390 ++++++++++++++++- core/chains/evm/log/orm_test.go | 8 + core/chains/evm/log/pool_test.go | 7 +- core/chains/evm/txmgr/broadcaster_test.go | 73 ++-- core/chains/evm/txmgr/confirmer_test.go | 207 +++++---- core/chains/evm/txmgr/evm_tx_store_test.go | 47 +- core/chains/evm/txmgr/finalizer_test.go | 7 +- .../evm/txmgr/stuck_tx_detector_test.go | 3 +- core/chains/evm/txmgr/txmgr_test.go | 20 +- core/chains/legacyevm/chain.go | 25 +- core/chains/legacyevm/chain_test.go | 2 +- core/cmd/shell.go | 2 +- core/cmd/shell_local_test.go | 25 +- core/config/app_config.go | 1 - core/internal/cltest/cltest.go | 2 +- core/internal/cltest/mocks.go | 7 +- core/internal/features/features_test.go | 2 +- core/internal/testutils/evmtest/evmtest.go | 12 +- core/internal/testutils/evmtest/v2/evmtest.go | 3 +- core/services/blockhashstore/bhs_test.go | 5 +- core/services/blockhashstore/delegate_test.go | 4 +- core/services/chainlink/application.go | 2 +- core/services/chainlink/config_general.go | 14 +- .../services/chainlink/config_general_test.go | 2 +- .../chainlink/mocks/general_config.go | 45 -- .../chainlink/relayer_chain_interoperators.go | 2 +- .../relayer_chain_interoperators_test.go | 4 +- core/services/directrequest/delegate_test.go | 9 +- core/services/feeds/orm_test.go | 2 +- core/services/feeds/service_test.go | 2 +- core/services/functions/listener_test.go | 5 +- .../headreporter/prometheus_reporter_test.go | 6 +- core/services/job/helpers_test.go | 5 +- core/services/job/job_orm_test.go | 18 +- .../job/job_pipeline_orm_integration_test.go | 5 +- core/services/job/runner_integration_test.go | 4 +- core/services/job/spawner_test.go | 4 +- .../keeper/registry1_1_synchronizer_test.go | 3 +- .../keeper/registry1_2_synchronizer_test.go | 3 +- .../keeper/registry1_3_synchronizer_test.go | 3 +- .../registry_synchronizer_helper_test.go | 4 +- core/services/keeper/upkeep_executer_test.go | 2 +- core/services/ocr2/delegate_test.go | 2 +- .../ccip/testhelpers/integration/chainlink.go | 2 +- .../testhelpers_1_4_0/chainlink.go | 2 +- core/services/pipeline/runner_test.go | 8 +- core/services/pipeline/task.eth_call_test.go | 2 +- core/services/pipeline/task.eth_tx_test.go | 2 +- core/services/relay/evm/relayer_extender.go | 4 +- .../relay/evm/relayer_extender_test.go | 2 +- core/services/vrf/delegate_test.go | 2 +- core/services/vrf/v2/integration_v2_test.go | 2 +- core/services/vrf/v2/listener_v2_test.go | 6 +- core/web/eth_keys_controller_test.go | 16 +- deployment/environment/memory/node.go | 2 +- evm/config/chain_scoped.go | 12 +- evm/config/configtest/configtest.go | 5 +- evm/config/toml/config.go | 11 + evm/gas/fee_history_estimator_test.go | 2 +- evm/testutils/config.go | 4 +- 62 files changed, 697 insertions(+), 807 deletions(-) delete mode 100644 core/chains/evm/log/helpers_internal_test.go diff --git a/core/chains/evm/log/helpers_internal_test.go b/core/chains/evm/log/helpers_internal_test.go deleted file mode 100644 index 59a3c4aadbc..00000000000 --- a/core/chains/evm/log/helpers_internal_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package log - -import ( - "github.com/ethereum/go-ethereum/core/types" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - - evmclient "github.com/smartcontractkit/chainlink/v2/evm/client" - evmtypes "github.com/smartcontractkit/chainlink/v2/evm/types" -) - -// NewTestBroadcaster creates a broadcaster with Pause/Resume enabled. -func NewTestBroadcaster(orm ORM, ethClient evmclient.Client, config Config, lggr logger.Logger, highestSavedHead *evmtypes.Head, mailMon *mailbox.Monitor) *broadcaster { - b := NewBroadcaster(orm, ethClient, config, lggr, highestSavedHead, mailMon) - b.testPause, b.testResume = make(chan struct{}), make(chan struct{}) - return b -} - -func (b *broadcaster) ExportedAppendLogChannel(ch1, ch2 <-chan types.Log) chan types.Log { - return b.appendLogChannel(ch1, ch2) -} diff --git a/core/chains/evm/log/helpers_test.go b/core/chains/evm/log/helpers_test.go index d24bf51d85b..59a3c4aadbc 100644 --- a/core/chains/evm/log/helpers_test.go +++ b/core/chains/evm/log/helpers_test.go @@ -1,404 +1,22 @@ -package log_test +package log import ( - "context" - "fmt" - "math/big" - "sync" - "sync/atomic" - "testing" - "time" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/google/uuid" - "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/jmoiron/sqlx" "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" - "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" - logmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/config" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" evmclient "github.com/smartcontractkit/chainlink/v2/evm/client" - "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" - evmconfig "github.com/smartcontractkit/chainlink/v2/evm/config" - "github.com/smartcontractkit/chainlink/v2/evm/testutils" evmtypes "github.com/smartcontractkit/chainlink/v2/evm/types" ) -type broadcasterHelper struct { - t *testing.T - lb log.BroadcasterInTest - db *sqlx.DB - mockEth *clienttest.MockEth - globalConfig config.AppConfig - config evmconfig.EVM - - // each received channel corresponds to one eth subscription - chchRawLogs chan testutils.RawSub[types.Log] - toUnsubscribe []func() - pipelineHelper cltest.JobPipelineV2TestHelper -} - -func newBroadcasterHelper(t *testing.T, blockHeight int64, timesSubscribe int, filterLogsResult []types.Log, overridesFn func(*chainlink.Config, *chainlink.Secrets)) *broadcasterHelper { - // ensure we check before registering any mock Cleanup assertions - testutils.SkipShortDB(t) - - expectedCalls := mockEthClientExpectedCalls{ - SubscribeFilterLogs: timesSubscribe, - HeaderByNumber: 1, - FilterLogs: 1, - FilterLogsResult: filterLogsResult, - } - - chchRawLogs := make(chan testutils.RawSub[types.Log], timesSubscribe) - mockEth := newMockEthClient(t, chchRawLogs, blockHeight, expectedCalls) - helper := newBroadcasterHelperWithEthClient(t, mockEth.EthClient, nil, overridesFn) - helper.chchRawLogs = chchRawLogs - helper.mockEth = mockEth - return helper -} - -func newBroadcasterHelperWithEthClient(t *testing.T, ethClient evmclient.Client, highestSeenHead *evmtypes.Head, overridesFn func(*chainlink.Config, *chainlink.Secrets)) *broadcasterHelper { - globalConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.Database.LogQueries = ptr(true) - finality := uint32(10) - c.EVM[0].FinalityDepth = &finality - - if overridesFn != nil { - overridesFn(c, s) - } - }) //TODO make evm directly - config := evmtest.NewChainScopedConfig(t, globalConfig).EVM() - lggr := logger.Test(t) - mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t)) - - db := testutils.NewSqlxDB(t) - orm := log.NewORM(db, cltest.FixtureChainID) - lb := log.NewTestBroadcaster(orm, ethClient, config, lggr, highestSeenHead, mailMon) - kst := cltest.NewKeyStore(t, db) - - chainsAndConfig := evmtest.NewLegacyChainsAndConfig(t, evmtest.TestChainOpts{ - Client: ethClient, - GeneralConfig: globalConfig, - DatabaseConfig: globalConfig.Database(), - FeatureConfig: globalConfig.Feature(), - ListenerConfig: globalConfig.Database().Listener(), - DB: db, - KeyStore: kst.Eth(), - LogBroadcaster: &log.NullBroadcaster{}, - MailMon: mailMon, - }) - - m := make(map[string]legacyevm.Chain) - for _, r := range chainsAndConfig.Slice() { - m[r.ID().String()] = r - } - - legacyChains := chainsAndConfig.NewLegacyChains() - pipelineHelper := cltest.NewJobPipelineV2(t, globalConfig.WebServer(), globalConfig.JobPipeline(), legacyChains, db, kst, nil, nil) - - return &broadcasterHelper{ - t: t, - lb: lb, - db: db, - globalConfig: globalConfig, - config: config, - pipelineHelper: pipelineHelper, - toUnsubscribe: make([]func(), 0), - } -} - -func (helper *broadcasterHelper) start() { - err := helper.lb.Start(testutils.Context(helper.t)) - require.NoError(helper.t, err) -} - -func (helper *broadcasterHelper) register(listener log.Listener, contract log.AbigenContract, numConfirmations uint32) { - logs := []generated.AbigenLog{ - flux_aggregator_wrapper.FluxAggregatorNewRound{}, - flux_aggregator_wrapper.FluxAggregatorAnswerUpdated{}, - } - helper.registerWithTopics(listener, contract, logs, numConfirmations) -} - -func (helper *broadcasterHelper) registerWithTopics(listener log.Listener, contract log.AbigenContract, logs []generated.AbigenLog, numConfirmations uint32) { - logsWithTopics := make(map[common.Hash][][]log.Topic) - for _, log := range logs { - logsWithTopics[log.Topic()] = nil - } - helper.registerWithTopicValues(listener, contract, numConfirmations, logsWithTopics) -} - -func (helper *broadcasterHelper) registerWithTopicValues(listener log.Listener, contract log.AbigenContract, numConfirmations uint32, - topics map[common.Hash][][]log.Topic) { - unsubscribe := helper.lb.Register(listener, log.ListenerOpts{ - Contract: contract.Address(), - ParseLog: contract.ParseLog, - LogsWithTopics: topics, - MinIncomingConfirmations: numConfirmations, - }) - - helper.toUnsubscribe = append(helper.toUnsubscribe, unsubscribe) -} - -func (helper *broadcasterHelper) requireBroadcastCount(expectedCount int) { - helper.t.Helper() - g := gomega.NewGomegaWithT(helper.t) - - comparisonFunc := func() (int, error) { - var count struct{ Count int } - err := helper.db.Get(&count, `SELECT count(*) FROM log_broadcasts`) - return count.Count, err - } - - g.Eventually(comparisonFunc, testutils.WaitTimeout(helper.t), time.Second).Should(gomega.Equal(expectedCount)) - g.Consistently(comparisonFunc, 1*time.Second, 200*time.Millisecond).Should(gomega.Equal(expectedCount)) -} - -func (helper *broadcasterHelper) unsubscribeAll() { - for _, unsubscribe := range helper.toUnsubscribe { - unsubscribe() - } - time.Sleep(100 * time.Millisecond) -} -func (helper *broadcasterHelper) stop() { - err := helper.lb.Close() - assert.NoError(helper.t, err) -} - -func newMockContract(t *testing.T) *logmocks.AbigenContract { - addr := testutils.NewAddress() - contract := logmocks.NewAbigenContract(t) - contract.On("Address").Return(addr).Maybe() - return contract -} - -type logOnBlock struct { - logBlockNumber uint64 - blockNumber uint64 - blockHash common.Hash -} - -func (l logOnBlock) String() string { - return fmt.Sprintf("blockInfo(log:%v received on: %v %s)", l.logBlockNumber, l.blockNumber, l.blockHash) -} - -type received struct { - uniqueLogs []types.Log - logs []types.Log - broadcasts []log.Broadcast - sync.Mutex -} - -func newReceived(logs []types.Log) *received { - var rec received - rec.logs = logs - rec.uniqueLogs = logs - return &rec -} - -func (rec *received) getLogs() []types.Log { - rec.Lock() - defer rec.Unlock() - r := make([]types.Log, len(rec.logs)) - copy(r, rec.logs) - return r +// NewTestBroadcaster creates a broadcaster with Pause/Resume enabled. +func NewTestBroadcaster(orm ORM, ethClient evmclient.Client, config Config, lggr logger.Logger, highestSavedHead *evmtypes.Head, mailMon *mailbox.Monitor) *broadcaster { + b := NewBroadcaster(orm, ethClient, config, lggr, highestSavedHead, mailMon) + b.testPause, b.testResume = make(chan struct{}), make(chan struct{}) + return b } -func (rec *received) getUniqueLogs() []types.Log { - rec.Lock() - defer rec.Unlock() - r := make([]types.Log, len(rec.uniqueLogs)) - copy(r, rec.uniqueLogs) - return r -} - -func (rec *received) logsOnBlocks() []logOnBlock { - rec.Lock() - defer rec.Unlock() - var blocks []logOnBlock - for _, broadcast := range rec.broadcasts { - blocks = append(blocks, logOnBlock{ - logBlockNumber: broadcast.RawLog().BlockNumber, - blockNumber: broadcast.LatestBlockNumber(), - blockHash: broadcast.LatestBlockHash(), - }) - } - return blocks -} - -type simpleLogListener struct { - name string - lggr logger.SugaredLogger - received *received - t *testing.T - db *sqlx.DB - jobID int32 - skipMarkingConsumed atomic.Bool -} - -func (helper *broadcasterHelper) newLogListenerWithJob(name string) *simpleLogListener { - t := helper.t - db := helper.db - jb := &job.Job{ - Type: job.Cron, - SchemaVersion: 1, - CronSpec: &job.CronSpec{CronSchedule: "@every 1s"}, - PipelineSpec: &pipeline.Spec{}, - ExternalJobID: uuid.New(), - } - err := helper.pipelineHelper.Jrm.CreateJob(testutils.Context(t), jb) - require.NoError(t, err) - - var rec received - return &simpleLogListener{ - db: db, - lggr: logger.Sugared(logger.Test(t)), - name: name, - received: &rec, - t: t, - jobID: jb.ID, - } -} - -func (listener *simpleLogListener) SkipMarkingConsumed(skip bool) { - listener.skipMarkingConsumed.Store(skip) -} - -func (listener *simpleLogListener) HandleLog(ctx context.Context, lb log.Broadcast) { - listener.received.Lock() - defer listener.received.Unlock() - listener.lggr.Tracef("Listener %v HandleLog for block %v %v received at %v %v", listener.name, lb.RawLog().BlockNumber, lb.RawLog().BlockHash, lb.LatestBlockNumber(), lb.LatestBlockHash()) - - listener.received.logs = append(listener.received.logs, lb.RawLog()) - listener.received.broadcasts = append(listener.received.broadcasts, lb) - consumed := listener.handleLogBroadcast(ctx, lb) - - if !consumed { - listener.received.uniqueLogs = append(listener.received.uniqueLogs, lb.RawLog()) - } else { - listener.lggr.Warnf("Listener %v: Log was already consumed!", listener.name) - } -} - -func (listener *simpleLogListener) JobID() int32 { - return listener.jobID -} - -func (listener *simpleLogListener) getUniqueLogs() []types.Log { - return listener.received.getUniqueLogs() -} - -func (listener *simpleLogListener) getUniqueLogsBlockNumbers() []uint64 { - var blockNums []uint64 - for _, uniqueLog := range listener.received.getUniqueLogs() { - blockNums = append(blockNums, uniqueLog.BlockNumber) - } - return blockNums -} - -func (listener *simpleLogListener) requireAllReceived(t *testing.T, expectedState *received) { - received := listener.received - defer func() { assert.EqualValues(t, expectedState.getUniqueLogs(), received.getUniqueLogs()) }() - require.Eventually(t, func() bool { - return len(received.getUniqueLogs()) == len(expectedState.getUniqueLogs()) - }, testutils.WaitTimeout(t), time.Second, "len(received.uniqueLogs): %v is not equal len(expectedState.uniqueLogs): %v", len(received.getUniqueLogs()), len(expectedState.getUniqueLogs())) -} - -func (listener *simpleLogListener) handleLogBroadcast(ctx context.Context, lb log.Broadcast) bool { - t := listener.t - consumed, err := listener.WasAlreadyConsumed(ctx, lb) - if !assert.NoError(t, err) { - return false - } - if !consumed && !listener.skipMarkingConsumed.Load() { - err = listener.MarkConsumed(ctx, lb) - if assert.NoError(t, err) { - consumed2, err := listener.WasAlreadyConsumed(ctx, lb) - if assert.NoError(t, err) { - assert.True(t, consumed2) - } - } - } - return consumed -} - -func (listener *simpleLogListener) WasAlreadyConsumed(ctx context.Context, broadcast log.Broadcast) (bool, error) { - return log.NewORM(listener.db, cltest.FixtureChainID).WasBroadcastConsumed(ctx, broadcast.RawLog().BlockHash, broadcast.RawLog().Index, listener.jobID) -} - -func (listener *simpleLogListener) MarkConsumed(ctx context.Context, broadcast log.Broadcast) error { - return log.NewORM(listener.db, cltest.FixtureChainID).MarkBroadcastConsumed(ctx, broadcast.RawLog().BlockHash, broadcast.RawLog().BlockNumber, broadcast.RawLog().Index, listener.jobID) -} - -type mockListener struct { - jobID int32 -} - -func (l *mockListener) JobID() int32 { return l.jobID } -func (l *mockListener) HandleLog(context.Context, log.Broadcast) {} - -type mockEthClientExpectedCalls struct { - SubscribeFilterLogs int - HeaderByNumber int - FilterLogs int - - FilterLogsResult []types.Log -} - -func newMockEthClient(t *testing.T, chchRawLogs chan<- testutils.RawSub[types.Log], blockHeight int64, expectedCalls mockEthClientExpectedCalls) *clienttest.MockEth { - ethClient := clienttest.NewClient(t) - mockEth := &clienttest.MockEth{EthClient: ethClient} - mockEth.EthClient.On("ConfiguredChainID", mock.Anything).Return(&cltest.FixtureChainID) - mockEth.EthClient.On("SubscribeFilterLogs", mock.Anything, mock.Anything, mock.Anything). - Return( - func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) ethereum.Subscription { - sub := mockEth.NewSub(t) - chchRawLogs <- testutils.NewRawSub(ch, sub.Err()) - return sub - }, - func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) error { - return nil - }, - ). - Times(expectedCalls.SubscribeFilterLogs) - - mockEth.EthClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)). - Return(&evmtypes.Head{Number: blockHeight}, nil). - Times(expectedCalls.HeaderByNumber) - - if expectedCalls.FilterLogs > 0 { - mockEth.EthClient.On("FilterLogs", mock.Anything, mock.Anything). - Run(func(args mock.Arguments) { - filterQuery := args.Get(1).(ethereum.FilterQuery) - fromBlock := filterQuery.FromBlock.Int64() - toBlock := filterQuery.ToBlock.Int64() - if mockEth.CheckFilterLogs != nil { - mockEth.CheckFilterLogs(fromBlock, toBlock) - } - }). - Return(expectedCalls.FilterLogsResult, nil). - Times(expectedCalls.FilterLogs) - } - - return mockEth +func (b *broadcaster) ExportedAppendLogChannel(ch1, ch2 <-chan types.Log) chan types.Log { + return b.appendLogChannel(ch1, ch2) } diff --git a/core/chains/evm/log/integration_test.go b/core/chains/evm/log/integration_test.go index 58606437480..4cd5024b581 100644 --- a/core/chains/evm/log/integration_test.go +++ b/core/chains/evm/log/integration_test.go @@ -2,8 +2,10 @@ package log_test import ( "context" + "fmt" "math/big" "slices" + "sync" "sync/atomic" "testing" "time" @@ -11,6 +13,8 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/google/uuid" + "github.com/jmoiron/sqlx" "github.com/onsi/gomega" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -22,14 +26,20 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" logmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log/mocks" + "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "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/evmtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + evmclient "github.com/smartcontractkit/chainlink/v2/evm/client" "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" - evmtestutils "github.com/smartcontractkit/chainlink/v2/evm/testutils" + evmconfig "github.com/smartcontractkit/chainlink/v2/evm/config" + "github.com/smartcontractkit/chainlink/v2/evm/testutils" evmtypes "github.com/smartcontractkit/chainlink/v2/evm/types" "github.com/smartcontractkit/chainlink/v2/evm/utils" ) @@ -82,7 +92,7 @@ func TestBroadcaster_ResubscribesOnAddOrRemoveContract(t *testing.T) { FilterLogs: backfillTimes, } - chchRawLogs := make(chan evmtestutils.RawSub[types.Log], backfillTimes) + chchRawLogs := make(chan testutils.RawSub[types.Log], backfillTimes) mockEth := newMockEthClient(t, chchRawLogs, blockHeight, expectedCalls) helper := newBroadcasterHelperWithEthClient(t, mockEth.EthClient, cltest.Head(lastStoredBlockHeight), nil) helper.mockEth = mockEth @@ -148,7 +158,7 @@ func TestBroadcaster_BackfillOnNodeStartAndOnReplay(t *testing.T) { FilterLogs: 2, } - chchRawLogs := make(chan evmtestutils.RawSub[types.Log], backfillTimes) + chchRawLogs := make(chan testutils.RawSub[types.Log], backfillTimes) mockEth := newMockEthClient(t, chchRawLogs, blockHeight, expectedCalls) helper := newBroadcasterHelperWithEthClient(t, mockEth.EthClient, cltest.Head(lastStoredBlockHeight), nil) helper.mockEth = mockEth @@ -205,7 +215,7 @@ func TestBroadcaster_ReplaysLogs(t *testing.T) { blocks.LogOnBlockNum(7, contract.Address()), } - mockEth := newMockEthClient(t, make(chan evmtestutils.RawSub[types.Log], 4), blockHeight, mockEthClientExpectedCalls{ + mockEth := newMockEthClient(t, make(chan testutils.RawSub[types.Log], 4), blockHeight, mockEthClientExpectedCalls{ FilterLogs: 4, FilterLogsResult: sentLogs, }) @@ -410,7 +420,7 @@ func TestBroadcaster_ShallowBackfillOnNodeStart(t *testing.T) { FilterLogs: backfillTimes, } - chchRawLogs := make(chan evmtestutils.RawSub[types.Log], backfillTimes) + chchRawLogs := make(chan testutils.RawSub[types.Log], backfillTimes) mockEth := newMockEthClient(t, chchRawLogs, blockHeight, expectedCalls) helper := newBroadcasterHelperWithEthClient(t, mockEth.EthClient, cltest.Head(lastStoredBlockHeight), func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].BlockBackfillSkip = ptr(true) @@ -460,7 +470,7 @@ func TestBroadcaster_BackfillInBatches(t *testing.T) { FilterLogs: expectedBatches, } - chchRawLogs := make(chan evmtestutils.RawSub[types.Log], backfillTimes) + chchRawLogs := make(chan testutils.RawSub[types.Log], backfillTimes) mockEth := newMockEthClient(t, chchRawLogs, blockHeight, expectedCalls) helper := newBroadcasterHelperWithEthClient(t, mockEth.EthClient, cltest.Head(lastStoredBlockHeight), func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].LogBackfillBatchSize = ptr(uint32(batchSize)) @@ -533,7 +543,7 @@ func TestBroadcaster_BackfillALargeNumberOfLogs(t *testing.T) { FilterLogsResult: backfilledLogs, } - chchRawLogs := make(chan evmtestutils.RawSub[types.Log], backfillTimes) + chchRawLogs := make(chan testutils.RawSub[types.Log], backfillTimes) mockEth := newMockEthClient(t, chchRawLogs, blockHeight, expectedCalls) helper := newBroadcasterHelperWithEthClient(t, mockEth.EthClient, cltest.Head(lastStoredBlockHeight), func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].LogBackfillBatchSize = ptr(batchSize) @@ -1014,7 +1024,7 @@ func TestBroadcaster_Register_ResubscribesToMostRecentlySeenBlock(t *testing.T) contract2 = newMockContract(t) ) mockEth := &clienttest.MockEth{EthClient: ethClient} - chchRawLogs := make(chan evmtestutils.RawSub[types.Log], backfillTimes) + chchRawLogs := make(chan testutils.RawSub[types.Log], backfillTimes) chStarted := make(chan struct{}) ethClient.On("ConfiguredChainID", mock.Anything).Return(&cltest.FixtureChainID) ethClient.On("SubscribeFilterLogs", mock.Anything, mock.Anything, mock.Anything). @@ -1022,7 +1032,7 @@ func TestBroadcaster_Register_ResubscribesToMostRecentlySeenBlock(t *testing.T) func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) ethereum.Subscription { defer close(chStarted) sub := mockEth.NewSub(t) - chchRawLogs <- evmtestutils.NewRawSub(ch, sub.Err()) + chchRawLogs <- testutils.NewRawSub(ch, sub.Err()) return sub }, func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) error { @@ -1035,7 +1045,7 @@ func TestBroadcaster_Register_ResubscribesToMostRecentlySeenBlock(t *testing.T) Return( func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) ethereum.Subscription { sub := mockEth.NewSub(t) - chchRawLogs <- evmtestutils.NewRawSub(ch, sub.Err()) + chchRawLogs <- testutils.NewRawSub(ch, sub.Err()) return sub }, func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) error { @@ -1326,7 +1336,7 @@ func TestBroadcaster_AppendLogChannel(t *testing.T) { ch2 := make(chan types.Log) ch3 := make(chan types.Log) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) mailMon := servicetest.RunHealthy(t, mailboxtest.NewMonitor(t)) lb := log.NewBroadcaster(nil, ethClient, nil, logger.Test(t), nil, mailMon) chCombined := lb.ExportedAppendLogChannel(ch1, ch2) @@ -1533,12 +1543,12 @@ func TestBroadcaster_BroadcastsWithZeroConfirmations(t *testing.T) { ethClient := clienttest.NewClient(t) mockEth := &clienttest.MockEth{EthClient: ethClient} ethClient.On("ConfiguredChainID").Return(big.NewInt(0)).Maybe() - logsChCh := make(chan evmtestutils.RawSub[types.Log]) + logsChCh := make(chan testutils.RawSub[types.Log]) ethClient.On("SubscribeFilterLogs", mock.Anything, mock.Anything, mock.Anything). Return( func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) ethereum.Subscription { sub := mockEth.NewSub(t) - logsChCh <- evmtestutils.NewRawSub(ch, sub.Err()) + logsChCh <- testutils.NewRawSub(ch, sub.Err()) return sub }, func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) error { @@ -1633,3 +1643,355 @@ func TestBroadcaster_BroadcastsWithZeroConfirmations(t *testing.T) { } func ptr[T any](t T) *T { return &t } + +func newBroadcasterHelper(t *testing.T, blockHeight int64, timesSubscribe int, filterLogsResult []types.Log, overridesFn func(*chainlink.Config, *chainlink.Secrets)) *broadcasterHelper { + // ensure we check before registering any mock Cleanup assertions + testutils.SkipShortDB(t) + + expectedCalls := mockEthClientExpectedCalls{ + SubscribeFilterLogs: timesSubscribe, + HeaderByNumber: 1, + FilterLogs: 1, + FilterLogsResult: filterLogsResult, + } + + chchRawLogs := make(chan testutils.RawSub[types.Log], timesSubscribe) + mockEth := newMockEthClient(t, chchRawLogs, blockHeight, expectedCalls) + helper := newBroadcasterHelperWithEthClient(t, mockEth.EthClient, nil, overridesFn) + helper.chchRawLogs = chchRawLogs + helper.mockEth = mockEth + return helper +} + +func newBroadcasterHelperWithEthClient(t *testing.T, ethClient evmclient.Client, highestSeenHead *evmtypes.Head, overridesFn func(*chainlink.Config, *chainlink.Secrets)) *broadcasterHelper { + globalConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.Database.LogQueries = ptr(true) + finality := uint32(10) + c.EVM[0].FinalityDepth = &finality + + if overridesFn != nil { + overridesFn(c, s) + } + }) + config := evmtest.NewChainScopedConfig(t, globalConfig).EVM() + lggr := logger.Test(t) + mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t)) + + db := testutils.NewSqlxDB(t) + orm := log.NewORM(db, cltest.FixtureChainID) + lb := log.NewTestBroadcaster(orm, ethClient, config, lggr, highestSeenHead, mailMon) + kst := cltest.NewKeyStore(t, db) + + chainsAndConfig := evmtest.NewLegacyChainsAndConfig(t, evmtest.TestChainOpts{ + Client: ethClient, + ChainConfigs: globalConfig.EVMConfigs(), + DatabaseConfig: globalConfig.Database(), + FeatureConfig: globalConfig.Feature(), + ListenerConfig: globalConfig.Database().Listener(), + DB: db, + KeyStore: kst.Eth(), + LogBroadcaster: &log.NullBroadcaster{}, + MailMon: mailMon, + }) + + m := make(map[string]legacyevm.Chain) + for _, r := range chainsAndConfig.Slice() { + m[r.ID().String()] = r + } + + legacyChains := chainsAndConfig.NewLegacyChains() + pipelineHelper := cltest.NewJobPipelineV2(t, globalConfig.WebServer(), globalConfig.JobPipeline(), legacyChains, db, kst, nil, nil) + + return &broadcasterHelper{ + t: t, + lb: lb, + db: db, + globalConfig: globalConfig, + config: config, + pipelineHelper: pipelineHelper, + toUnsubscribe: make([]func(), 0), + } +} + +type broadcasterHelper struct { + t *testing.T + lb log.BroadcasterInTest + db *sqlx.DB + mockEth *clienttest.MockEth + globalConfig config.AppConfig + config evmconfig.EVM + + // each received channel corresponds to one eth subscription + chchRawLogs chan testutils.RawSub[types.Log] + toUnsubscribe []func() + pipelineHelper cltest.JobPipelineV2TestHelper +} + +func (helper *broadcasterHelper) start() { + err := helper.lb.Start(testutils.Context(helper.t)) + require.NoError(helper.t, err) +} + +func (helper *broadcasterHelper) register(listener log.Listener, contract log.AbigenContract, numConfirmations uint32) { + logs := []generated.AbigenLog{ + flux_aggregator_wrapper.FluxAggregatorNewRound{}, + flux_aggregator_wrapper.FluxAggregatorAnswerUpdated{}, + } + helper.registerWithTopics(listener, contract, logs, numConfirmations) +} + +func (helper *broadcasterHelper) registerWithTopics(listener log.Listener, contract log.AbigenContract, logs []generated.AbigenLog, numConfirmations uint32) { + logsWithTopics := make(map[common.Hash][][]log.Topic) + for _, log := range logs { + logsWithTopics[log.Topic()] = nil + } + helper.registerWithTopicValues(listener, contract, numConfirmations, logsWithTopics) +} + +func (helper *broadcasterHelper) registerWithTopicValues(listener log.Listener, contract log.AbigenContract, numConfirmations uint32, + topics map[common.Hash][][]log.Topic) { + unsubscribe := helper.lb.Register(listener, log.ListenerOpts{ + Contract: contract.Address(), + ParseLog: contract.ParseLog, + LogsWithTopics: topics, + MinIncomingConfirmations: numConfirmations, + }) + + helper.toUnsubscribe = append(helper.toUnsubscribe, unsubscribe) +} + +func (helper *broadcasterHelper) requireBroadcastCount(expectedCount int) { + helper.t.Helper() + g := gomega.NewGomegaWithT(helper.t) + + comparisonFunc := func() (int, error) { + var count struct{ Count int } + err := helper.db.Get(&count, `SELECT count(*) FROM log_broadcasts`) + return count.Count, err + } + + g.Eventually(comparisonFunc, testutils.WaitTimeout(helper.t), time.Second).Should(gomega.Equal(expectedCount)) + g.Consistently(comparisonFunc, 1*time.Second, 200*time.Millisecond).Should(gomega.Equal(expectedCount)) +} + +func (helper *broadcasterHelper) unsubscribeAll() { + for _, unsubscribe := range helper.toUnsubscribe { + unsubscribe() + } + time.Sleep(100 * time.Millisecond) +} +func (helper *broadcasterHelper) stop() { + err := helper.lb.Close() + assert.NoError(helper.t, err) +} + +func newMockContract(t *testing.T) *logmocks.AbigenContract { + addr := testutils.NewAddress() + contract := logmocks.NewAbigenContract(t) + contract.On("Address").Return(addr).Maybe() + return contract +} + +type logOnBlock struct { + logBlockNumber uint64 + blockNumber uint64 + blockHash common.Hash +} + +func (l logOnBlock) String() string { + return fmt.Sprintf("blockInfo(log:%v received on: %v %s)", l.logBlockNumber, l.blockNumber, l.blockHash) +} + +type received struct { + uniqueLogs []types.Log + logs []types.Log + broadcasts []log.Broadcast + sync.Mutex +} + +func newReceived(logs []types.Log) *received { + var rec received + rec.logs = logs + rec.uniqueLogs = logs + return &rec +} + +func (rec *received) getLogs() []types.Log { + rec.Lock() + defer rec.Unlock() + r := make([]types.Log, len(rec.logs)) + copy(r, rec.logs) + return r +} + +func (rec *received) getUniqueLogs() []types.Log { + rec.Lock() + defer rec.Unlock() + r := make([]types.Log, len(rec.uniqueLogs)) + copy(r, rec.uniqueLogs) + return r +} + +func (rec *received) logsOnBlocks() []logOnBlock { + rec.Lock() + defer rec.Unlock() + var blocks []logOnBlock + for _, broadcast := range rec.broadcasts { + blocks = append(blocks, logOnBlock{ + logBlockNumber: broadcast.RawLog().BlockNumber, + blockNumber: broadcast.LatestBlockNumber(), + blockHash: broadcast.LatestBlockHash(), + }) + } + return blocks +} + +type simpleLogListener struct { + name string + lggr logger.SugaredLogger + received *received + t *testing.T + db *sqlx.DB + jobID int32 + skipMarkingConsumed atomic.Bool +} + +func (helper *broadcasterHelper) newLogListenerWithJob(name string) *simpleLogListener { + t := helper.t + db := helper.db + jb := &job.Job{ + Type: job.Cron, + SchemaVersion: 1, + CronSpec: &job.CronSpec{CronSchedule: "@every 1s"}, + PipelineSpec: &pipeline.Spec{}, + ExternalJobID: uuid.New(), + } + err := helper.pipelineHelper.Jrm.CreateJob(testutils.Context(t), jb) + require.NoError(t, err) + + var rec received + return &simpleLogListener{ + db: db, + lggr: logger.Sugared(logger.Test(t)), + name: name, + received: &rec, + t: t, + jobID: jb.ID, + } +} + +func (listener *simpleLogListener) SkipMarkingConsumed(skip bool) { + listener.skipMarkingConsumed.Store(skip) +} + +func (listener *simpleLogListener) HandleLog(ctx context.Context, lb log.Broadcast) { + listener.received.Lock() + defer listener.received.Unlock() + listener.lggr.Tracef("Listener %v HandleLog for block %v %v received at %v %v", listener.name, lb.RawLog().BlockNumber, lb.RawLog().BlockHash, lb.LatestBlockNumber(), lb.LatestBlockHash()) + + listener.received.logs = append(listener.received.logs, lb.RawLog()) + listener.received.broadcasts = append(listener.received.broadcasts, lb) + consumed := listener.handleLogBroadcast(ctx, lb) + + if !consumed { + listener.received.uniqueLogs = append(listener.received.uniqueLogs, lb.RawLog()) + } else { + listener.lggr.Warnf("Listener %v: Log was already consumed!", listener.name) + } +} + +func (listener *simpleLogListener) JobID() int32 { + return listener.jobID +} + +func (listener *simpleLogListener) getUniqueLogs() []types.Log { + return listener.received.getUniqueLogs() +} + +func (listener *simpleLogListener) getUniqueLogsBlockNumbers() []uint64 { + var blockNums []uint64 + for _, uniqueLog := range listener.received.getUniqueLogs() { + blockNums = append(blockNums, uniqueLog.BlockNumber) + } + return blockNums +} + +func (listener *simpleLogListener) requireAllReceived(t *testing.T, expectedState *received) { + received := listener.received + defer func() { assert.EqualValues(t, expectedState.getUniqueLogs(), received.getUniqueLogs()) }() + require.Eventually(t, func() bool { + return len(received.getUniqueLogs()) == len(expectedState.getUniqueLogs()) + }, testutils.WaitTimeout(t), time.Second, "len(received.uniqueLogs): %v is not equal len(expectedState.uniqueLogs): %v", len(received.getUniqueLogs()), len(expectedState.getUniqueLogs())) +} + +func (listener *simpleLogListener) handleLogBroadcast(ctx context.Context, lb log.Broadcast) bool { + t := listener.t + consumed, err := listener.WasAlreadyConsumed(ctx, lb) + if !assert.NoError(t, err) { + return false + } + if !consumed && !listener.skipMarkingConsumed.Load() { + err = listener.MarkConsumed(ctx, lb) + if assert.NoError(t, err) { + consumed2, err := listener.WasAlreadyConsumed(ctx, lb) + if assert.NoError(t, err) { + assert.True(t, consumed2) + } + } + } + return consumed +} + +func (listener *simpleLogListener) WasAlreadyConsumed(ctx context.Context, broadcast log.Broadcast) (bool, error) { + return log.NewORM(listener.db, cltest.FixtureChainID).WasBroadcastConsumed(ctx, broadcast.RawLog().BlockHash, broadcast.RawLog().Index, listener.jobID) +} + +func (listener *simpleLogListener) MarkConsumed(ctx context.Context, broadcast log.Broadcast) error { + return log.NewORM(listener.db, cltest.FixtureChainID).MarkBroadcastConsumed(ctx, broadcast.RawLog().BlockHash, broadcast.RawLog().BlockNumber, broadcast.RawLog().Index, listener.jobID) +} + +type mockEthClientExpectedCalls struct { + SubscribeFilterLogs int + HeaderByNumber int + FilterLogs int + + FilterLogsResult []types.Log +} + +func newMockEthClient(t *testing.T, chchRawLogs chan<- testutils.RawSub[types.Log], blockHeight int64, expectedCalls mockEthClientExpectedCalls) *clienttest.MockEth { + ethClient := clienttest.NewClient(t) + mockEth := &clienttest.MockEth{EthClient: ethClient} + mockEth.EthClient.On("ConfiguredChainID", mock.Anything).Return(&cltest.FixtureChainID) + mockEth.EthClient.On("SubscribeFilterLogs", mock.Anything, mock.Anything, mock.Anything). + Return( + func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) ethereum.Subscription { + sub := mockEth.NewSub(t) + chchRawLogs <- testutils.NewRawSub(ch, sub.Err()) + return sub + }, + func(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) error { + return nil + }, + ). + Times(expectedCalls.SubscribeFilterLogs) + + mockEth.EthClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)). + Return(&evmtypes.Head{Number: blockHeight}, nil). + Times(expectedCalls.HeaderByNumber) + + if expectedCalls.FilterLogs > 0 { + mockEth.EthClient.On("FilterLogs", mock.Anything, mock.Anything). + Run(func(args mock.Arguments) { + filterQuery := args.Get(1).(ethereum.FilterQuery) + fromBlock := filterQuery.FromBlock.Int64() + toBlock := filterQuery.ToBlock.Int64() + if mockEth.CheckFilterLogs != nil { + mockEth.CheckFilterLogs(fromBlock, toBlock) + } + }). + Return(expectedCalls.FilterLogsResult, nil). + Times(expectedCalls.FilterLogs) + } + + return mockEth +} diff --git a/core/chains/evm/log/orm_test.go b/core/chains/evm/log/orm_test.go index c1c9c54d82c..be8cbaa4b5a 100644 --- a/core/chains/evm/log/orm_test.go +++ b/core/chains/evm/log/orm_test.go @@ -1,6 +1,7 @@ package log_test import ( + "context" "math/big" "math/rand" "testing" @@ -238,3 +239,10 @@ func TestORM_Reinitialize(t *testing.T) { }) } } + +type mockListener struct { + jobID int32 +} + +func (l *mockListener) JobID() int32 { return l.jobID } +func (l *mockListener) HandleLog(context.Context, log.Broadcast) {} diff --git a/core/chains/evm/log/pool_test.go b/core/chains/evm/log/pool_test.go index c4789f5acd4..50b16f51954 100644 --- a/core/chains/evm/log/pool_test.go +++ b/core/chains/evm/log/pool_test.go @@ -4,13 +4,12 @@ import ( "math/big" "testing" - "github.com/stretchr/testify/assert" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" ) var ( diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index ad7342c9707..9bdd9614cb5 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -65,7 +65,7 @@ func NewTestEthBroadcaster( ethClient client.Client, keyStore keystore.Eth, databaseListener txmgr.ListenerConfig, - config evmconfig.ChainScopedConfig, + config evmconfig.EVM, checkerFactory txmgr.TransmitCheckerFactory, nonceAutoSync bool, nonceTracker txmgr.NonceTracker, @@ -73,17 +73,17 @@ func NewTestEthBroadcaster( t.Helper() lggr := logger.Test(t) - ge := config.EVM().GasEstimator() + ge := config.GasEstimator() estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { - return gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), nil, ge.BlockHistory(), lggr, nil) + return gas.NewFixedPriceEstimator(config.GasEstimator(), nil, ge.BlockHistory(), lggr, nil) }, ge.EIP1559DynamicFees(), ge, ethClient) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator) ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), - txmgr.NewEvmTxmConfig(config.EVM()), - txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), - config.EVM().Transactions(), + txmgr.NewEvmTxmConfig(config), + txmgr.NewEvmTxmFeeConfig(config.GasEstimator()), + config.Transactions(), databaseListener, keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync, "") @@ -199,7 +199,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { ethClient.On("NonceAt", mock.Anything, otherAddress, mock.Anything).Return(uint64(0), nil).Once() lggr := logger.Test(t) nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, checkerFactory, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), checkerFactory, false, nonceTracker) toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") timeNow := time.Now() @@ -398,7 +398,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { }) ethClient.On("NonceAt", mock.Anything, otherAddress, mock.Anything).Return(uint64(1), nil).Once() nonceTracker = txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, checkerFactory, false, nonceTracker) + eb = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), checkerFactory, false, nonceTracker) t.Run("sends transactions with type 0x2 in EIP-1559 mode", func(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { @@ -566,7 +566,7 @@ func TestEthBroadcaster_TransmitChecking(t *testing.T) { checkerFactory := &testCheckerFactory{} ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, checkerFactory, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), checkerFactory, false, nonceTracker) checker := txmgr.TransmitCheckerSpec{ CheckerType: txmgr.TransmitCheckerTypeSimulate, @@ -715,7 +715,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success_WithMultiplier(t *testing ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { assert.Equal(t, int(1600), int(tx.Gas())) @@ -748,7 +748,6 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { nextNonce := evmtypes.Nonce(916714082576372851) firstNonce := nextNonce secondNonce := nextNonce + 1 - evmcfg := configtest.NewChainScopedConfig(t, nil) ctx := tests.Context(t) t.Run("cannot be more than one transaction per address in an unfinished state", func(t *testing.T) { @@ -789,14 +788,14 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { t.Run("previous run assigned nonce but never broadcast", func(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - + evmcfg := configtest.NewChainScopedConfig(t, nil) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.RandomKey{Nonce: nextNonce.Int64()}.MustInsertWithState(t, ethKeyStore) ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved // the nonce to the eth_tx so evm.key_states.next_nonce has not been @@ -828,14 +827,14 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { t.Run("previous run assigned nonce and broadcast but it fatally errored before we could save", func(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - + evmcfg := configtest.NewChainScopedConfig(t, nil) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.RandomKey{Nonce: nextNonce.Int64()}.MustInsertWithState(t, ethKeyStore) ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx inProgressEthTx := mustInsertInProgressEthTxWithAttempt(t, txStore, firstNonce, fromAddress) @@ -865,14 +864,14 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { t.Run("previous run assigned nonce and broadcast and is now in mempool", func(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - + evmcfg := configtest.NewChainScopedConfig(t, nil) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.RandomKey{Nonce: nextNonce.Int64()}.MustInsertWithState(t, ethKeyStore) ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx inProgressEthTx := mustInsertInProgressEthTxWithAttempt(t, txStore, firstNonce, fromAddress) @@ -901,14 +900,14 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { t.Run("previous run assigned nonce and broadcast and now the transaction has been confirmed", func(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - + evmcfg := configtest.NewChainScopedConfig(t, nil) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.RandomKey{Nonce: nextNonce.Int64()}.MustInsertWithState(t, ethKeyStore) ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx inProgressEthTx := mustInsertInProgressEthTxWithAttempt(t, txStore, firstNonce, fromAddress) @@ -939,14 +938,14 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { failedToReachNodeError := context.DeadlineExceeded db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - + evmcfg := configtest.NewChainScopedConfig(t, nil) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.RandomKey{Nonce: nextNonce.Int64()}.MustInsertWithState(t, ethKeyStore) ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx inProgressEthTx := mustInsertInProgressEthTxWithAttempt(t, txStore, firstNonce, fromAddress) @@ -987,7 +986,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx inProgressEthTx := mustInsertInProgressEthTxWithAttempt(t, txStore, firstNonce, fromAddress) @@ -1046,13 +1045,12 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) - evmcfg := configtest.NewChainScopedConfig(t, nil) ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() lggr := logger.Test(t) txmClient := txmgr.NewEvmTxmClient(ethClient, nil) nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmClient) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, configtest.NewChainScopedConfig(t, nil).EVM(), &testCheckerFactory{}, false, nonceTracker) ctx := tests.Context(t) require.NoError(t, commonutils.JustError(db.Exec(`SET CONSTRAINTS fk_pipeline_runs_pruning_key DEFERRED`))) @@ -1181,6 +1179,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { // same as the parent test, but callback is set by ctor t.Run("callback set by ctor", func(t *testing.T) { + evmcfg := configtest.NewChainScopedConfig(t, nil) estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { return gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), nil, evmcfg.EVM().GasEstimator().BlockHistory(), lggr, nil) }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), evmcfg.EVM().GasEstimator(), ethClient) @@ -1396,7 +1395,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { underpricedError := "transaction underpriced" localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) etx := mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, testutils.FixtureChainID) - + evmcfg := configtest.NewChainScopedConfig(t, nil) // First was underpriced ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { return tx.Nonce() == localNextNonce && tx.GasPrice().Cmp(evmcfg.EVM().GasEstimator().PriceDefault().ToInt()) == 0 @@ -1506,16 +1505,16 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { // In this scenario the node operator REALLY fucked up and set the bump // to zero (even though that should not be possible due to config // validation) - evmcfg2 := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { c.GasEstimator.BumpMin = assets.NewWeiI(0) c.GasEstimator.BumpPercent = ptr[uint16](0) }) - eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg2, &testCheckerFactory{}, false, nonceTracker) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, testutils.FixtureChainID) // First was underpriced ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { - return tx.Nonce() == localNextNonce && tx.GasPrice().Cmp(evmcfg2.EVM().GasEstimator().PriceDefault().ToInt()) == 0 + return tx.Nonce() == localNextNonce && tx.GasPrice().Cmp(evmcfg.EVM().GasEstimator().PriceDefault().ToInt()) == 0 }), fromAddress).Return(multinode.Underpriced, errors.New(underpricedError)).Once() // Do the thing @@ -1595,14 +1594,14 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { // In this scenario the node operator REALLY fucked up and set the bump // to zero (even though that should not be possible due to config // validation) - evmcfg2 := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { c.GasEstimator.EIP1559DynamicFees = ptr(true) c.GasEstimator.BumpMin = assets.NewWeiI(0) c.GasEstimator.BumpPercent = ptr[uint16](0) }) localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(localNextNonce, nil).Once() - eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg2, &testCheckerFactory{}, false, nonceTracker) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, testutils.FixtureChainID) underpricedError := "transaction underpriced" localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress) @@ -1628,13 +1627,13 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { gasTipCapDefault := assets.NewWeiI(42) - evmcfg2 := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { c.GasEstimator.EIP1559DynamicFees = ptr(true) c.GasEstimator.TipCapDefault = gasTipCapDefault }) localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(localNextNonce, nil).Once() - eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg2, &testCheckerFactory{}, false, nonceTracker) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) // Second was underpriced but above minimum ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { @@ -1642,11 +1641,11 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { }), fromAddress).Return(multinode.Underpriced, errors.New(underpricedError)).Once() // Resend at the bumped price ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { - return tx.Nonce() == localNextNonce && tx.GasTipCap().Cmp(big.NewInt(0).Add(gasTipCapDefault.ToInt(), evmcfg2.EVM().GasEstimator().BumpMin().ToInt())) == 0 + return tx.Nonce() == localNextNonce && tx.GasTipCap().Cmp(big.NewInt(0).Add(gasTipCapDefault.ToInt(), evmcfg.EVM().GasEstimator().BumpMin().ToInt())) == 0 }), fromAddress).Return(multinode.Underpriced, errors.New(underpricedError)).Once() // Final bump succeeds ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { - return tx.Nonce() == localNextNonce && tx.GasTipCap().Cmp(big.NewInt(0).Add(gasTipCapDefault.ToInt(), big.NewInt(0).Mul(evmcfg2.EVM().GasEstimator().BumpMin().ToInt(), big.NewInt(2)))) == 0 + return tx.Nonce() == localNextNonce && tx.GasTipCap().Cmp(big.NewInt(0).Add(gasTipCapDefault.ToInt(), big.NewInt(0).Mul(evmcfg.EVM().GasEstimator().BumpMin().ToInt(), big.NewInt(2)))) == 0 }), fromAddress).Return(multinode.Successful, nil).Once() retryable, err := eb2.ProcessUnstartedTxs(ctx, fromAddress) @@ -1747,7 +1746,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Once() lggr := logger.Test(t) nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, kst, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, kst, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) ctx := tests.Context(t) _, err := nonceTracker.GetNextSequence(ctx, fromAddress) require.NoError(t, err) @@ -1795,7 +1794,7 @@ func TestEthBroadcaster_Trigger(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) lggr := logger.Test(t) nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), &testCheckerFactory{}, false, nonceTracker) eb.Trigger(testutils.NewAddress()) eb.Trigger(testutils.NewAddress()) @@ -1865,7 +1864,7 @@ func TestEthBroadcaster_NonceTracker_InProgressTx(t *testing.T) { // Tx with nonce 0 in DB will set local nonce map to value to 1 mustInsertInProgressEthTxWithAttempt(t, txStore, evmtypes.Nonce(inProgressTxNonce), fromAddress) nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) - eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg, checkerFactory, false, nonceTracker) + eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, dbListenerCfg, evmcfg.EVM(), checkerFactory, false, nonceTracker) // Check the local nonce map was set to 1 higher than in-progress tx nonce nonce := getLocalNextNonce(t, nonceTracker, fromAddress) diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index fd1b5c154f9..c1b19992a09 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/evm/config/toml" "github.com/smartcontractkit/chainlink-framework/chains/fees" txmgrcommon "github.com/smartcontractkit/chainlink-framework/chains/txmgr" @@ -29,13 +30,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/evm/assets" "github.com/smartcontractkit/chainlink/v2/evm/client" "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" evmconfig "github.com/smartcontractkit/chainlink/v2/evm/config" + "github.com/smartcontractkit/chainlink/v2/evm/config/configtest" "github.com/smartcontractkit/chainlink/v2/evm/gas" gasmocks "github.com/smartcontractkit/chainlink/v2/evm/gas/mocks" "github.com/smartcontractkit/chainlink/v2/evm/keystore" @@ -45,11 +44,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/evm/utils" ) -func newTestChainScopedConfig(t *testing.T) (chainlink.GeneralConfig, evmconfig.ChainScopedConfig) { - cfg := configtest.NewTestGeneralConfig(t) - return cfg, evmtest.NewChainScopedConfig(t, cfg) -} - func newBroadcastLegacyEthTxAttempt(t *testing.T, etxID int64, gasPrice ...int64) txmgr.TxAttempt { attempt := cltest.NewLegacyEthTxAttempt(t, etxID) attempt.State = txmgrtypes.TxAttemptBroadcast @@ -107,7 +101,7 @@ func TestEthConfirmer_Lifecycle(t *testing.T) { t.Parallel() db := testutils.NewSqlxDB(t) - gconfig, config := newTestChainScopedConfig(t) + config := configtest.NewChainScopedConfig(t, nil) txStore := newTxStore(t, db) ethClient := clienttest.NewClientWithDefaultChainID(t) @@ -124,7 +118,7 @@ func TestEthConfirmer_Lifecycle(t *testing.T) { txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), config.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ethKeyStore, txBuilder, lggr, stuckTxDetector, ht) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), confirmerConfig{}, ethKeyStore, txBuilder, lggr, stuckTxDetector, ht) ctx := tests.Context(t) // Can't close unstarted instance @@ -187,12 +181,11 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { t.Parallel() db := testutils.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = assets.GWei(500) - }) txStore := cltest.NewTestTxStore(t, db) ethClient := clienttest.NewClientWithDefaultChainID(t) - evmcfg := evmtest.NewChainScopedConfig(t, cfg) + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = assets.GWei(500) + }) ctx := tests.Context(t) blockNum := int64(100) @@ -207,7 +200,7 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx1 := mustInsertConfirmedEthTxWithReceipt(t, txStore, fromAddress, 0, blockNum) etx2 := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 4, fromAddress, 1, blockNum, assets.NewWeiI(1)) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(1), nil).Maybe() require.NoError(t, ec.CheckForConfirmation(ctx, &head)) @@ -227,7 +220,7 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) // Insert confirmed transaction that stays confirmed etx := mustInsertConfirmedEthTxWithReceipt(t, txStore, fromAddress, 0, blockNum) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Maybe() require.NoError(t, ec.CheckForConfirmation(ctx, &head)) @@ -247,7 +240,7 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { // Insert terminally stuck transaction that stays fatal error etx := mustInsertTerminallyStuckTxWithAttempt(t, txStore, fromAddress, 0, blockNum) mustInsertEthReceipt(t, txStore, blockNum, utils.NewHash(), etx.TxAttempts[0].Hash) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(0), nil).Maybe() require.NoError(t, ec.CheckForConfirmation(ctx, &head)) @@ -277,7 +270,7 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { mustInsertEthReceipt(t, txStore, blockNum, utils.NewHash(), etx4.TxAttempts[0].Hash) // Insert unconfirmed transaction that is untouched etx5 := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 4, fromAddress, 1, blockNum, assets.NewWeiI(1)) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(2), nil).Maybe() require.NoError(t, ec.CheckForConfirmation(ctx, &head)) @@ -325,7 +318,7 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, blockNum, assets.NewWeiI(1)) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(1), nil).Maybe() require.NoError(t, ec.CheckForConfirmation(ctx, &head)) @@ -340,7 +333,7 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := mustInsertUnconfirmedEthTxWithBroadcastPurgeAttempt(t, txStore, 0, fromAddress) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(1), nil).Maybe() require.NoError(t, ec.CheckForConfirmation(ctx, &head)) @@ -366,7 +359,7 @@ func TestEthConfirmer_CheckForConfirmation(t *testing.T) { etx4 := mustInsertUnconfirmedEthTxWithBroadcastPurgeAttempt(t, txStore, 3, fromAddress) // Insert unconfirmed transact that is not confirmed and left untouched etx5 := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 4, fromAddress, 1, blockNum, assets.NewWeiI(1)) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("NonceAt", mock.Anything, fromAddress, mock.Anything).Return(uint64(4), nil).Maybe() require.NoError(t, ec.CheckForConfirmation(ctx, &head)) @@ -416,13 +409,12 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) { t.Parallel() db := testutils.NewSqlxDB(t) - cfg := configtest.NewTestGeneralConfig(t) txStore := cltest.NewTestTxStore(t, db) ctx := tests.Context(t) ethClient := clienttest.NewClientWithDefaultChainID(t) - evmcfg := evmtest.NewChainScopedConfig(t, cfg) + evmcfg := configtest.NewChainScopedConfig(t, nil) ethKeyStore := cltest.NewKeyStore(t, db).Eth() @@ -443,7 +435,7 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) { lggr := logger.Test(t) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) t.Run("returns nothing when there are no transactions", func(t *testing.T) { etxs, err := ec.FindTxsRequiringRebroadcast(tests.Context(t), lggr, evmFromAddress, currentHead, gasBumpThreshold, 10, 0, &cltest.FixtureChainID) @@ -713,12 +705,11 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing ethClient := clienttest.NewClientWithDefaultChainID(t) t.Run("should retry previous attempt if connectivity check failed for legacy transactions", func(t *testing.T) { - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(false) - c.EVM[0].GasEstimator.BlockHistory.BlockHistorySize = ptr[uint16](2) - c.EVM[0].GasEstimator.BlockHistory.CheckInclusionBlocks = ptr[uint16](4) + ccfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.EIP1559DynamicFees = ptr(false) + c.GasEstimator.BlockHistory.BlockHistorySize = ptr[uint16](2) + c.GasEstimator.BlockHistory.CheckInclusionBlocks = ptr[uint16](4) }) - ccfg := evmtest.NewChainScopedConfig(t, cfg) ctx := tests.Context(t) txStore := cltest.NewTestTxStore(t, db) @@ -737,7 +728,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), ccfg.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) // Create confirmer with necessary state - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr, stuckTxDetector, ht) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), confirmerConfig{}, kst, txBuilder, lggr, stuckTxDetector, ht) servicetest.Run(t, ec) currentHead := int64(30) oldEnough := int64(15) @@ -762,12 +753,11 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing }) t.Run("should retry previous attempt if connectivity check failed for dynamic transactions", func(t *testing.T) { - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true) - c.EVM[0].GasEstimator.BlockHistory.BlockHistorySize = ptr[uint16](2) - c.EVM[0].GasEstimator.BlockHistory.CheckInclusionBlocks = ptr[uint16](4) + ccfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.EIP1559DynamicFees = ptr(true) + c.GasEstimator.BlockHistory.BlockHistorySize = ptr[uint16](2) + c.GasEstimator.BlockHistory.CheckInclusionBlocks = ptr[uint16](4) }) - ccfg := evmtest.NewChainScopedConfig(t, cfg) ctx := tests.Context(t) txStore := cltest.NewTestTxStore(t, db) @@ -786,7 +776,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), ccfg.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr, stuckTxDetector, ht) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), confirmerConfig{}, kst, txBuilder, lggr, stuckTxDetector, ht) servicetest.Run(t, ec) currentHead := int64(30) oldEnough := int64(15) @@ -815,16 +805,15 @@ func TestEthConfirmer_RebroadcastWhereNecessary_MaxFeeScenario(t *testing.T) { t.Parallel() db := testutils.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = assets.GWei(500) - }) txStore := cltest.NewTestTxStore(t, db) ctx := tests.Context(t) ethClient := clienttest.NewClientWithDefaultChainID(t) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - evmcfg := evmtest.NewChainScopedConfig(t, cfg) + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = assets.GWei(500) + }) _, _ = cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) @@ -833,7 +822,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_MaxFeeScenario(t *testing.T) { addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() // Use a mock keystore for this test - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, kst, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, kst, nil) currentHead := int64(30) oldEnough := int64(19) nonce := int64(0) @@ -882,13 +871,12 @@ func TestEthConfirmer_RebroadcastWhereNecessary_MaxFeeScenario(t *testing.T) { func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { t.Parallel() - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = assets.GWei(500) - c.EVM[0].GasEstimator.BumpMin = assets.NewWeiI(0) - }) ctx := tests.Context(t) ethClient := clienttest.NewClientWithDefaultChainID(t) - evmcfg := evmtest.NewChainScopedConfig(t, cfg) + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = assets.GWei(500) + c.GasEstimator.BumpMin = assets.NewWeiI(0) + }) currentHead := int64(30) t.Run("does nothing if no transactions require bumping", func(t *testing.T) { @@ -897,7 +885,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) require.NoError(t, ec.RebroadcastWhereNecessary(ctx, currentHead)) }) @@ -917,7 +905,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { }), mock.Anything).Return(nil, errors.New("signing error")).Once() // Use a mock keystore for this test - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, kst, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, kst, nil) err := ec.RebroadcastWhereNecessary(ctx, currentHead) require.Error(t, err) @@ -936,7 +924,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, 25, assets.NewWeiI(100)) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -956,7 +944,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) latestGasPrice := assets.GWei(20) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, 25, latestGasPrice) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -982,7 +970,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := mustInsertUnconfirmedEthTxWithAttemptState(t, txStore, 0, fromAddress, txmgrtypes.TxAttemptBroadcast) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) require.NoError(t, ec.RebroadcastWhereNecessary(ctx, currentHead)) var err error @@ -999,7 +987,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) latestGasPrice := assets.GWei(20) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, 25, latestGasPrice) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1026,7 +1014,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) latestGasPrice := assets.GWei(20) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, 25, latestGasPrice) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1057,7 +1045,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { latestGasPrice := assets.GWei(20) broadcastBlockNum := int64(25) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, broadcastBlockNum, latestGasPrice) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1108,7 +1096,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { latestGasPrice := assets.GWei(20) broadcastBlockNum := int64(25) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, broadcastBlockNum, latestGasPrice) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1135,16 +1123,15 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) priceMax := assets.GWei(30) - gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = priceMax + newCfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = priceMax }) - newCfg := evmtest.NewChainScopedConfig(t, gcfg) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) broadcastBlockNum := int64(25) currentAttemptPrice := priceMax.Sub(assets.GWei(1)) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, broadcastBlockNum, currentAttemptPrice) - ec := newEthConfirmer(t, txStore, ethClient, cfg, newCfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, newCfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1167,15 +1154,14 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) priceMax := assets.GWei(30) - gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = priceMax + newCfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = priceMax }) - newCfg := evmtest.NewChainScopedConfig(t, gcfg) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) broadcastBlockNum := int64(25) etx := mustInsertUnconfirmedTxWithBroadcastAttempts(t, txStore, 0, fromAddress, 1, broadcastBlockNum, priceMax) - ec := newEthConfirmer(t, txStore, ethClient, cfg, newCfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, newCfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1197,16 +1183,15 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { t.Run("EIP-1559: bumps using EIP-1559 rules when existing attempts are of type 0x2", func(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.BumpMin = assets.GWei(1) + newCfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.BumpMin = assets.GWei(1) }) - newCfg := evmtest.NewChainScopedConfig(t, gcfg) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := mustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, 0, fromAddress) err := txStore.UpdateTxAttemptBroadcastBeforeBlockNum(ctx, etx.ID, uint(25)) require.NoError(t, err) - ec := newEthConfirmer(t, txStore, ethClient, cfg, newCfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, newCfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1229,16 +1214,15 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { t.Run("EIP-1559: resubmits at the old price and does not create a new attempt if one of the bumped EIP-1559 transactions would have its tip cap exceed EVM.GasEstimator.PriceMax", func(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = assets.NewWeiI(1) + newCfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = assets.NewWeiI(1) }) - newCfg := evmtest.NewChainScopedConfig(t, gcfg) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := mustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, 0, fromAddress) err := txStore.UpdateTxAttemptBroadcastBeforeBlockNum(ctx, etx.ID, uint(25)) require.NoError(t, err) - ec := newEthConfirmer(t, txStore, ethClient, cfg, newCfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, newCfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1259,17 +1243,16 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { t.Run("EIP-1559: re-bumps attempt if initial bump is underpriced because the bumped gas price is insufficiently higher than the previous one", func(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) - gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.BumpMin = assets.GWei(1) + newCfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.BumpMin = assets.GWei(1) }) - newCfg := evmtest.NewChainScopedConfig(t, gcfg) // NOTE: This test case was empirically impossible when I tried it on eth mainnet (any EIP1559 transaction with a higher tip cap is accepted even if it's only 1 wei more) but appears to be possible on Polygon/Matic, probably due to poor design that applies the 10% minimum to the overall value (base fee + tip cap) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := mustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, 0, fromAddress) err := txStore.UpdateTxAttemptBroadcastBeforeBlockNum(ctx, etx.ID, uint(25)) require.NoError(t, err) - ec := newEthConfirmer(t, txStore, ethClient, cfg, newCfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, newCfg, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx.Sequence) //nolint:gosec // disable G115 @@ -1296,14 +1279,13 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh t.Parallel() db := testutils.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = assets.GWei(500) - }) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - evmcfg := evmtest.NewChainScopedConfig(t, cfg) + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = assets.GWei(500) + }) _, _ = cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) @@ -1318,7 +1300,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh t.Run("terminally underpriced transaction with in_progress attempt is retried with more gas", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, kst, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, kst, nil) originalBroadcastAt := time.Unix(1616509100, 0) etx := mustInsertUnconfirmedEthTxWithAttemptState(t, txStore, nonce, fromAddress, txmgrtypes.TxAttemptInProgress, originalBroadcastAt) @@ -1342,7 +1324,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh t.Run("multiple gas bumps with existing broadcast attempts are retried with more gas until success in legacy mode", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, kst, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, kst, nil) etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ @@ -1374,7 +1356,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh t.Run("multiple gas bumps with existing broadcast attempts are retried with more gas until success in EIP-1559 mode", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, kst, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, kst, nil) etx := mustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, nonce, fromAddress) nonce++ @@ -1422,7 +1404,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) { // keyStates, err := ethKeyStore.GetStatesForKeys(keys) // require.NoError(t, err) - gconfig, config := newTestChainScopedConfig(t) + config := configtest.NewChainScopedConfig(t, nil) currentHead := int64(30) oldEnough := int64(19) nonce := int64(0) @@ -1438,7 +1420,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) { insufficientEthError := errors.New("insufficient funds for gas * price + value") t.Run("saves attempt with state 'insufficient_eth' if eth node returns this error", func(t *testing.T) { - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) expectedBumpedGasPrice := big.NewInt(20000000000) require.Greater(t, expectedBumpedGasPrice.Int64(), attempt1_1.TxFee.GasPrice.ToInt().Int64()) @@ -1464,7 +1446,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) { }) t.Run("does not bump gas when previous error was 'out of eth', instead resubmits existing transaction", func(t *testing.T) { - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) expectedBumpedGasPrice := big.NewInt(20000000000) require.Greater(t, expectedBumpedGasPrice.Int64(), attempt1_1.TxFee.GasPrice.ToInt().Int64()) @@ -1489,7 +1471,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) { }) t.Run("saves the attempt as broadcast after node wallet has been topped up with sufficient balance", func(t *testing.T) { - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) expectedBumpedGasPrice := big.NewInt(20000000000) require.Greater(t, expectedBumpedGasPrice.Int64(), attempt1_1.TxFee.GasPrice.ToInt().Int64()) @@ -1517,11 +1499,10 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) { depth := 2 etxCount := 4 - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.BumpTxDepth = ptr(uint32(depth)) + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.BumpTxDepth = ptr(uint32(depth)) }) - evmcfg := evmtest.NewChainScopedConfig(t, cfg) - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) for i := 0; i < etxCount; i++ { n := nonce @@ -1546,9 +1527,6 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyStuckError(t *testing. t.Parallel() db := testutils.NewSqlxDB(t) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.PriceMax = assets.GWei(500) - }) txStore := cltest.NewTestTxStore(t, db) ctx := tests.Context(t) @@ -1556,10 +1534,12 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyStuckError(t *testing. ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) - evmcfg := evmtest.NewChainScopedConfig(t, cfg) + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.PriceMax = assets.GWei(500) + }) // Use a mock keystore for this test - ec := newEthConfirmer(t, txStore, ethClient, cfg, evmcfg, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, evmcfg, ethKeyStore, nil) currentHead := int64(30) oldEnough := int64(19) nonce := int64(0) @@ -1603,7 +1583,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) - gconfig, config := newTestChainScopedConfig(t) + config := configtest.NewChainScopedConfig(t, nil) mustCreateUnstartedGeneratedTx(t, txStore, fromAddress, config.EVM().ChainID()) mustInsertInProgressEthTx(t, txStore, 0, fromAddress) etx1 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress) @@ -1614,7 +1594,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { t.Run("rebroadcasts one eth_tx if it falls within in nonce range", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx1.Sequence) && @@ -1629,7 +1609,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { t.Run("uses default gas limit if overrideGasLimit is 0", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx1.Sequence) && @@ -1644,7 +1624,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { t.Run("rebroadcasts several eth_txes in nonce range", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.GasPrice.Int64() && tx.Gas() == overrideGasLimit @@ -1658,7 +1638,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { t.Run("broadcasts zero transactions if eth_tx doesn't exist for that nonce", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(1) @@ -1684,7 +1664,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { t.Run("zero transactions use default gas limit if override wasn't specified", func(t *testing.T) { ethClient := clienttest.NewClientWithDefaultChainID(t) - ec := newEthConfirmer(t, txStore, ethClient, gconfig, config, ethKeyStore, nil) + ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(0) && tx.GasPrice().Int64() == gasPriceWei.GasPrice.Int64() && tx.Gas() == config.EVM().GasEstimator().LimitDefault() @@ -1716,18 +1696,17 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { autoPurgeThreshold := uint32(5) autoPurgeMinAttempts := uint32(3) limitDefault := uint64(100) - cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.LimitDefault = ptr(limitDefault) - c.EVM[0].Transactions.AutoPurge.Enabled = ptr(true) - c.EVM[0].Transactions.AutoPurge.Threshold = ptr(autoPurgeThreshold) - c.EVM[0].Transactions.AutoPurge.MinAttempts = ptr(autoPurgeMinAttempts) + evmcfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.GasEstimator.LimitDefault = ptr(limitDefault) + c.Transactions.AutoPurge.Enabled = ptr(true) + c.Transactions.AutoPurge.Threshold = ptr(autoPurgeThreshold) + c.Transactions.AutoPurge.MinAttempts = ptr(autoPurgeMinAttempts) }) - evmcfg := evmtest.NewChainScopedConfig(t, cfg) ge := evmcfg.EVM().GasEstimator() txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), evmcfg.EVM().Transactions().AutoPurge(), feeEstimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database(), ethKeyStore, txBuilder, lggr, stuckTxDetector, ht) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), confirmerConfig{}, ethKeyStore, txBuilder, lggr, stuckTxDetector, ht) fn := func(ctx context.Context, id uuid.UUID, result interface{}, err error) error { require.ErrorContains(t, err, client.TerminallyStuckMsg) return nil @@ -1795,7 +1774,7 @@ func TestEthConfirmer_ProcessStuckTransactions(t *testing.T) { func ptr[T any](t T) *T { return &t } -func newEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient client.Client, gconfig chainlink.GeneralConfig, config evmconfig.ChainScopedConfig, ks keystore.Eth, fn txmgrcommon.ResumeCallback) *txmgr.Confirmer { +func newEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient client.Client, config evmconfig.ChainScopedConfig, ks keystore.Eth, fn txmgrcommon.ResumeCallback) *txmgr.Confirmer { lggr := logger.Test(t) ge := config.EVM().GasEstimator() estimator := gas.NewEvmFeeEstimator(lggr, func(lggr logger.Logger) gas.EvmEstimator { @@ -1804,8 +1783,16 @@ func newEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient client.Cl txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ks, estimator) stuckTxDetector := txmgr.NewStuckTxDetector(lggr, testutils.FixtureChainID, "", assets.NewWei(assets.NewEth(100).ToInt()), config.EVM().Transactions().AutoPurge(), estimator, txStore, ethClient) ht := headtracker.NewSimulatedHeadTracker(ethClient, true, 0) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ks, txBuilder, lggr, stuckTxDetector, ht) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), confirmerConfig{}, ks, txBuilder, lggr, stuckTxDetector, ht) ec.SetResumeCallback(fn) servicetest.Run(t, ec) return ec } + +var _ txmgrtypes.ConfirmerDatabaseConfig = confirmerConfig{} + +type confirmerConfig struct{} + +func (d confirmerConfig) DefaultQueryTimeout() time.Duration { + return 10 * time.Second +} diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index 495260d0ca4..e23da197fda 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -23,12 +23,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/evm/assets" "github.com/smartcontractkit/chainlink/v2/evm/client" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" + "github.com/smartcontractkit/chainlink/v2/evm/config/configtest" + "github.com/smartcontractkit/chainlink/v2/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/evm/gas" "github.com/smartcontractkit/chainlink/v2/evm/testutils" "github.com/smartcontractkit/chainlink/v2/evm/types" @@ -373,10 +372,10 @@ func TestORM_SetBroadcastBeforeBlockNum(t *testing.T) { t.Parallel() db := testutils.NewSqlxDB(t) - _, cfg := newTestChainScopedConfig(t) + cfg := configtest.NewChainScopedConfig(t, nil) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) chainID := ethClient.ConfiguredChainID() @@ -552,7 +551,7 @@ func TestORM_GetInProgressTxAttempts(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) // insert etx with attempt @@ -572,7 +571,7 @@ func TestORM_FindTxesPendingCallback(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) testutils.MustExec(t, db, `SET CONSTRAINTS fk_pipeline_runs_pruning_key DEFERRED`) @@ -605,7 +604,7 @@ func TestORM_FindTxesPendingCallback(t *testing.T) { testutils.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, min_confirmations = $2, signal_callback = TRUE WHERE id = $3`, &tr1.ID, minConfirmations, etx1.ID) // Callback to pipeline service completed. Should be ignored - run2 := cltest.MustInsertPipelineRunWithStatus(t, db, 0, pipeline.RunStatusCompleted, 0) + run2 := cltest.MustInsertPipelineRunWithStatus(t, db, 0, "completed", 0) tr2 := cltest.MustInsertUnfinishedPipelineTaskRun(t, db, run2.ID) etx2 := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 4, 1, fromAddress) testutils.MustExec(t, db, `UPDATE evm.txes SET meta='{"FailOnRevert": false}'`) @@ -659,7 +658,7 @@ func TestORM_FindTxesPendingCallback(t *testing.T) { func Test_FindTxWithIdempotencyKey(t *testing.T) { t.Parallel() db := testutils.NewSqlxDB(t) - _, cfg := newTestChainScopedConfig(t) + cfg := configtest.NewChainScopedConfig(t, nil) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) @@ -787,7 +786,7 @@ func TestORM_FindEarliestUnconfirmedBroadcastTime(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) t.Run("no unconfirmed eth txes", func(t *testing.T) { @@ -810,7 +809,7 @@ func TestORM_FindEarliestUnconfirmedTxAttemptBlock(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) _, fromAddress2 := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) @@ -977,7 +976,7 @@ func TestORM_FindTxsRequiringGasBump(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) currentBlockNum := int64(10) @@ -1154,7 +1153,7 @@ func TestORM_FindNextUnstartedTransactionFromAddress(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) @@ -1276,15 +1275,13 @@ func TestORM_UpdateTxUnstartedToInProgress(t *testing.T) { require.Len(t, etx.TxAttempts, 1) zero := commonconfig.MustNewDuration(time.Duration(0)) - evmCfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].Chain.Transactions.ReaperInterval = zero - c.EVM[0].Chain.Transactions.ReaperThreshold = zero - c.EVM[0].Chain.Transactions.ResendAfterThreshold = zero + ccfg := configtest.NewChainScopedConfig(t, func(c *toml.EVMConfig) { + c.Transactions.ReaperInterval = zero + c.Transactions.ReaperThreshold = zero + c.Transactions.ResendAfterThreshold = zero }) - - ccfg := evmtest.NewChainScopedConfig(t, evmCfg) evmTxmCfg := txmgr.NewEvmTxmConfig(ccfg.EVM()) - ec := evmtest.NewEthClientMockWithDefaultChain(t) + ec := clienttest.NewClientWithDefaultChainID(t) txMgr := txmgr.NewEvmTxm(ec.ConfiguredChainID(), evmTxmCfg, ccfg.EVM().Transactions(), nil, logger.Test(t), nil, nil, nil, txStore, nil, nil, nil, nil, nil, nil) err := txMgr.XXXTestAbandon(fromAddress) // mark transaction as abandoned @@ -1346,7 +1343,7 @@ func TestORM_GetAbandonedTransactionsByBatch(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) _, enabled := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) enabledAddrs := []common.Address{enabled} @@ -1447,7 +1444,7 @@ func TestORM_HasInProgressTransaction(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) t.Run("no in progress eth transaction", func(t *testing.T) { @@ -1632,7 +1629,7 @@ func TestORM_CreateTransaction(t *testing.T) { gasLimit := uint64(1000) payload := []byte{1, 2, 3} - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) t.Run("with queue under capacity inserts eth_tx", func(t *testing.T) { subject := uuid.New() @@ -1725,7 +1722,7 @@ func TestORM_PruneUnstartedTxQueue(t *testing.T) { db := testutils.NewSqlxDB(t) txStore := txmgr.NewTxStore(db, logger.Test(t)) ethKeyStore := cltest.NewKeyStore(t, db).Eth() - evmtest.NewEthClientMockWithDefaultChain(t) + _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) t.Run("does not prune if queue has not exceeded capacity-1", func(t *testing.T) { diff --git a/core/chains/evm/txmgr/finalizer_test.go b/core/chains/evm/txmgr/finalizer_test.go index f5e423ab966..7fef240370d 100644 --- a/core/chains/evm/txmgr/finalizer_test.go +++ b/core/chains/evm/txmgr/finalizer_test.go @@ -27,10 +27,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/evm/client" "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" + "github.com/smartcontractkit/chainlink/v2/evm/config/configtest" "github.com/smartcontractkit/chainlink/v2/evm/testutils" "github.com/smartcontractkit/chainlink/v2/evm/types" "github.com/smartcontractkit/chainlink/v2/evm/utils" @@ -458,8 +457,8 @@ func TestFinalizer_ResumePendingRuns(t *testing.T) { func TestFinalizer_FetchAndStoreReceipts(t *testing.T) { t.Parallel() ctx := tests.Context(t) - cfg := configtest.NewTestGeneralConfig(t) - config := evmtest.NewChainScopedConfig(t, cfg) + + config := configtest.NewChainScopedConfig(t, nil) ethClient := clienttest.NewClientWithDefaultChainID(t) txmClient := txmgr.NewEvmTxmClient(ethClient, nil) rpcBatchSize := config.EVM().RPCDefaultBatchSize() diff --git a/core/chains/evm/txmgr/stuck_tx_detector_test.go b/core/chains/evm/txmgr/stuck_tx_detector_test.go index 38fe5674a8c..7c3eb302311 100644 --- a/core/chains/evm/txmgr/stuck_tx_detector_test.go +++ b/core/chains/evm/txmgr/stuck_tx_detector_test.go @@ -17,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/evm/config/configtest" txmgrcommon "github.com/smartcontractkit/chainlink-framework/chains/txmgr" txmgrtypes "github.com/smartcontractkit/chainlink-framework/chains/txmgr/types" @@ -108,7 +109,7 @@ func TestStuckTxDetector_FindPotentialStuckTxs(t *testing.T) { t.Parallel() db := testutils.NewSqlxDB(t) - _, config := newTestChainScopedConfig(t) + config := configtest.NewChainScopedConfig(t, nil) txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() ctx := tests.Context(t) diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index 2246bb6b64e..001ead9255e 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -34,8 +34,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/evm/assets" evmclient "github.com/smartcontractkit/chainlink/v2/evm/client" "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" @@ -541,8 +539,8 @@ func TestTxm_Reset(t *testing.T) { // Lots of boilerplate setup since we actually want to test start/stop of EthBroadcaster/EthConfirmer db := testutils.NewSqlxDB(t) - gcfg := configtest.NewTestGeneralConfig(t) - cfg := evmtest.NewChainScopedConfig(t, gcfg) + + _, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) kst := cltest.NewKeyStore(t, db) _, addr := cltest.RandomKey{}.MustInsert(t, kst.Eth()) @@ -558,14 +556,14 @@ func TestTxm_Reset(t *testing.T) { } ethClient := clienttest.NewClientWithDefaultChainID(t) - ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, nil) + ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, nil).Maybe() ethClient.On("BatchCallContextAll", mock.Anything, mock.Anything).Return(nil).Maybe() ethClient.On("PendingNonceAt", mock.Anything, addr).Return(uint64(128), nil).Maybe() ethClient.On("PendingNonceAt", mock.Anything, addr2).Return(uint64(44), nil).Maybe() - estimator, err := gas.NewEstimator(logger.Test(t), ethClient, cfg.EVM().ChainType(), ethClient.ConfiguredChainID(), cfg.EVM().GasEstimator(), nil) + estimator, err := gas.NewEstimator(logger.Test(t), ethClient, evmConfig.ChainType(), ethClient.ConfiguredChainID(), evmConfig.GasEstimator(), nil) require.NoError(t, err) - txm, err := makeTestEvmTxm(t, db, ethClient, estimator, cfg.EVM(), cfg.EVM().GasEstimator(), cfg.EVM().Transactions(), gcfg.Database(), gcfg.Database().Listener(), kst.Eth()) + txm, err := makeTestEvmTxm(t, db, ethClient, estimator, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), dbConfig, dbConfig.Listener(), kst.Eth()) require.NoError(t, err) cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, addr2) @@ -611,8 +609,8 @@ func TestTxm_GetTransactionStatus(t *testing.T) { txStore := cltest.NewTestTxStore(t, db) ethKeyStore := cltest.NewKeyStore(t, db).Eth() feeLimit := uint64(10_000) - gcfg := configtest.NewTestGeneralConfig(t) - cfg := evmtest.NewChainScopedConfig(t, gcfg) + + _, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) h99 := &evmtypes.Head{ Hash: utils.NewHash(), @@ -625,7 +623,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { } head.Parent.Store(h99) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), nil).Maybe() ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head, nil).Once() ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(head.Parent.Load(), nil).Once() @@ -634,7 +632,7 @@ func TestTxm_GetTransactionStatus(t *testing.T) { feeEstimator.On("Start", mock.Anything).Return(nil).Once() feeEstimator.On("Close", mock.Anything).Return(nil).Once() feeEstimator.On("OnNewLongestChain", mock.Anything, mock.Anything).Once() - txm, err := makeTestEvmTxm(t, db, ethClient, feeEstimator, cfg.EVM(), cfg.EVM().GasEstimator(), cfg.EVM().Transactions(), gcfg.Database(), gcfg.Database().Listener(), ethKeyStore) + txm, err := makeTestEvmTxm(t, db, ethClient, feeEstimator, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), dbConfig, dbConfig.Listener(), ethKeyStore) require.NoError(t, err) servicetest.Run(t, txm) diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 721de61e770..8d3e2251bb0 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -125,12 +125,6 @@ func (e errChainDisabled) Error() string { return fmt.Sprintf("cannot create new chain with ID %s, the chain is disabled", e.ChainID.String()) } -// TODO BCF-2509 what is this and does it need the entire app config? -type AppConfig interface { - EVMRPCEnabled() bool - toml.HasEVMConfigs -} - type FeatureConfig interface { LogPoller() bool } @@ -142,7 +136,7 @@ type ChainRelayOpts struct { } type ChainOpts struct { - AppConfig AppConfig + ChainConfigs toml.EVMConfigs DatabaseConfig txmgr.DatabaseConfig FeatureConfig FeatureConfig ListenerConfig txmgr.ListenerConfig @@ -164,8 +158,8 @@ type ChainOpts struct { func (o ChainOpts) Validate() error { var err error - if o.AppConfig == nil { - err = errors.Join(err, errors.New("nil AppConfig")) + if o.ChainConfigs == nil { + err = errors.Join(err, errors.New("nil ChainConfigs")) } if o.DatabaseConfig == nil { err = errors.Join(err, errors.New("nil DatabaseConfig")) @@ -195,11 +189,10 @@ func NewTOMLChain(ctx context.Context, chain *toml.EVMConfig, opts ChainRelayOpt return nil, err } chainID := chain.ChainID - l := opts.Logger.With("evmChainID", chainID.String()) if !chain.IsEnabled() { return nil, errChainDisabled{ChainID: chainID} } - cfg := config.NewTOMLChainScopedConfig(chain, l) + cfg := config.NewTOMLChainScopedConfig(chain) // note: per-chain validation is not necessary at this point since everything is checked earlier on boot. return newChain(ctx, cfg, chain.Nodes, opts, clientsByChainID) } @@ -209,7 +202,7 @@ func newChain(ctx context.Context, cfg *config.ChainScoped, nodes []*toml.Node, l := opts.Logger var cl client.Client var err error - if !opts.AppConfig.EVMRPCEnabled() { + if !opts.ChainConfigs.RPCEnabled() { cl = client.NewNullClient(chainID, l) } else if opts.GenEthClient == nil { cl, err = client.NewEvmClient(cfg.EVM().NodePool(), cfg.EVM(), cfg.EVM().NodePool().Errors(), l, chainID, nodes, cfg.EVM().ChainType()) @@ -223,7 +216,7 @@ func newChain(ctx context.Context, cfg *config.ChainScoped, nodes []*toml.Node, headBroadcaster := headtracker.NewHeadBroadcaster(l) headSaver := headtracker.NullSaver var headTracker httypes.HeadTracker - if !opts.AppConfig.EVMRPCEnabled() { + if !opts.ChainConfigs.RPCEnabled() { headTracker = headtracker.NullTracker } else if opts.GenHeadTracker == nil { var orm headtracker.ORM @@ -267,7 +260,7 @@ func newChain(ctx context.Context, cfg *config.ChainScoped, nodes []*toml.Node, // note: gas estimator is started as a part of the txm var txm txmgr.TxManager //nolint:gocritic // ignoring suggestion to convert to switch statement - if !opts.AppConfig.EVMRPCEnabled() { + if !opts.ChainConfigs.RPCEnabled() { txm = &txmgr.NullTxManager{ErrMsg: fmt.Sprintf("Ethereum is disabled for chain %d", chainID)} } else if !cfg.EVM().Transactions().Enabled() { txm = &txmgr.NullTxManager{ErrMsg: fmt.Sprintf("TXM disabled for chain %d", chainID)} @@ -287,13 +280,13 @@ func newChain(ctx context.Context, cfg *config.ChainScoped, nodes []*toml.Node, } var balanceMonitor monitor.BalanceMonitor - if opts.AppConfig.EVMRPCEnabled() && cfg.EVM().BalanceMonitor().Enabled() { + if opts.ChainConfigs.RPCEnabled() && cfg.EVM().BalanceMonitor().Enabled() { balanceMonitor = monitor.NewBalanceMonitor(cl, opts.KeyStore, l) headBroadcaster.Subscribe(balanceMonitor) } var logBroadcaster log.Broadcaster - if !opts.AppConfig.EVMRPCEnabled() { + if !opts.ChainConfigs.RPCEnabled() { logBroadcaster = &log.NullBroadcaster{ErrMsg: fmt.Sprintf("Ethereum is disabled for chain %d", chainID)} } else if !cfg.EVM().LogBroadcasterEnabled() { logBroadcaster = &log.NullBroadcaster{ErrMsg: fmt.Sprintf("LogBroadcaster disabled for chain %d", chainID)} diff --git a/core/chains/legacyevm/chain_test.go b/core/chains/legacyevm/chain_test.go index be5a8b76917..16553c52c98 100644 --- a/core/chains/legacyevm/chain_test.go +++ b/core/chains/legacyevm/chain_test.go @@ -38,7 +38,7 @@ func TestChainOpts_Validate(t *testing.T) { { name: "valid", opts: legacyevm.ChainOpts{ - AppConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), ListenerConfig: cfg.Database().Listener(), FeatureConfig: cfg.Feature(), diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 144bd4a953e..f182875d2da 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -257,7 +257,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G evmFactoryCfg := chainlink.EVMFactoryConfig{ CSAETHKeystore: keyStore, ChainOpts: legacyevm.ChainOpts{ - AppConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), ListenerConfig: cfg.Database().Listener(), FeatureConfig: cfg.Feature(), diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 331432299a8..5e86b17c575 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -9,12 +9,18 @@ import ( "testing" "time" + gethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "github.com/urfave/cli" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" "github.com/smartcontractkit/chainlink-framework/multinode" - evmrelayer "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" @@ -30,18 +36,13 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" + evmrelayer "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/sessions/localauth" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" "github.com/smartcontractkit/chainlink/v2/plugins" - - gethTypes "github.com/ethereum/go-ethereum/core/types" - "github.com/google/uuid" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/urfave/cli" ) func genTestEVMRelayers(t *testing.T, cfg chainlink.GeneralConfig, ds sqlutil.DataSource, ks evmrelayer.CSAETHKeystore) *chainlink.CoreRelayerChainInteroperators { @@ -54,7 +55,7 @@ func genTestEVMRelayers(t *testing.T, cfg chainlink.GeneralConfig, ds sqlutil.Da relayers, err := chainlink.NewCoreRelayerChainInteroperators(chainlink.InitEVM(testutils.Context(t), f, chainlink.EVMFactoryConfig{ ChainOpts: legacyevm.ChainOpts{ - AppConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), ListenerConfig: cfg.Database().Listener(), FeatureConfig: cfg.Feature(), @@ -291,7 +292,7 @@ func TestShell_RebroadcastTransactions_Txm(t *testing.T) { app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) app.On("GetConfig").Return(config) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) legacy := cltest.NewLegacyChainsWithMockChain(t, ethClient, config) mockRelayerChainInteroperators := &chainlinkmocks.FakeRelayerChainInteroperators{EVMChains: legacy} @@ -373,7 +374,7 @@ func TestShell_RebroadcastTransactions_OutsideRange_Txm(t *testing.T) { app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) app.On("GetConfig").Return(config) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("Dial", mock.Anything).Return(nil) legacy := cltest.NewLegacyChainsWithMockChain(t, ethClient, config) @@ -451,7 +452,7 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) { app.On("GetDB").Maybe().Return(sqlxDB) app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) ethClient.On("Dial", mock.Anything).Return(nil) legacy := cltest.NewLegacyChainsWithMockChain(t, ethClient, config) diff --git a/core/config/app_config.go b/core/config/app_config.go index 4ce8873bb96..d4ef27b6305 100644 --- a/core/config/app_config.go +++ b/core/config/app_config.go @@ -20,7 +20,6 @@ type AppConfig interface { ShutdownGracePeriod() time.Duration InsecureFastScrypt() bool EVMEnabled() bool - EVMRPCEnabled() bool CosmosEnabled() bool SolanaEnabled() bool StarkNetEnabled() bool diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 132dd60a8f9..ae3b8c5e243 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -436,7 +436,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn evmOpts := chainlink.EVMFactoryConfig{ ChainOpts: legacyevm.ChainOpts{ - AppConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), ListenerConfig: cfg.Database().Listener(), FeatureConfig: cfg.Feature(), diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index b2ad81bb2c2..24922715eda 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -28,6 +28,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/web" evmclient "github.com/smartcontractkit/chainlink/v2/evm/client" + "github.com/smartcontractkit/chainlink/v2/evm/config/toml" evmtypes "github.com/smartcontractkit/chainlink/v2/evm/types" ) @@ -398,7 +399,7 @@ func (m MockPasswordPrompter) Prompt() string { return m.Password } -func NewLegacyChainsWithMockChain(t testing.TB, ethClient evmclient.Client, cfg legacyevm.AppConfig) legacyevm.LegacyChainContainer { +func NewLegacyChainsWithMockChain(t testing.TB, ethClient evmclient.Client, cfg toml.HasEVMConfigs) legacyevm.LegacyChainContainer { ch := new(evmmocks.Chain) ch.On("Client").Return(ethClient) ch.On("Logger").Return(logger.TestLogger(t)) @@ -410,7 +411,7 @@ func NewLegacyChainsWithMockChain(t testing.TB, ethClient evmclient.Client, cfg return NewLegacyChainsWithChain(ch, cfg) } -func NewLegacyChainsWithMockChainAndTxManager(t testing.TB, ethClient evmclient.Client, cfg legacyevm.AppConfig, txm txmgr.TxManager) legacyevm.LegacyChainContainer { +func NewLegacyChainsWithMockChainAndTxManager(t testing.TB, ethClient evmclient.Client, cfg toml.HasEVMConfigs, txm txmgr.TxManager) legacyevm.LegacyChainContainer { ch := new(evmmocks.Chain) ch.On("Client").Return(ethClient) ch.On("Logger").Return(logger.TestLogger(t)) @@ -422,7 +423,7 @@ func NewLegacyChainsWithMockChainAndTxManager(t testing.TB, ethClient evmclient. return NewLegacyChainsWithChain(ch, cfg) } -func NewLegacyChainsWithChain(ch legacyevm.Chain, cfg legacyevm.AppConfig) legacyevm.LegacyChainContainer { +func NewLegacyChainsWithChain(ch legacyevm.Chain, cfg toml.HasEVMConfigs) legacyevm.LegacyChainContainer { m := map[string]legacyevm.Chain{ch.ID().String(): ch} return legacyevm.NewLegacyChains(m, cfg.EVMConfigs()) } diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index c69ce1defc5..929a9b22aaf 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -1286,7 +1286,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { require.NoError(t, kst.Unlock(ctx, cltest.Password)) chainsAndConfig := evmtest.NewLegacyChainsAndConfig(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/internal/testutils/evmtest/evmtest.go b/core/internal/testutils/evmtest/evmtest.go index 685736827db..6bfab4166c5 100644 --- a/core/internal/testutils/evmtest/evmtest.go +++ b/core/internal/testutils/evmtest/evmtest.go @@ -36,7 +36,7 @@ import ( ubig "github.com/smartcontractkit/chainlink/v2/evm/utils/big" ) -func NewChainScopedConfig(t testing.TB, cfg legacyevm.AppConfig) evmconfig.ChainScopedConfig { +func NewChainScopedConfig(t testing.TB, cfg configtoml.HasEVMConfigs) evmconfig.ChainScopedConfig { var evmCfg *configtoml.EVMConfig if len(cfg.EVMConfigs()) > 0 { evmCfg = cfg.EVMConfigs()[0] @@ -48,14 +48,14 @@ func NewChainScopedConfig(t testing.TB, cfg legacyevm.AppConfig) evmconfig.Chain } } - return evmconfig.NewTOMLChainScopedConfig(evmCfg, logger.TestLogger(t)) + return evmconfig.NewTOMLChainScopedConfig(evmCfg) } type TestChainOpts struct { Client evmclient.Client LogBroadcaster log.Broadcaster LogPoller logpoller.LogPoller - GeneralConfig legacyevm.AppConfig + ChainConfigs configtoml.EVMConfigs DatabaseConfig txmgr.DatabaseConfig FeatureConfig legacyevm.FeatureConfig ListenerConfig txmgr.ListenerConfig @@ -90,7 +90,7 @@ func NewChainOpts(t testing.TB, testopts TestChainOpts) legacyevm.ChainRelayOpts Logger: lggr, KeyStore: testopts.KeyStore, ChainOpts: legacyevm.ChainOpts{ - AppConfig: testopts.GeneralConfig, + ChainConfigs: testopts.ChainConfigs, DatabaseConfig: testopts.DatabaseConfig, ListenerConfig: testopts.ListenerConfig, FeatureConfig: testopts.FeatureConfig, @@ -103,7 +103,7 @@ func NewChainOpts(t testing.TB, testopts TestChainOpts) legacyevm.ChainRelayOpts if testopts.Client != nil { return testopts.Client } - return evmclient.NewNullClient(MustGetDefaultChainID(t, testopts.GeneralConfig.EVMConfigs()), logger.TestLogger(t)) + return evmclient.NewNullClient(MustGetDefaultChainID(t, testopts.ChainConfigs), logger.TestLogger(t)) } if testopts.LogBroadcaster != nil { opts.GenLogBroadcaster = func(*big.Int) log.Broadcaster { @@ -301,10 +301,12 @@ func nodeStatus(n *configtoml.Node, chainID string) (types.NodeStatus, error) { return s, nil } +// Deprecated: use clienttest.NewClient func NewEthClientMock(t *testing.T) *clienttest.Client { return clienttest.NewClient(t) } +// Deprecated: use clienttest.NewClientWithDefaultChainID func NewEthClientMockWithDefaultChain(t *testing.T) *clienttest.Client { c := NewEthClientMock(t) c.On("ConfiguredChainID").Return(testutils.FixtureChainID).Maybe() diff --git a/core/internal/testutils/evmtest/v2/evmtest.go b/core/internal/testutils/evmtest/v2/evmtest.go index 53666768442..5f8d93f851c 100644 --- a/core/internal/testutils/evmtest/v2/evmtest.go +++ b/core/internal/testutils/evmtest/v2/evmtest.go @@ -3,7 +3,6 @@ package v2 import ( "testing" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/evm/config" "github.com/smartcontractkit/chainlink/v2/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/evm/utils/big" @@ -17,5 +16,5 @@ func ChainArbitrumRinkeby(t *testing.T) config.ChainScopedConfig { return scoped func scopedConfig(t *testing.T, chainID int64) config.ChainScopedConfig { id := big.NewI(chainID) evmCfg := toml.EVMConfig{ChainID: id, Chain: toml.Defaults(id)} - return config.NewTOMLChainScopedConfig(&evmCfg, logger.TestLogger(t)) + return config.NewTOMLChainScopedConfig(&evmCfg) } diff --git a/core/services/blockhashstore/bhs_test.go b/core/services/blockhashstore/bhs_test.go index 5b89794eb6e..9aa589a98c2 100644 --- a/core/services/blockhashstore/bhs_test.go +++ b/core/services/blockhashstore/bhs_test.go @@ -19,18 +19,19 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/blockhashstore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" "github.com/smartcontractkit/chainlink/v2/evm/types" ) func TestStoreRotatesFromAddresses(t *testing.T) { ctx := testutils.Context(t) db := pgtest.NewSqlxDB(t) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) cfg := configtest.NewTestGeneralConfig(t) kst := cltest.NewKeyStore(t, db) require.NoError(t, kst.Unlock(ctx, cltest.Password)) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/blockhashstore/delegate_test.go b/core/services/blockhashstore/delegate_test.go index be32bd21e66..8f006d6a708 100644 --- a/core/services/blockhashstore/delegate_test.go +++ b/core/services/blockhashstore/delegate_test.go @@ -49,7 +49,7 @@ func createTestDelegate(t *testing.T) (*blockhashstore.Delegate, *testData) { t.Helper() lggr, logs := logger.TestLoggerObserved(t, zapcore.DebugLevel) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.Feature.LogPoller = func(b bool) *bool { return &b }(true) }) @@ -63,7 +63,7 @@ func createTestDelegate(t *testing.T) (*blockhashstore.Delegate, *testData) { legacyChains := evmtest.NewLegacyChains( t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 3e4649e0f40..e92847ccb34 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -622,7 +622,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { ) // Flux monitor requires ethereum just to boot, silence errors with a null delegate - if !cfg.EVMRPCEnabled() { + if !cfg.EVMConfigs().RPCEnabled() { delegates[job.FluxMonitor] = &job.NullDelegate{Type: job.FluxMonitor} } else { delegates[job.FluxMonitor] = fluxmonitorv2.NewDelegate( diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index ea27d28d28b..65d9126b3d6 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -195,6 +195,9 @@ func (o *GeneralConfigOpts) parse() (err error) { } func (g *generalConfig) EVMConfigs() evmcfg.EVMConfigs { + if g.c.EVM == nil { + return evmcfg.EVMConfigs{} // return empty to pass nil check + } return g.c.EVM } @@ -316,17 +319,6 @@ func (g *generalConfig) EVMEnabled() bool { return false } -func (g *generalConfig) EVMRPCEnabled() bool { - for _, c := range g.c.EVM { - if c.IsEnabled() { - if len(c.Nodes) > 0 { - return true - } - } - } - return false -} - func (g *generalConfig) SolanaEnabled() bool { for _, c := range g.c.Solana { if c.IsEnabled() { diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go index 3f02b880baf..22a5a131e5a 100644 --- a/core/services/chainlink/config_general_test.go +++ b/core/services/chainlink/config_general_test.go @@ -23,7 +23,7 @@ func TestTOMLGeneralConfig_Defaults(t *testing.T) { config, err := GeneralConfigOpts{}.New() require.NoError(t, err) assert.Equal(t, (*url.URL)(nil), config.WebServer().BridgeResponseURL()) - assert.False(t, config.EVMRPCEnabled()) + assert.False(t, config.EVMConfigs().RPCEnabled()) assert.False(t, config.EVMEnabled()) assert.False(t, config.CosmosEnabled()) assert.False(t, config.SolanaEnabled()) diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go index 44b272ba93a..007f1e3e2db 100644 --- a/core/services/chainlink/mocks/general_config.go +++ b/core/services/chainlink/mocks/general_config.go @@ -602,51 +602,6 @@ func (_c *GeneralConfig_EVMEnabled_Call) RunAndReturn(run func() bool) *GeneralC return _c } -// EVMRPCEnabled provides a mock function with no fields -func (_m *GeneralConfig) EVMRPCEnabled() bool { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for EVMRPCEnabled") - } - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// GeneralConfig_EVMRPCEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EVMRPCEnabled' -type GeneralConfig_EVMRPCEnabled_Call struct { - *mock.Call -} - -// EVMRPCEnabled is a helper method to define mock.On call -func (_e *GeneralConfig_Expecter) EVMRPCEnabled() *GeneralConfig_EVMRPCEnabled_Call { - return &GeneralConfig_EVMRPCEnabled_Call{Call: _e.mock.On("EVMRPCEnabled")} -} - -func (_c *GeneralConfig_EVMRPCEnabled_Call) Run(run func()) *GeneralConfig_EVMRPCEnabled_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *GeneralConfig_EVMRPCEnabled_Call) Return(_a0 bool) *GeneralConfig_EVMRPCEnabled_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *GeneralConfig_EVMRPCEnabled_Call) RunAndReturn(run func() bool) *GeneralConfig_EVMRPCEnabled_Call { - _c.Call.Return(run) - return _c -} - // Feature provides a mock function with no fields func (_m *GeneralConfig) Feature() config.Feature { ret := _m.Called() diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index a3e9e2ad205..379bc658b0b 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -128,7 +128,7 @@ func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfi op.loopRelayers[id] = a legacyMap[id.ChainID] = a.Chain() } - op.legacyChains.EVMChains = legacyevm.NewLegacyChains(legacyMap, config.AppConfig.EVMConfigs()) + op.legacyChains.EVMChains = legacyevm.NewLegacyChains(legacyMap, config.ChainConfigs) return nil } } diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 26d6442132f..3fb98900b80 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -213,7 +213,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { initFuncs: []chainlink.CoreRelayerChainInitFunc{ chainlink.InitEVM(testctx, factory, chainlink.EVMFactoryConfig{ ChainOpts: legacyevm.ChainOpts{ - AppConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), ListenerConfig: cfg.Database().Listener(), FeatureConfig: cfg.Feature(), @@ -289,7 +289,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { TOMLConfigs: cfg.SolanaConfigs()}), chainlink.InitEVM(testctx, factory, chainlink.EVMFactoryConfig{ ChainOpts: legacyevm.ChainOpts{ - AppConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), ListenerConfig: cfg.Database().Listener(), FeatureConfig: cfg.Feature(), diff --git a/core/services/directrequest/delegate_test.go b/core/services/directrequest/delegate_test.go index 80469a03636..4116ce57732 100644 --- a/core/services/directrequest/delegate_test.go +++ b/core/services/directrequest/delegate_test.go @@ -33,11 +33,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" pipeline_mocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" ubig "github.com/smartcontractkit/chainlink/v2/evm/utils/big" ) func TestDelegate_ServicesForSpec(t *testing.T) { - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) runner := pipeline_mocks.NewRunner(t) db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { @@ -46,7 +47,7 @@ func TestDelegate_ServicesForSpec(t *testing.T) { keyStore := cltest.NewKeyStore(t, db) mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t)) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), @@ -84,7 +85,7 @@ type DirectRequestUniverse struct { } func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfig, specF func(spec *job.Job)) *DirectRequestUniverse { - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) broadcaster := log_mocks.NewBroadcaster(t) runner := pipeline_mocks.NewRunner(t) broadcaster.On("AddDependents", 1) @@ -94,7 +95,7 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi db := pgtest.NewSqlxDB(t) keyStore := cltest.NewKeyStore(t, db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go index 0b042e98d79..f22d3a72c9d 100644 --- a/core/services/feeds/orm_test.go +++ b/core/services/feeds/orm_test.go @@ -1736,7 +1736,7 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job { pipelineORM = pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgeORM = bridges.NewORM(db) legacyChains = evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index 055423c1dc9..24738680fb3 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -226,7 +226,7 @@ func setupTestServiceCfg(t *testing.T, overrideCfg func(c *chainlink.Config, s * keyStore := new(ksmocks.Master) ethKeyStore := cltest.NewKeyStore(t, db).Eth() legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: gcfg, + ChainConfigs: gcfg.EVMConfigs(), DatabaseConfig: gcfg.Database(), FeatureConfig: gcfg.Feature(), ListenerConfig: gcfg.Database().Listener(), diff --git a/core/services/functions/listener_test.go b/core/services/functions/listener_test.go index 765c1908009..5cbab946b45 100644 --- a/core/services/functions/listener_test.go +++ b/core/services/functions/listener_test.go @@ -44,6 +44,7 @@ import ( sync_mocks "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/telem" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" ) type FunctionsListenerUniverse struct { @@ -78,7 +79,7 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].MinIncomingConfirmations = ptr[uint32](1) }) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) broadcaster := log_mocks.NewBroadcaster(t) broadcaster.On("AddDependents", 1) mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t)) @@ -86,7 +87,7 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe db := pgtest.NewSqlxDB(t) kst := cltest.NewKeyStore(t, db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/headreporter/prometheus_reporter_test.go b/core/services/headreporter/prometheus_reporter_test.go index ea8ffa732f8..a6a728738ba 100644 --- a/core/services/headreporter/prometheus_reporter_test.go +++ b/core/services/headreporter/prometheus_reporter_test.go @@ -17,10 +17,10 @@ import ( "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/evmtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/headreporter" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" "github.com/smartcontractkit/chainlink/v2/evm/gas" ) @@ -121,7 +121,7 @@ func Test_PrometheusReporter(t *testing.T) { func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainContainer { config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) keyStore := cltest.NewKeyStore(t, db).Eth() - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) estimator, err := gas.NewEstimator(logger.TestLogger(t), ethClient, config.ChainType(), ethClient.ConfiguredChainID(), evmConfig.GasEstimator(), nil) require.NoError(t, err) lggr := logger.TestLogger(t) @@ -157,7 +157,7 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon } func newLegacyChainContainerWithNullTxm(t *testing.T) legacyevm.LegacyChainContainer { - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) txm := &txmgr.NullTxManager{ErrMsg: fmt.Sprintf("TXM disabled for chain %d", ethClient.ConfiguredChainID())} cfg := configtest.NewGeneralConfig(t, nil) return cltest.NewLegacyChainsWithMockChainAndTxManager(t, ethClient, cfg, txm) diff --git a/core/services/job/helpers_test.go b/core/services/job/helpers_test.go index 6dd72b3d759..fae03ed6d43 100644 --- a/core/services/job/helpers_test.go +++ b/core/services/job/helpers_test.go @@ -25,6 +25,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/ocr" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" ) const ( @@ -211,12 +212,12 @@ func makeMinimalHTTPOracleSpec(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralC s := fmt.Sprintf(minimalNonBootstrapTemplate, contractAddress, transmitterAddress, keyBundle, fetchUrl, timeout) keyStore := cltest.NewKeyStore(t, db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), DB: db, - Client: evmtest.NewEthClientMockWithDefaultChain(t), + Client: clienttest.NewClientWithDefaultChainID(t), KeyStore: keyStore.Eth(), }) _, err := ocr.ValidatedOracleSpecToml(cfg, legacyChains, s) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index 6edf76118ce..eb0a7d23ce7 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -377,7 +377,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -803,7 +803,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { JobID: externalJobID.UUID.String(), }) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -1080,7 +1080,7 @@ func Test_FindJobs(t *testing.T) { _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -1171,7 +1171,7 @@ func Test_FindJob(t *testing.T) { externalJobID := uuid.New() _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -1409,7 +1409,7 @@ func Test_FindPipelineRuns(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -1479,7 +1479,7 @@ func Test_PipelineRunsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -1548,7 +1548,7 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -1669,7 +1669,7 @@ func Test_FindPipelineRunsByIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -1855,7 +1855,7 @@ func Test_CountPipelineRunsByJobID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), diff --git a/core/services/job/job_pipeline_orm_integration_test.go b/core/services/job/job_pipeline_orm_integration_test.go index efc30299d7d..ff24995cec9 100644 --- a/core/services/job/job_pipeline_orm_integration_test.go +++ b/core/services/job/job_pipeline_orm_integration_test.go @@ -21,6 +21,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" ) func clearJobsDb(t *testing.T, db *sqlx.DB) { @@ -155,11 +156,11 @@ func TestPipelineORM_Integration(t *testing.T) { orm := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), - Client: evmtest.NewEthClientMockWithDefaultChain(t), + Client: clienttest.NewClientWithDefaultChainID(t), DB: db, KeyStore: ethKeyStore, }) diff --git a/core/services/job/runner_integration_test.go b/core/services/job/runner_integration_test.go index 1caa1461dc8..03f71e6cf09 100644 --- a/core/services/job/runner_integration_test.go +++ b/core/services/job/runner_integration_test.go @@ -86,7 +86,7 @@ func TestRunner(t *testing.T) { legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ DB: db, Client: ethClient, - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -570,7 +570,7 @@ answer1 [type=median index=0]; legacyChains2 := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ DB: db, Client: ethClient, - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index b28abcc9208..7e3f634228e 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -101,7 +101,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ DB: db, Client: ethClient, - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), @@ -286,7 +286,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { testopts := evmtest.TestChainOpts{ DB: db, Client: ethClient, - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), diff --git a/core/services/keeper/registry1_1_synchronizer_test.go b/core/services/keeper/registry1_1_synchronizer_test.go index b5d5bae5948..2ec2b18e88d 100644 --- a/core/services/keeper/registry1_1_synchronizer_test.go +++ b/core/services/keeper/registry1_1_synchronizer_test.go @@ -18,7 +18,6 @@ import ( registry1_1 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "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/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" @@ -73,7 +72,7 @@ func mockRegistry1_1( func Test_LogListenerOpts1_1(t *testing.T) { db := pgtest.NewSqlxDB(t) korm := keeper.NewORM(db, logger.TestLogger(t)) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address()) contractAddress := j.KeeperSpec.ContractAddress.Address() diff --git a/core/services/keeper/registry1_2_synchronizer_test.go b/core/services/keeper/registry1_2_synchronizer_test.go index 81af282d8c9..e7d915d565c 100644 --- a/core/services/keeper/registry1_2_synchronizer_test.go +++ b/core/services/keeper/registry1_2_synchronizer_test.go @@ -17,7 +17,6 @@ import ( registry1_2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "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/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" @@ -95,7 +94,7 @@ func mockRegistry1_2( func Test_LogListenerOpts1_2(t *testing.T) { db := pgtest.NewSqlxDB(t) korm := keeper.NewORM(db, logger.TestLogger(t)) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address()) contractAddress := j.KeeperSpec.ContractAddress.Address() diff --git a/core/services/keeper/registry1_3_synchronizer_test.go b/core/services/keeper/registry1_3_synchronizer_test.go index dd4be5f3593..210b7092fbb 100644 --- a/core/services/keeper/registry1_3_synchronizer_test.go +++ b/core/services/keeper/registry1_3_synchronizer_test.go @@ -18,7 +18,6 @@ import ( registry1_3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "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/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keeper" @@ -97,7 +96,7 @@ func mockRegistry1_3( func Test_LogListenerOpts1_3(t *testing.T) { db := pgtest.NewSqlxDB(t) korm := keeper.NewORM(db, logger.TestLogger(t)) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address()) contractAddress := j.KeeperSpec.ContractAddress.Address() diff --git a/core/services/keeper/registry_synchronizer_helper_test.go b/core/services/keeper/registry_synchronizer_helper_test.go index 8a6b01b3394..34fff6095ca 100644 --- a/core/services/keeper/registry_synchronizer_helper_test.go +++ b/core/services/keeper/registry_synchronizer_helper_test.go @@ -38,7 +38,7 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) ( db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, nil) korm := keeper.NewORM(db, logger.TestLogger(t)) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) keyStore := cltest.NewKeyStore(t, db) lbMock := logmocks.NewBroadcaster(t) lbMock.On("AddDependents", 1).Maybe() @@ -47,7 +47,7 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) ( DB: db, Client: ethClient, LogBroadcaster: lbMock, - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index bd2d7640f96..3a881d52265 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -85,7 +85,7 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain DB: db, Client: ethClient, KeyStore: keyStore.Eth(), - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/ocr2/delegate_test.go b/core/services/ocr2/delegate_test.go index e55429d45cf..f98db3913dc 100644 --- a/core/services/ocr2/delegate_test.go +++ b/core/services/ocr2/delegate_test.go @@ -47,7 +47,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) { txManager := txmmocks.NewMockEvmTxManager(t) legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ DB: db, - GeneralConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), FeatureConfig: config.Feature(), ListenerConfig: config.Database().Listener(), diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index fde3f5e41c9..881b1199bb8 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -444,7 +444,7 @@ func setupNodeCCIP( mailMon := mailbox.NewMonitor("CCIP", lggr.Named("Mailbox")) evmOpts := chainlink.EVMFactoryConfig{ ChainOpts: legacyevm.ChainOpts{ - AppConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), ListenerConfig: config.Database().Listener(), FeatureConfig: config.Feature(), diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go index 6747d5bc1e7..5c556935a69 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go @@ -444,7 +444,7 @@ func setupNodeCCIP( mailMon := mailbox.NewMonitor("CCIP", lggr.Named("Mailbox")) evmOpts := chainlink.EVMFactoryConfig{ ChainOpts: legacyevm.ChainOpts{ - AppConfig: config, + ChainConfigs: config.EVMConfigs(), DatabaseConfig: config.Database(), ListenerConfig: config.Database().Listener(), FeatureConfig: config.Feature(), diff --git a/core/services/pipeline/runner_test.go b/core/services/pipeline/runner_test.go index c9b3e1ed6ff..7b636534513 100644 --- a/core/services/pipeline/runner_test.go +++ b/core/services/pipeline/runner_test.go @@ -40,7 +40,7 @@ import ( func newRunner(t testing.TB, db *sqlx.DB, bridgeORM bridges.ORM, cfg chainlink.GeneralConfig) (pipeline.Runner, *mocks.ORM) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), @@ -516,7 +516,7 @@ func Test_PipelineRunner_HandleFaultsPersistRun(t *testing.T) { cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, db).Eth() legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), @@ -562,7 +562,7 @@ func Test_PipelineRunner_ExecuteAndInsertFinishedRun_SavingTheSpec(t *testing.T) cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, db).Eth() legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), @@ -1038,7 +1038,7 @@ func Test_PipelineRunner_ExecuteRun(t *testing.T) { cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, db).Eth() legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/pipeline/task.eth_call_test.go b/core/services/pipeline/task.eth_call_test.go index 9e87fe5c19c..920964e5e48 100644 --- a/core/services/pipeline/task.eth_call_test.go +++ b/core/services/pipeline/task.eth_call_test.go @@ -314,7 +314,7 @@ func TestETHCallTask(t *testing.T) { if test.expectedErrorCause != nil || test.expectedErrorContains != "" { legacyChains = evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ DB: db, - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/pipeline/task.eth_tx_test.go b/core/services/pipeline/task.eth_tx_test.go index e3864a41dca..0e1e96593fc 100644 --- a/core/services/pipeline/task.eth_tx_test.go +++ b/core/services/pipeline/task.eth_tx_test.go @@ -580,7 +580,7 @@ func TestETHTxTask(t *testing.T) { legacyChains := evmtest.NewLegacyChains(t, evmtest.TestChainOpts{ DB: db, - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index 8b7e79c1fc5..2a5199de851 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -43,7 +43,7 @@ func NewLegacyChains(ctx context.Context, opts legacyevm.ChainRelayOpts) (result unique := make(map[string]struct{}) - evmConfigs := opts.AppConfig.EVMConfigs() + evmConfigs := opts.ChainConfigs var enabled []*toml.EVMConfig for i, cfg := range evmConfigs { _, alreadyExists := unique[cfg.ChainID.String()] @@ -81,5 +81,5 @@ func NewLegacyChains(ctx context.Context, opts legacyevm.ChainRelayOpts) (result func NewLegacyChainsAndConfig(ctx context.Context, opts legacyevm.ChainRelayOpts) (*LegacyChainsAndConfig, error) { result, err := NewLegacyChains(ctx, opts) // always return because it's accumulating errors - return &LegacyChainsAndConfig{result, opts.AppConfig.EVMConfigs()}, err + return &LegacyChainsAndConfig{result, opts.ChainConfigs}, err } diff --git a/core/services/relay/evm/relayer_extender_test.go b/core/services/relay/evm/relayer_extender_test.go index 9a65b486da7..0bda7825c71 100644 --- a/core/services/relay/evm/relayer_extender_test.go +++ b/core/services/relay/evm/relayer_extender_test.go @@ -38,7 +38,7 @@ func TestChainRelayExtenders(t *testing.T) { opts := evmtest.NewChainOpts(t, evmtest.TestChainOpts{ DB: db, KeyStore: kst.Eth(), - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go index cebf2446309..6f8d4cfc714 100644 --- a/core/services/vrf/delegate_test.go +++ b/core/services/vrf/delegate_test.go @@ -92,7 +92,7 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv KeyStore: ks.Eth(), Client: ec, DB: db, - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index d06ee65278c..fd73a3e7504 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -2107,7 +2107,7 @@ func TestStartingCountsV1(t *testing.T) { KeyStore: ks.Eth(), Client: ec, DB: db, - GeneralConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), FeatureConfig: cfg.Feature(), ListenerConfig: cfg.Database().Listener(), diff --git a/core/services/vrf/v2/listener_v2_test.go b/core/services/vrf/v2/listener_v2_test.go index b3b9dd40282..0a58887a361 100644 --- a/core/services/vrf/v2/listener_v2_test.go +++ b/core/services/vrf/v2/listener_v2_test.go @@ -14,15 +14,14 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" clnull "github.com/smartcontractkit/chainlink-common/pkg/utils/null" - txmgrcommon "github.com/smartcontractkit/chainlink-framework/chains/txmgr" txmgrtypes "github.com/smartcontractkit/chainlink-framework/chains/txmgr/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" "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/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -30,13 +29,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" "github.com/smartcontractkit/chainlink/v2/evm/gas" evmtypes "github.com/smartcontractkit/chainlink/v2/evm/types" ) func makeTestTxm(t *testing.T, txStore txmgr.TestEvmTxStore, keyStore keystore.Master) txmgrcommon.TxManager[*big.Int, *evmtypes.Head, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee] { _, _, evmConfig := txmgr.MakeTestConfigs(t) - ec := evmtest.NewEthClientMockWithDefaultChain(t) + ec := clienttest.NewClientWithDefaultChainID(t) txmConfig := txmgr.NewEvmTxmConfig(evmConfig) txm := txmgr.NewEvmTxm(ec.ConfiguredChainID(), txmConfig, evmConfig.Transactions(), keyStore.Eth(), logger.TestLogger(t), nil, nil, nil, txStore, nil, nil, nil, nil, nil, nil) diff --git a/core/web/eth_keys_controller_test.go b/core/web/eth_keys_controller_test.go index 78982e2e304..4dd5d7969b7 100644 --- a/core/web/eth_keys_controller_test.go +++ b/core/web/eth_keys_controller_test.go @@ -1,12 +1,16 @@ package web_test import ( + "errors" "math/big" "net/http" "net/url" "testing" - "github.com/pkg/errors" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/assets" commontxmmocks "github.com/smartcontractkit/chainlink/v2/common/txmgr/types/mocks" @@ -15,17 +19,11 @@ import ( "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/evmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" webpresenters "github.com/smartcontractkit/chainlink/v2/core/web/presenters" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/google/uuid" + "github.com/smartcontractkit/chainlink/v2/evm/client/clienttest" ) func TestETHKeysController_Index_Success(t *testing.T) { @@ -217,7 +215,7 @@ func TestETHKeysController_CreateSuccess(t *testing.T) { config := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].BalanceMonitor.Enabled = ptr(false) }) - ethClient := evmtest.NewEthClientMockWithDefaultChain(t) + ethClient := clienttest.NewClientWithDefaultChainID(t) app := cltest.NewApplicationWithConfigAndKey(t, config, ethClient) sub := commonmocks.NewSubscription(t) diff --git a/deployment/environment/memory/node.go b/deployment/environment/memory/node.go index 97e60c646b9..0100c26f6dc 100644 --- a/deployment/environment/memory/node.go +++ b/deployment/environment/memory/node.go @@ -169,7 +169,7 @@ func NewNode( mailMon := mailbox.NewMonitor("node", lggr.Named("mailbox")) evmOpts := chainlink.EVMFactoryConfig{ ChainOpts: legacyevm.ChainOpts{ - AppConfig: cfg, + ChainConfigs: cfg.EVMConfigs(), DatabaseConfig: cfg.Database(), ListenerConfig: cfg.Database().Listener(), FeatureConfig: cfg.Feature(), diff --git a/evm/config/chain_scoped.go b/evm/config/chain_scoped.go index eb29a49d012..37d8faa43f4 100644 --- a/evm/config/chain_scoped.go +++ b/evm/config/chain_scoped.go @@ -5,22 +5,16 @@ import ( "time" "github.com/smartcontractkit/chainlink-common/pkg/assets" - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/v2/evm/config/chaintype" "github.com/smartcontractkit/chainlink/v2/evm/config/toml" ) -func NewTOMLChainScopedConfig(tomlConfig *toml.EVMConfig, lggr logger.Logger) *ChainScoped { - return &ChainScoped{ - evmConfig: &EVMConfig{C: tomlConfig}, - lggr: lggr} +func NewTOMLChainScopedConfig(tomlConfig *toml.EVMConfig) *ChainScoped { + return &ChainScoped{evmConfig: &EVMConfig{C: tomlConfig}} } -// ChainScoped implements config.ChainScopedConfig with a gencfg.BasicConfig and EVMConfig. +// ChainScoped implements config.ChainScopedConfig with EVMConfig. type ChainScoped struct { - lggr logger.Logger - evmConfig *EVMConfig } diff --git a/evm/config/configtest/configtest.go b/evm/config/configtest/configtest.go index facefec5548..9092b81c001 100644 --- a/evm/config/configtest/configtest.go +++ b/evm/config/configtest/configtest.go @@ -3,13 +3,12 @@ package configtest import ( "testing" - "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/v2/evm/config" "github.com/smartcontractkit/chainlink/v2/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/evm/utils/big" ) -func NewChainScopedConfig(t testing.TB, overrideFn func(c *toml.EVMConfig)) config.ChainScopedConfig { +func NewChainScopedConfig(t testing.TB, overrideFn func(c *toml.EVMConfig)) *config.ChainScoped { chainID := big.NewI(0) evmCfg := &toml.EVMConfig{ ChainID: chainID, @@ -24,5 +23,5 @@ func NewChainScopedConfig(t testing.TB, overrideFn func(c *toml.EVMConfig)) conf overrideFn(evmCfg) } - return config.NewTOMLChainScopedConfig(evmCfg, logger.Test(t)) + return config.NewTOMLChainScopedConfig(evmCfg) } diff --git a/evm/config/toml/config.go b/evm/config/toml/config.go index 64fe11372d6..ff41176c853 100644 --- a/evm/config/toml/config.go +++ b/evm/config/toml/config.go @@ -163,6 +163,17 @@ func (cs EVMConfigs) NodeStatus(name string) (commontypes.NodeStatus, error) { return commontypes.NodeStatus{}, fmt.Errorf("node %s: %w", name, ErrNotFound) } +func (cs EVMConfigs) RPCEnabled() bool { + for _, c := range cs { + if c.IsEnabled() { + if len(c.Nodes) > 0 { + return true + } + } + } + return false +} + func legacyNode(n *Node, chainID *big.Big) (v2 types.Node) { v2.Name = *n.Name v2.EVMChainID = *chainID diff --git a/evm/gas/fee_history_estimator_test.go b/evm/gas/fee_history_estimator_test.go index 8371db8fac1..ae3bb6452f0 100644 --- a/evm/gas/fee_history_estimator_test.go +++ b/evm/gas/fee_history_estimator_test.go @@ -65,7 +65,7 @@ func TestFeeHistoryEstimatorLifecycle(t *testing.T) { CacheTimeout: 10 * time.Second, } - u := gas.NewFeeHistoryEstimator(logger.Test(t), nil, cfg, chainID, nil) + u := gas.NewFeeHistoryEstimator(logger.Test(t), client, cfg, chainID, nil) err := u.Start(tests.Context(t)) assert.NoError(t, err) err = u.Close() diff --git a/evm/testutils/config.go b/evm/testutils/config.go index e95541bd276..e1b85905606 100644 --- a/evm/testutils/config.go +++ b/evm/testutils/config.go @@ -3,8 +3,6 @@ package testutils import ( "testing" - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/v2/evm/config" "github.com/smartcontractkit/chainlink/v2/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/evm/utils/big" @@ -26,5 +24,5 @@ func NewTestChainScopedConfig(t testing.TB, overrideFn func(c *toml.EVMConfig)) overrideFn(evmCfg) } - return config.NewTOMLChainScopedConfig(evmCfg, logger.Test(t)) + return config.NewTOMLChainScopedConfig(evmCfg) }