Skip to content

Commit

Permalink
Add config to toggle the TXM (#15714)
Browse files Browse the repository at this point in the history
* Added config to enable or disable the TXM

* Added changeset

* Fixed test

* Fixed linting

* Fixed linting

* Updated config description

* Regenerated config doc

* Updated error message

* Updated the config name and nolint comment

* Initialized gas estimator regardless of TXM toggle

* Fixed logger name to match previous naming

* Fixed linting error

* Addressed feedback

* Moved EVM.TransactionManagerEnabled config to EVM.Transactions.Enabled

* Fixed linting
  • Loading branch information
amit-momin authored Dec 19, 2024
1 parent cc49b25 commit e706d72
Show file tree
Hide file tree
Showing 22 changed files with 166 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/wild-cats-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

Added the `EVM.Transactions.Enabled` config to enable or disable the transaction manager. #added
4 changes: 4 additions & 0 deletions core/chains/evm/config/chain_scoped_transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ type transactionsConfig struct {
c toml.Transactions
}

func (t *transactionsConfig) Enabled() bool {
return *t.c.Enabled
}

func (t *transactionsConfig) ForwardersEnabled() bool {
return *t.c.ForwardersEnabled
}
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type ClientErrors interface {
}

type Transactions interface {
Enabled() bool
ForwardersEnabled() bool
ReaperInterval() time.Duration
ResendAfterThreshold() time.Duration
Expand Down
13 changes: 12 additions & 1 deletion core/chains/evm/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,20 @@ func TestChainScopedConfig(t *testing.T) {

assert.Equal(t, false, cfg3.EVM().LogBroadcasterEnabled())
})
})

