diff --git a/common/txmgr/sequence_syncer.go b/common/txmgr/sequence_syncer.go deleted file mode 100644 index dd4d458dd74..00000000000 --- a/common/txmgr/sequence_syncer.go +++ /dev/null @@ -1,11 +0,0 @@ -package txmgr - -import ( - "context" - - "github.com/smartcontractkit/chainlink/v2/common/types" -) - -type SequenceSyncer[ADDR types.Hashable, TX_HASH types.Hashable, BLOCK_HASH types.Hashable, SEQ types.Sequence] interface { - Sync(ctx context.Context, addr ADDR, localSequence SEQ) (SEQ, error) -} diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 85e9e985601..dc4c945f86a 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -67,7 +67,7 @@ func NewTestEthBroadcaster( return gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), ge.BlockHistory(), lggr) }, ge.EIP1559DynamicFees(), nil) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator) - ethBroadcaster := txmgr.NewEvmBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), config.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync) + ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), config.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync) // Mark instance as test ethBroadcaster.XXXTestDisableUnstartedTxAutoProcessing() @@ -85,7 +85,6 @@ func TestEthBroadcaster_Lifecycle(t *testing.T) { estimator := gasmocks.NewEvmFeeEstimator(t) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator) txmClient := txmgr.NewEvmTxmClient(ethClient) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmClient) ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), nil) eb := txmgr.NewEvmBroadcaster( txStore, @@ -96,7 +95,6 @@ func TestEthBroadcaster_Lifecycle(t *testing.T) { evmcfg.Database().Listener(), ethKeyStore, txBuilder, - nonceTracker, logger.Test(t), &testCheckerFactory{}, false, @@ -146,7 +144,6 @@ func TestEthBroadcaster_LoadNextSequenceMapFailure_StartupSuccess(t *testing.T) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator) ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), errors.New("Getting on-chain nonce failed")) txmClient := txmgr.NewEvmTxmClient(ethClient) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmClient) eb := txmgr.NewEvmBroadcaster( txStore, txmClient, @@ -156,7 +153,6 @@ func TestEthBroadcaster_LoadNextSequenceMapFailure_StartupSuccess(t *testing.T) evmcfg.Database().Listener(), ethKeyStore, txBuilder, - nonceTracker, logger.Test(t), &testCheckerFactory{}, false, @@ -626,7 +622,6 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi }).Once() ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil) txmClient := txmgr.NewEvmTxmClient(ethClient) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmClient) eb := txmgr.NewEvmBroadcaster( txStore, txmClient, @@ -636,7 +631,6 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi cfg.Database().Listener(), ethKeyStore, txBuilder, - nonceTracker, logger.Test(t), &testCheckerFactory{}, false, @@ -1158,9 +1152,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { }, evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), nil) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator) localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress) - ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() - nonceTracker2 := txmgr.NewNonceTracker(lggr, txStore, txmClient) - eb2 := txmgr.NewEvmBroadcaster(txStore, txmClient, txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), evmcfg.Database().Listener(), ethKeyStore, txBuilder, nonceTracker2, lggr, &testCheckerFactory{}, false) + eb2 := txmgr.NewEvmBroadcaster(txStore, txmClient, txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), evmcfg.Database().Listener(), ethKeyStore, txBuilder, lggr, &testCheckerFactory{}, false) retryable, err := eb2.ProcessUnstartedTxs(ctx, fromAddress) assert.NoError(t, err) assert.False(t, retryable) @@ -1174,6 +1166,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { t.Run("geth Client fails with error indicating that the transaction was too expensive", func(t *testing.T) { TxFeeExceedsCapError := "tx fee (1.10 ether) exceeds the configured cap (1.00 ether)" localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) + ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() etx := mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { return tx.Nonce() == localNextNonce @@ -1483,9 +1476,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { c.EVM[0].GasEstimator.BumpMin = assets.NewWeiI(0) c.EVM[0].GasEstimator.BumpPercent = ptr[uint16](0) })) - ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() - nonceTracker2 := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) - eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker2) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker) mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID) // First was underpriced @@ -1577,8 +1568,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { })) localNextNonce := getLocalNextNonce(t, nonceTracker, fromAddress) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() - nonceTracker2 := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) - eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker2) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker) mustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID) underpricedError := "transaction underpriced" localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress) @@ -1609,8 +1599,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { c.EVM[0].GasEstimator.TipCapDefault = assets.NewWeiI(0) })) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() - nonceTracker2 := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) - eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker2) + eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker) retryable, err := eb2.ProcessUnstartedTxs(ctx, fromAddress) require.Error(t, err) @@ -1624,8 +1613,8 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { c.EVM[0].GasEstimator.TipCapDefault = gasTipCapDefault })) localNextNonce = getLocalNextNonce(t, nonceTracker, fromAddress) - nonceTracker2 = txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) - eb2 = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker2) + ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(localNextNonce, nil).Once() + eb2 = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false, nonceTracker) // Second was underpriced but above minimum ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { @@ -1760,8 +1749,7 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) { kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Once() ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() txmClient := txmgr.NewEvmTxmClient(ethClient) - nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmClient) - eb := txmgr.NewEvmBroadcaster(txStore, txmClient, evmTxmCfg, txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database().Listener(), kst, txBuilder, nonceTracker, lggr, checkerFactory, false) + eb := txmgr.NewEvmBroadcaster(txStore, txmClient, evmTxmCfg, txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database().Listener(), kst, txBuilder, lggr, checkerFactory, false) err := eb.Start(ctx) assert.NoError(t, err) diff --git a/core/chains/evm/txmgr/builder.go b/core/chains/evm/txmgr/builder.go index 200e206b401..0900fc294a1 100644 --- a/core/chains/evm/txmgr/builder.go +++ b/core/chains/evm/txmgr/builder.go @@ -52,8 +52,7 @@ func NewTxm( feeCfg := NewEvmTxmFeeConfig(fCfg) // wrap Evm specific config txmClient := NewEvmTxmClient(client) // wrap Evm specific client chainID := txmClient.ConfiguredChainID() - nonceTracker := NewNonceTracker(lggr, txStore, txmClient) - evmBroadcaster := NewEvmBroadcaster(txStore, txmClient, txmCfg, feeCfg, txConfig, listenerConfig, keyStore, txAttemptBuilder, nonceTracker, lggr, checker, chainConfig.NonceAutoSync()) + evmBroadcaster := NewEvmBroadcaster(txStore, txmClient, txmCfg, feeCfg, txConfig, listenerConfig, keyStore, txAttemptBuilder, lggr, checker, chainConfig.NonceAutoSync()) evmTracker := NewEvmTracker(txStore, keyStore, chainID, lggr) evmConfirmer := NewEvmConfirmer(txStore, txmClient, txmCfg, feeCfg, txConfig, dbConfig, keyStore, txAttemptBuilder, lggr) var evmResender *Resender @@ -137,10 +136,10 @@ func NewEvmBroadcaster( listenerConfig txmgrtypes.BroadcasterListenerConfig, keystore KeyStore, txAttemptBuilder TxAttemptBuilder, - nonceTracker NonceTracker, logger logger.Logger, checkerFactory TransmitCheckerFactory, autoSyncNonce bool, ) *Broadcaster { + nonceTracker := NewNonceTracker(logger, txStore, client) return txmgr.NewBroadcaster(txStore, client, chainConfig, feeConfig, txConfig, listenerConfig, keystore, txAttemptBuilder, nonceTracker, logger, checkerFactory, autoSyncNonce) } diff --git a/core/chains/evm/txmgr/nonce_tracker.go b/core/chains/evm/txmgr/nonce_tracker.go index 87c632bae0a..f4eb301c36e 100644 --- a/core/chains/evm/txmgr/nonce_tracker.go +++ b/core/chains/evm/txmgr/nonce_tracker.go @@ -22,7 +22,7 @@ type NonceTrackerTxStore interface { type NonceTrackerClient interface { ConfiguredChainID() *big.Int - PendingNonceAt(context.Context, common.Address) (evmtypes.Nonce, error) + PendingSequenceAt(context.Context, common.Address) (evmtypes.Nonce, error) } type nonceTracker struct { @@ -71,7 +71,7 @@ func (s *nonceTracker) getSequenceForAddr(ctx context.Context, address common.Ad } // Look for nonce on-chain if no tx found for address in TxStore or if error occurred // Returns the nonce that should be used for the next transaction so no need to increment - nonce, err := s.client.PendingNonceAt(ctx, address) + nonce, err := s.client.PendingSequenceAt(ctx, address) if err == nil { return nonce, nil } @@ -118,7 +118,7 @@ func (s *nonceTracker) SyncSequence(ctx context.Context, addr common.Address, ch } func (s *nonceTracker) SyncOnChain(ctx context.Context, addr common.Address, localSequence evmtypes.Nonce) error { - nonce, err := s.client.PendingNonceAt(ctx, addr) + nonce, err := s.client.PendingSequenceAt(ctx, addr) if err != nil { return err } diff --git a/core/chains/evm/txmgr/nonce_tracker_test.go b/core/chains/evm/txmgr/nonce_tracker_test.go index f6a261e1617..e0ae0699d83 100644 --- a/core/chains/evm/txmgr/nonce_tracker_test.go +++ b/core/chains/evm/txmgr/nonce_tracker_test.go @@ -50,7 +50,9 @@ func TestNonceTracker_LoadSequenceMap(t *testing.T) { seq, err := nonceTracker.GetNextSequence(ctx, addr1) require.NoError(t, err) require.Equal(t, types.Nonce(randNonce1+1), seq) - + seq, err = nonceTracker.GetNextSequence(ctx, addr2) + require.NoError(t, err) + require.Equal(t, types.Nonce(randNonce2+1), seq) }) t.Run("set next nonce using client when not found in tx table", func(t *testing.T) { @@ -67,7 +69,9 @@ func TestNonceTracker_LoadSequenceMap(t *testing.T) { seq, err := nonceTracker.GetNextSequence(ctx, addr1) require.NoError(t, err) require.Equal(t, types.Nonce(randNonce1), seq) - + seq, err = nonceTracker.GetNextSequence(ctx, addr2) + require.NoError(t, err) + require.Equal(t, types.Nonce(randNonce2), seq) }) }