t.Run("EVM.Transactions.Enabled", func(t *testing.T) {
t.Run("turn on EVM.Transactions.Enabled by default", func(t *testing.T) {
assert.True(t, cfg.EVM().Transactions().Enabled())
})

t.Run("use Noop logBroadcaster when LogBroadcaster is disabled", func(t *testing.T) {
t.Run("verify EVM.Transactions.Enabled is set correctly", func(t *testing.T) {
val := false
cfg3 := testutils.NewTestChainScopedConfig(t, func(c *toml.EVMConfig) {
c.Transactions.Enabled = ptr(val)
})

assert.False(t, cfg3.EVM().Transactions().Enabled())
})
})
}
Expand Down
4 changes: 4 additions & 0 deletions core/chains/evm/config/toml/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ func (c *Chain) ValidateConfig() (err error) {
}

type Transactions struct {
Enabled *bool
ForwardersEnabled *bool
MaxInFlight *uint32
MaxQueued *uint32
Expand All @@ -483,6 +484,9 @@ type Transactions struct {
}

func (t *Transactions) setFrom(f *Transactions) {
if v := f.Enabled; v != nil {
t.Enabled = v
}
if v := f.ForwardersEnabled; v != nil {
t.ForwardersEnabled = v
}
Expand Down
1 change: 0 additions & 1 deletion core/chains/evm/config/toml/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ func (c *Chain) SetFrom(f *Chain) {
if v := f.FinalizedBlockOffset; v != nil {
c.FinalizedBlockOffset = v
}

if v := f.NoNewFinalizedHeadsThreshold; v != nil {
c.NoNewFinalizedHeadsThreshold = v
}
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/config/toml/defaults/fallback.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ NoNewFinalizedHeadsThreshold = '0'
LogBroadcasterEnabled = true

[Transactions]
Enabled = true
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 250
Expand Down
22 changes: 18 additions & 4 deletions core/chains/legacyevm/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod
chainID := cfg.EVM().ChainID()
l := opts.Logger
var client evmclient.Client
var err error
if !opts.AppConfig.EVMRPCEnabled() {
client = evmclient.NewNullClient(chainID, l)
} else if opts.GenEthClient == nil {
var err error
client, err = evmclient.NewEvmClient(cfg.EVM().NodePool(), cfg.EVM(), cfg.EVM().NodePool().Errors(), l, chainID, nodes, cfg.EVM().ChainType())
if err != nil {
return nil, err
Expand Down Expand Up @@ -244,10 +244,24 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod
}
}

// note: gas estimator is started as a part of the txm
txm, gasEstimator, err := newEvmTxm(opts.DS, cfg.EVM(), opts.AppConfig.EVMRPCEnabled(), opts.AppConfig.Database(), opts.AppConfig.Database().Listener(), client, l, logPoller, opts, headTracker, clientsByChainID)
// initialize gas estimator
gasEstimator, err := newGasEstimator(cfg.EVM(), client, l, opts, clientsByChainID)
if err != nil {
return nil, fmt.Errorf("failed to instantiate EvmTxm for chain with ID %s: %w", chainID.String(), err)
return nil, fmt.Errorf("failed to instantiate gas estimator for chain with ID %s: %w", chainID, err)
}

// 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() {
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)}
} else {
txm, err = newEvmTxm(opts.DS, cfg.EVM(), opts.AppConfig.Database(), opts.AppConfig.Database().Listener(), client, l, logPoller, opts, headTracker, gasEstimator)
if err != nil {
return nil, fmt.Errorf("failed to instantiate EvmTxm for chain with ID %s: %w", chainID, err)
}
}

headBroadcaster.Subscribe(txm)
Expand Down
37 changes: 21 additions & 16 deletions core/chains/legacyevm/evm_txm.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,18 @@ import (
func newEvmTxm(
ds sqlutil.DataSource,
cfg evmconfig.EVM,
evmRPCEnabled bool,
databaseConfig txmgr.DatabaseConfig,
listenerConfig txmgr.ListenerConfig,
client evmclient.Client,
lggr logger.Logger,
logPoller logpoller.LogPoller,
opts ChainRelayOpts,
headTracker httypes.HeadTracker,
clientsByChainID map[string]rollups.DAClient,
) (txm txmgr.TxManager,
estimator gas.EvmFeeEstimator,
) (txm txmgr.TxManager,
err error,
) {
chainID := cfg.ChainID()
if !evmRPCEnabled {
txm = &txmgr.NullTxManager{ErrMsg: fmt.Sprintf("Ethereum is disabled for chain %d", chainID)}
return txm, nil, nil
}

lggr = lggr.Named("Txm")
lggr.Infow("Initializing EVM transaction manager",
Expand All @@ -45,15 +39,6 @@ func newEvmTxm(
"limitDefault", cfg.GasEstimator().LimitDefault(),
)

// build estimator from factory
if opts.GenGasEstimator == nil {
if estimator, err = gas.NewEstimator(lggr, client, cfg.ChainType(), chainID, cfg.GasEstimator(), clientsByChainID); err != nil {
return nil, nil, fmt.Errorf("failed to initialize estimator: %w", err)
}
} else {
estimator = opts.GenGasEstimator(chainID)
}

if opts.GenTxManager == nil {
txm, err = txmgr.NewTxm(
ds,
Expand All @@ -74,3 +59,23 @@ func newEvmTxm(
}
return
}

func newGasEstimator(
cfg evmconfig.EVM,
client evmclient.Client,
lggr logger.Logger,
opts ChainRelayOpts,
clientsByChainID map[string]rollups.DAClient,
) (estimator gas.EvmFeeEstimator, err error) {
lggr = lggr.Named("Txm")
chainID := cfg.ChainID()
// build estimator from factory
if opts.GenGasEstimator == nil {
if estimator, err = gas.NewEstimator(lggr, client, cfg.ChainType(), chainID, cfg.GasEstimator(), clientsByChainID); err != nil {
return nil, fmt.Errorf("failed to initialize estimator: %w", err)
}
} else {
estimator = opts.GenGasEstimator(chainID)
}
return
}
2 changes: 2 additions & 0 deletions core/config/docs/chains-evm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ LogBroadcasterEnabled = true # Default
NoNewFinalizedHeadsThreshold = '0' # Default

[EVM.Transactions]
# Enabled is a feature flag for the Transaction Manager. This flag also enables or disables the gas estimator since it is dependent on the TXM to start it.
Enabled = true # Default
# ForwardersEnabled enables or disables sending transactions through forwarder contracts.
ForwardersEnabled = false # Default
# MaxInFlight controls how many transactions are allowed to be "in-flight" i.e. broadcast but unconfirmed at any one time. You can consider this a form of transaction throttling.
Expand Down
2 changes: 2 additions & 0 deletions core/services/chainlink/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ func TestConfig_Marshal(t *testing.T) {
NoNewFinalizedHeadsThreshold: &hour,

Transactions: evmcfg.Transactions{
Enabled: ptr(true),
MaxInFlight: ptr[uint32](19),
MaxQueued: ptr[uint32](99),
ReaperInterval: &minute,
Expand Down Expand Up @@ -1118,6 +1119,7 @@ FinalizedBlockOffset = 16
NoNewFinalizedHeadsThreshold = '1h0m0s'
[EVM.Transactions]
Enabled = true
ForwardersEnabled = true
MaxInFlight = 19
MaxQueued = 99
Expand Down
1 change: 1 addition & 0 deletions core/services/chainlink/testdata/config-full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ FinalizedBlockOffset = 16
NoNewFinalizedHeadsThreshold = '1h0m0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = true
MaxInFlight = 19
MaxQueued = 99
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ FinalizedBlockOffset = 12
NoNewFinalizedHeadsThreshold = '9m0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 250
Expand Down Expand Up @@ -430,6 +431,7 @@ FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 250
Expand Down Expand Up @@ -534,6 +536,7 @@ FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '6m0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 5000
Expand Down
1 change: 1 addition & 0 deletions core/web/resolver/testdata/config-full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '15m0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = true
MaxInFlight = 19
MaxQueued = 99
Expand Down
3 changes: 3 additions & 0 deletions core/web/resolver/testdata/config-multi-chain-effective.toml
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '9m0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 250
Expand Down Expand Up @@ -430,6 +431,7 @@ FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 250
Expand Down Expand Up @@ -534,6 +536,7 @@ FinalizedBlockOffset = 0
NoNewFinalizedHeadsThreshold = '6m0s'

[EVM.Transactions]
Enabled = true
ForwardersEnabled = false
MaxInFlight = 16
MaxQueued = 5000
Expand Down
Loading

0 comments on commit e706d72

Please sign in to comment.