From 958b551b4ceea7fd301c4de779756633a9714a65 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko Date: Mon, 27 May 2024 20:11:38 +0200 Subject: [PATCH] Added config options to control HeadTracker's support of finality tags --- .changeset/sour-owls-grab.md | 7 + common/headtracker/head_tracker.go | 23 ++- common/headtracker/types/config.go | 2 + .../evm/config/chain_scoped_head_tracker.go | 8 ++ core/chains/evm/config/config.go | 2 + core/chains/evm/config/config_test.go | 2 + core/chains/evm/config/toml/config.go | 23 ++- .../config/toml/defaults/Avalanche_Fuji.toml | 3 + .../evm/config/toml/defaults/BSC_Testnet.toml | 1 + .../config/toml/defaults/Celo_Testnet.toml | 1 + .../toml/defaults/Ethereum_Sepolia.toml | 3 + .../config/toml/defaults/Gnosis_Chiado.toml | 3 + .../config/toml/defaults/Linea_Sepolia.toml | 1 + .../config/toml/defaults/Metis_Sepolia.toml | 3 + .../config/toml/defaults/Polygon_Amoy.toml | 1 + .../config/toml/defaults/WeMix_Testnet.toml | 3 + .../evm/config/toml/defaults/fallback.toml | 2 + .../chains/evm/headtracker/head_saver_test.go | 7 + .../evm/headtracker/head_tracker_test.go | 86 +++++++++-- core/config/docs/chains-evm.toml | 8 ++ core/services/chainlink/config_test.go | 14 +- .../chainlink/testdata/config-full.toml | 2 + .../chainlink/testdata/config-invalid.toml | 1 + .../config-multi-chain-effective.toml | 6 + core/web/resolver/testdata/config-full.toml | 2 + .../config-multi-chain-effective.toml | 6 + docs/CONFIG.md | 136 ++++++++++++++++++ .../disk-based-logging-disabled.txtar | 2 + .../validate/disk-based-logging-no-dir.txtar | 2 + .../node/validate/disk-based-logging.txtar | 2 + testdata/scripts/node/validate/invalid.txtar | 2 + testdata/scripts/node/validate/valid.txtar | 2 + testdata/scripts/node/validate/warnings.txtar | 2 + 33 files changed, 348 insertions(+), 20 deletions(-) create mode 100644 .changeset/sour-owls-grab.md diff --git a/.changeset/sour-owls-grab.md b/.changeset/sour-owls-grab.md new file mode 100644 index 00000000000..a31046b4a93 --- /dev/null +++ b/.changeset/sour-owls-grab.md @@ -0,0 +1,7 @@ +--- +"chainlink": patch +--- + +Added config option `HeadTracker.FinalityTagSupportDisabled` to force `HeadTracker` to track blocks up to `FinalityDepth` even if `FinalityTagsEnabled = true`. This option is a temporary measure to address high CPU usage on chains with extremely large actual finality depth (gap between the current head and the latest finalized block). #added + +Added config option `HeadTracker.MaxAllowedFinalityDepth` maximum gap between current head to the latest finalized block that `HeadTracker` considers healthy. #added diff --git a/common/headtracker/head_tracker.go b/common/headtracker/head_tracker.go index 6247e87c673..39275d5c9ba 100644 --- a/common/headtracker/head_tracker.go +++ b/common/headtracker/head_tracker.go @@ -119,7 +119,7 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) Start(ctx context.Context) error if ctx.Err() != nil { return ctx.Err() } - ht.log.Errorw("Error handling initial head", "err", err) + ht.log.Errorw("Error handling initial head", "err", err.Error()) } ht.wgDone.Add(3) @@ -338,9 +338,24 @@ func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) backfillLoop() { // calculateLatestFinalized - returns latest finalized block. It's expected that currentHeadNumber - is the head of // canonical chain. There is no guaranties that returned block belongs to the canonical chain. Additional verification // must be performed before usage. -func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) calculateLatestFinalized(ctx context.Context, currentHead HTH) (h HTH, err error) { - if ht.config.FinalityTagEnabled() { - return ht.client.LatestFinalizedBlock(ctx) +func (ht *headTracker[HTH, S, ID, BLOCK_HASH]) calculateLatestFinalized(ctx context.Context, currentHead HTH) (latestFinalized HTH, err error) { + if ht.config.FinalityTagEnabled() && !ht.htConfig.FinalityTagSupportDisabled() { + latestFinalized, err = ht.client.LatestFinalizedBlock(ctx) + if err != nil { + return latestFinalized, fmt.Errorf("failed to get latest finalized block: %w", err) + } + + if !latestFinalized.IsValid() { + return latestFinalized, fmt.Errorf("failed to get valid latest finalized block") + } + + if currentHead.BlockNumber()-latestFinalized.BlockNumber() > int64(ht.htConfig.MaxAllowedFinalityDepth()) { + return latestFinalized, fmt.Errorf("gap between latest finalized block (%d) and current head (%d) is too large (> %d)", + latestFinalized.BlockNumber(), currentHead.BlockNumber(), ht.htConfig.MaxAllowedFinalityDepth()) + } + + return latestFinalized, nil + } // no need to make an additional RPC call on chains with instant finality if ht.config.FinalityDepth() == 0 { diff --git a/common/headtracker/types/config.go b/common/headtracker/types/config.go index 019aa9847d9..08cb21cc2a5 100644 --- a/common/headtracker/types/config.go +++ b/common/headtracker/types/config.go @@ -12,4 +12,6 @@ type HeadTrackerConfig interface { HistoryDepth() uint32 MaxBufferSize() uint32 SamplingInterval() time.Duration + FinalityTagSupportDisabled() bool + MaxAllowedFinalityDepth() uint32 } diff --git a/core/chains/evm/config/chain_scoped_head_tracker.go b/core/chains/evm/config/chain_scoped_head_tracker.go index c46f5b72e6c..901a265309f 100644 --- a/core/chains/evm/config/chain_scoped_head_tracker.go +++ b/core/chains/evm/config/chain_scoped_head_tracker.go @@ -21,3 +21,11 @@ func (h *headTrackerConfig) MaxBufferSize() uint32 { func (h *headTrackerConfig) SamplingInterval() time.Duration { return h.c.SamplingInterval.Duration() } + +func (h *headTrackerConfig) FinalityTagSupportDisabled() bool { + return *h.c.FinalityTagSupportDisabled +} + +func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { + return *h.c.MaxAllowedFinalityDepth +} diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 34de754de21..82f3a5a23ff 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -70,6 +70,8 @@ type HeadTracker interface { HistoryDepth() uint32 MaxBufferSize() uint32 SamplingInterval() time.Duration + FinalityTagSupportDisabled() bool + MaxAllowedFinalityDepth() uint32 } type BalanceMonitor interface { diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index ddf9817958d..31f5e9060ac 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -376,6 +376,8 @@ func TestChainScopedConfig_HeadTracker(t *testing.T) { assert.Equal(t, uint32(100), ht.HistoryDepth()) assert.Equal(t, uint32(3), ht.MaxBufferSize()) assert.Equal(t, time.Second, ht.SamplingInterval()) + assert.Equal(t, true, ht.FinalityTagSupportDisabled()) + assert.Equal(t, uint32(10000), ht.MaxAllowedFinalityDepth()) } func Test_chainScopedConfig_Validate(t *testing.T) { diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index a326881bdde..de6877948ef 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -677,9 +677,11 @@ func (e *KeySpecificGasEstimator) setFrom(f *KeySpecificGasEstimator) { } type HeadTracker struct { - HistoryDepth *uint32 - MaxBufferSize *uint32 - SamplingInterval *commonconfig.Duration + HistoryDepth *uint32 + MaxBufferSize *uint32 + SamplingInterval *commonconfig.Duration + MaxAllowedFinalityDepth *uint32 + FinalityTagSupportDisabled *bool } func (t *HeadTracker) setFrom(f *HeadTracker) { @@ -692,6 +694,21 @@ func (t *HeadTracker) setFrom(f *HeadTracker) { if v := f.SamplingInterval; v != nil { t.SamplingInterval = v } + if v := f.MaxAllowedFinalityDepth; v != nil { + t.MaxAllowedFinalityDepth = v + } + if v := f.FinalityTagSupportDisabled; v != nil { + t.FinalityTagSupportDisabled = v + } +} + +func (t *HeadTracker) ValidateConfig() (err error) { + if *t.MaxAllowedFinalityDepth < 1 { + err = multierr.Append(err, commonconfig.ErrInvalid{Name: "MaxAllowedFinalityDepth", Value: *t.MaxAllowedFinalityDepth, + Msg: "must be greater than or equal to 1"}) + } + + return } type ClientErrors struct { diff --git a/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml b/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml index 98c4f9b44ea..da231e1a4cf 100644 --- a/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml +++ b/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml @@ -15,3 +15,6 @@ PriceMin = '25 gwei' [GasEstimator.BlockHistory] BlockHistorySize = 24 + +[HeadTracker] +FinalityTagSupportDisabled = false \ No newline at end of file diff --git a/core/chains/evm/config/toml/defaults/BSC_Testnet.toml b/core/chains/evm/config/toml/defaults/BSC_Testnet.toml index f97dafa0648..4dbd26a5282 100644 --- a/core/chains/evm/config/toml/defaults/BSC_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/BSC_Testnet.toml @@ -27,6 +27,7 @@ BlockHistorySize = 24 [HeadTracker] HistoryDepth = 100 SamplingInterval = '1s' +FinalityTagSupportDisabled = false [OCR] DatabaseTimeout = '2s' diff --git a/core/chains/evm/config/toml/defaults/Celo_Testnet.toml b/core/chains/evm/config/toml/defaults/Celo_Testnet.toml index 0508e86da3a..7b62f43b865 100644 --- a/core/chains/evm/config/toml/defaults/Celo_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/Celo_Testnet.toml @@ -17,3 +17,4 @@ BlockHistorySize = 24 [HeadTracker] HistoryDepth = 50 +FinalityTagSupportDisabled = false diff --git a/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml b/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml index 27acddeb721..c9caa7f493c 100644 --- a/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml @@ -12,3 +12,6 @@ TransactionPercentile = 50 [OCR2.Automation] GasLimit = 10500000 + +[HeadTracker] +FinalityTagSupportDisabled = false diff --git a/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml b/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml index 72c4ed13ae0..6f30139c498 100644 --- a/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml +++ b/core/chains/evm/config/toml/defaults/Gnosis_Chiado.toml @@ -9,3 +9,6 @@ EIP1559DynamicFees = true PriceMax = '500 gwei' # 15s delay since feeds update every minute in volatile situations BumpThreshold = 3 + +[HeadTracker] +FinalityTagSupportDisabled = false diff --git a/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml b/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml index 11a70bbf072..ad0dd6f02cc 100644 --- a/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml @@ -11,3 +11,4 @@ ResendAfterThreshold = '3m' [HeadTracker] HistoryDepth = 1000 +FinalityTagSupportDisabled = false \ No newline at end of file diff --git a/core/chains/evm/config/toml/defaults/Metis_Sepolia.toml b/core/chains/evm/config/toml/defaults/Metis_Sepolia.toml index d8ddffd77d7..4e48d80b809 100644 --- a/core/chains/evm/config/toml/defaults/Metis_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Metis_Sepolia.toml @@ -18,3 +18,6 @@ BlockHistorySize = 0 [NodePool] SyncThreshold = 10 + +[HeadTracker] +FinalityTagSupportDisabled = false diff --git a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml index c097e2f7e36..164b0890b8c 100644 --- a/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml +++ b/core/chains/evm/config/toml/defaults/Polygon_Amoy.toml @@ -26,6 +26,7 @@ BlockHistorySize = 24 [HeadTracker] HistoryDepth = 2000 SamplingInterval = '1s' +FinalityTagSupportDisabled = false [NodePool] SyncThreshold = 10 diff --git a/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml b/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml index 6cdb451eb1d..da996230aa4 100644 --- a/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml @@ -12,3 +12,6 @@ ContractConfirmations = 1 [GasEstimator] EIP1559DynamicFees = true TipCapDefault = '100 gwei' + +[HeadTracker] +FinalityTagSupportDisabled = false diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index d65d0a1b0c1..4ffb009ac44 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -54,6 +54,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +FinalityTagSupportDisabled = true +MaxAllowedFinalityDepth = 10000 [NodePool] PollFailureThreshold = 5 diff --git a/core/chains/evm/headtracker/head_saver_test.go b/core/chains/evm/headtracker/head_saver_test.go index 78058efa560..d7c7c100e3f 100644 --- a/core/chains/evm/headtracker/head_saver_test.go +++ b/core/chains/evm/headtracker/head_saver_test.go @@ -36,6 +36,13 @@ func (h *headTrackerConfig) MaxBufferSize() uint32 { return uint32(0) } +func (h *headTrackerConfig) FinalityTagSupportDisabled() bool { + return false +} +func (h *headTrackerConfig) MaxAllowedFinalityDepth() uint32 { + return 10000 +} + type config struct { finalityDepth uint32 blockEmissionIdleWarningThreshold time.Duration diff --git a/core/chains/evm/headtracker/head_tracker_test.go b/core/chains/evm/headtracker/head_tracker_test.go index bf2b984b548..f326eae79b6 100644 --- a/core/chains/evm/headtracker/head_tracker_test.go +++ b/core/chains/evm/headtracker/head_tracker_test.go @@ -205,11 +205,27 @@ func TestHeadTracker_Start(t *testing.T) { t.Parallel() const historyDepth = 100 - newHeadTracker := func(t *testing.T) *headTrackerUniverse { + const finalityDepth = 50 + type opts struct { + FinalityTagEnable *bool + MaxAllowedFinalityDepth *uint32 + FinalityTagSupportDisabled *bool + } + newHeadTracker := func(t *testing.T, opts opts) *headTrackerUniverse { db := pgtest.NewSqlxDB(t) gCfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, _ *chainlink.Secrets) { - c.EVM[0].FinalityTagEnabled = ptr[bool](true) + if opts.FinalityTagEnable != nil { + c.EVM[0].FinalityTagEnabled = opts.FinalityTagEnable + } c.EVM[0].HeadTracker.HistoryDepth = ptr[uint32](historyDepth) + c.EVM[0].FinalityDepth = ptr[uint32](finalityDepth) + if opts.MaxAllowedFinalityDepth != nil { + c.EVM[0].HeadTracker.MaxAllowedFinalityDepth = opts.MaxAllowedFinalityDepth + } + + if opts.FinalityTagSupportDisabled != nil { + c.EVM[0].HeadTracker.FinalityTagSupportDisabled = opts.FinalityTagSupportDisabled + } }) config := evmtest.NewChainScopedConfig(t, gCfg) orm := headtracker.NewORM(cltest.FixtureChainID, db) @@ -219,7 +235,7 @@ func TestHeadTracker_Start(t *testing.T) { t.Run("Fail start if context was canceled", func(t *testing.T) { ctx, cancel := context.WithCancel(testutils.Context(t)) - ht := newHeadTracker(t) + ht := newHeadTracker(t, opts{}) ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Run(func(args mock.Arguments) { cancel() }).Return(cltest.Head(0), context.Canceled) @@ -227,19 +243,19 @@ func TestHeadTracker_Start(t *testing.T) { require.ErrorIs(t, err, context.Canceled) }) t.Run("Starts even if failed to get initialHead", func(t *testing.T) { - ht := newHeadTracker(t) + ht := newHeadTracker(t, opts{}) ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(cltest.Head(0), errors.New("failed to get init head")) ht.Start(t) tests.AssertLogEventually(t, ht.observer, "Error handling initial head") }) t.Run("Starts even if received invalid head", func(t *testing.T) { - ht := newHeadTracker(t) + ht := newHeadTracker(t, opts{}) ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, nil) ht.Start(t) tests.AssertLogEventually(t, ht.observer, "Got nil initial head") }) t.Run("Starts even if fails to get finalizedHead", func(t *testing.T) { - ht := newHeadTracker(t) + ht := newHeadTracker(t, opts{FinalityTagEnable: ptr(true), FinalityTagSupportDisabled: ptr(false)}) head := cltest.Head(1000) ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(head, nil).Once() ht.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(nil, errors.New("failed to load latest finalized")).Once() @@ -247,16 +263,31 @@ func TestHeadTracker_Start(t *testing.T) { tests.AssertLogEventually(t, ht.observer, "Error handling initial head") }) t.Run("Starts even if latest finalizedHead is nil", func(t *testing.T) { - ht := newHeadTracker(t) + ht := newHeadTracker(t, opts{FinalityTagEnable: ptr(true), FinalityTagSupportDisabled: ptr(false)}) head := cltest.Head(1000) ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(head, nil).Once() ht.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(nil, nil).Once() + ht.ethClient.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(nil, errors.New("failed to connect")).Maybe() ht.Start(t) tests.AssertLogEventually(t, ht.observer, "Error handling initial head") }) - t.Run("Happy path", func(t *testing.T) { + t.Run("Logs error if finality gap is too big", func(t *testing.T) { + ht := newHeadTracker(t, opts{FinalityTagEnable: ptr(true), FinalityTagSupportDisabled: ptr(false), MaxAllowedFinalityDepth: ptr(uint32(10))}) + head := cltest.Head(1000) + ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(head, nil).Once() + ht.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(cltest.Head(989), nil).Once() + ht.ethClient.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(nil, errors.New("failed to connect")).Maybe() + ht.Start(t) + tests.AssertEventually(t, func() bool { + // must exactly match the error passed to logger + field := zap.String("err", "failed to calculate latest finalized head: gap between latest finalized block (989) and current head (1000) is too large (> 10)") + filtered := ht.observer.FilterMessage("Error handling initial head").FilterField(field) + return filtered.Len() > 0 + }) + }) + t.Run("Happy path (finality tag)", func(t *testing.T) { head := cltest.Head(1000) - ht := newHeadTracker(t) + ht := newHeadTracker(t, opts{FinalityTagEnable: ptr(true), FinalityTagSupportDisabled: ptr(false)}) ctx := testutils.Context(t) require.NoError(t, ht.orm.IdempotentInsertHead(ctx, cltest.Head(799))) ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(head, nil).Once() @@ -265,9 +296,46 @@ func TestHeadTracker_Start(t *testing.T) { ht.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(finalizedHead, nil).Once() // on backfill ht.ethClient.On("LatestFinalizedBlock", mock.Anything).Return(nil, errors.New("backfill call to finalized failed")).Maybe() + ht.ethClient.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(nil, errors.New("failed to connect")).Maybe() ht.Start(t) tests.AssertLogEventually(t, ht.observer, "Loaded chain from DB") }) + happyPathFD := func(t *testing.T, opts opts) { + head := cltest.Head(1000) + ht := newHeadTracker(t, opts) + ht.ethClient.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(head, nil).Once() + finalizedHead := cltest.Head(head.Number - finalityDepth) + ht.ethClient.On("HeadByNumber", mock.Anything, big.NewInt(finalizedHead.Number)).Return(finalizedHead, nil).Once() + ctx := testutils.Context(t) + require.NoError(t, ht.orm.IdempotentInsertHead(ctx, cltest.Head(finalizedHead.Number-1))) + // on backfill + ht.ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(nil, errors.New("backfill call to finalized failed")).Maybe() + ht.ethClient.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(nil, errors.New("failed to connect")).Maybe() + ht.Start(t) + tests.AssertLogEventually(t, ht.observer, "Loaded chain from DB") + } + testCases := []struct { + Name string + Opts opts + }{ + { + Name: "Happy path (Chain FT is disabled & HeadTracker's FT is disabled)", + Opts: opts{FinalityTagEnable: ptr(false), FinalityTagSupportDisabled: ptr(true)}, + }, + { + Name: "Happy path (Chain FT is disabled & HeadTracker's FT is enabled, but ignored)", + Opts: opts{FinalityTagEnable: ptr(false), FinalityTagSupportDisabled: ptr(false)}, + }, + { + Name: "Happy path (Chain FT is enabled & HeadTracker's FT is disabled)", + Opts: opts{FinalityTagEnable: ptr(true), FinalityTagSupportDisabled: ptr(true)}, + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + happyPathFD(t, tc.Opts) + }) + } } func TestHeadTracker_CallsHeadTrackableCallbacks(t *testing.T) { diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 49360caad21..30391e353bf 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -301,6 +301,14 @@ MaxBufferSize = 3 # Default # **ADVANCED** # SamplingInterval means that head tracker callbacks will at maximum be made once in every window of this duration. This is a performance optimisation for fast chains. Set to 0 to disable sampling entirely. SamplingInterval = '1s' # Default +# FinalityTagSupportDisabled disables FinalityTag support in HeadTracker and makes it track blocks up to FinalityDepth from the most recent head. +# It should only be used on chains with an extremely large actual finality depth (the number of blocks between the most recent head and the latest finalized block). +# Has no effect if `FinalityTagsEnabled` = false +FinalityTagSupportDisabled = true # Default +# MaxAllowedFinalityDepth - defines maximum number of blocks between the most recent head and the latest finalized block. +# If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. +# Has no effect if `FinalityTagsEnabled` = false +MaxAllowedFinalityDepth = 10000 # Default [[EVM.KeySpecific]] # Key is the account to apply these settings to diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 8119021b565..3773d2b08c2 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -24,6 +24,7 @@ import ( coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config" stkcfg "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" + commonconfig "github.com/smartcontractkit/chainlink/v2/common/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -569,9 +570,11 @@ func TestConfig_Marshal(t *testing.T) { }, HeadTracker: evmcfg.HeadTracker{ - HistoryDepth: ptr[uint32](15), - MaxBufferSize: ptr[uint32](17), - SamplingInterval: &hour, + HistoryDepth: ptr[uint32](15), + MaxBufferSize: ptr[uint32](17), + SamplingInterval: &hour, + FinalityTagSupportDisabled: ptr[bool](false), + MaxAllowedFinalityDepth: ptr[uint32](1500), }, NodePool: evmcfg.NodePool{ @@ -1028,6 +1031,8 @@ TransactionPercentile = 15 HistoryDepth = 15 MaxBufferSize = 17 SamplingInterval = '1h0m0s' +MaxAllowedFinalityDepth = 1500 +FinalityTagSupportDisabled = false [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' @@ -1260,7 +1265,7 @@ func TestConfig_Validate(t *testing.T) { - WSURL: missing: required for primary nodes - HTTPURL: missing: required for all nodes - 1.HTTPURL: missing: required for all nodes - - 1: 6 errors: + - 1: 7 errors: - ChainType: invalid value (Foo): must not be set with this chain id - Nodes: missing: must have at least one node - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zksync or omitted @@ -1268,6 +1273,7 @@ func TestConfig_Validate(t *testing.T) { - GasEstimator: 2 errors: - FeeCapDefault: invalid value (101 wei): must be equal to PriceMax (99 wei) since you are using FixedPrice estimation with gas bumping disabled in EIP1559 mode - PriceMax will be used as the FeeCap for transactions instead of FeeCapDefault - PriceMax: invalid value (1 gwei): must be greater than or equal to PriceDefault + - HeadTracker.MaxAllowedFinalityDepth: invalid value (0): must be greater than or equal to 1 - KeySpecific.Key: invalid value (0xde709f2102306220921060314715629080e2fb77): duplicate - must be unique - 2: 5 errors: - ChainType: invalid value (Arbitrum): only "optimismBedrock" can be used with this chain id diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index b199ae530f5..655dbc3604b 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -332,6 +332,8 @@ TransactionPercentile = 15 HistoryDepth = 15 MaxBufferSize = 17 SamplingInterval = '1h0m0s' +MaxAllowedFinalityDepth = 1500 +FinalityTagSupportDisabled = false [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/services/chainlink/testdata/config-invalid.toml b/core/services/chainlink/testdata/config-invalid.toml index 7d1ed17c3c2..40a4419fa29 100644 --- a/core/services/chainlink/testdata/config-invalid.toml +++ b/core/services/chainlink/testdata/config-invalid.toml @@ -63,6 +63,7 @@ PriceMax = 99 [EVM.HeadTracker] HistoryDepth = 30 +MaxAllowedFinalityDepth = 0 [[EVM.KeySpecific]] Key = '0xde709f2102306220921060314715629080e2fb77' diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index 7aa3bb50b35..5b9d67cc556 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -309,6 +309,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 @@ -400,6 +402,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 @@ -485,6 +489,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 75fad4d2fc9..e6d2eae9e2c 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -331,6 +331,8 @@ TransactionPercentile = 15 HistoryDepth = 15 MaxBufferSize = 17 SamplingInterval = '1h0m0s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index 7aa3bb50b35..5b9d67cc556 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -309,6 +309,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 @@ -400,6 +402,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 @@ -485,6 +489,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index a0e2957cd72..9ae575d7025 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1789,6 +1789,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -1874,6 +1876,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -1959,6 +1963,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2044,6 +2050,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2130,6 +2138,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2215,6 +2225,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2300,6 +2312,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2386,6 +2400,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2471,6 +2487,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2555,6 +2573,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2639,6 +2659,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2724,6 +2746,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -2810,6 +2834,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2895,6 +2921,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -2980,6 +3008,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3065,6 +3095,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3150,6 +3182,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3235,6 +3269,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3320,6 +3356,8 @@ TransactionPercentile = 60 HistoryDepth = 400 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3405,6 +3443,8 @@ TransactionPercentile = 60 HistoryDepth = 5 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3490,6 +3530,8 @@ TransactionPercentile = 60 HistoryDepth = 5 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3575,6 +3617,8 @@ TransactionPercentile = 60 HistoryDepth = 5 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3661,6 +3705,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3746,6 +3792,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3830,6 +3878,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3915,6 +3965,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -3999,6 +4051,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4084,6 +4138,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4169,6 +4225,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -4253,6 +4311,8 @@ TransactionPercentile = 60 HistoryDepth = 10 MaxBufferSize = 100 SamplingInterval = '0s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4337,6 +4397,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4422,6 +4484,8 @@ TransactionPercentile = 60 HistoryDepth = 400 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4506,6 +4570,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4591,6 +4657,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4675,6 +4743,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4760,6 +4830,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -4845,6 +4917,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -4931,6 +5005,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -5016,6 +5092,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -5101,6 +5179,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -5186,6 +5266,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -5271,6 +5353,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -5355,6 +5439,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -5439,6 +5525,8 @@ TransactionPercentile = 60 HistoryDepth = 1000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -5523,6 +5611,8 @@ TransactionPercentile = 60 HistoryDepth = 350 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -5608,6 +5698,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -5693,6 +5785,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -5777,6 +5871,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -5862,6 +5958,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -5947,6 +6045,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6033,6 +6133,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6119,6 +6221,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6204,6 +6308,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6289,6 +6395,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6374,6 +6482,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6459,6 +6569,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [NodePool] PollFailureThreshold = 5 @@ -6544,6 +6656,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6629,6 +6743,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -6714,6 +6830,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [NodePool] PollFailureThreshold = 5 @@ -7308,6 +7426,8 @@ Setting it lower will tend to set lower gas prices. HistoryDepth = 100 # Default MaxBufferSize = 3 # Default SamplingInterval = '1s' # Default +FinalityTagSupportDisabled = true # Default +MaxAllowedFinalityDepth = 10000 # Default ``` The head tracker continually listens for new heads from the chain. @@ -7338,6 +7458,22 @@ SamplingInterval = '1s' # Default ``` SamplingInterval means that head tracker callbacks will at maximum be made once in every window of this duration. This is a performance optimisation for fast chains. Set to 0 to disable sampling entirely. +### FinalityTagSupportDisabled +```toml +FinalityTagSupportDisabled = true # Default +``` +FinalityTagSupportDisabled disables FinalityTag support in HeadTracker and makes it track blocks up to FinalityDepth from the most recent head. +It should only be used on chains with an extremely large actual finality depth (the number of blocks between the most recent head and the latest finalized block). +Has no effect if `FinalityTagsEnabled` = false + +### MaxAllowedFinalityDepth +```toml +MaxAllowedFinalityDepth = 10000 # Default +``` +MaxAllowedFinalityDepth - defines maximum number of blocks between the most recent head and the latest finalized block. +If actual finality depth exceeds this number, HeadTracker aborts backfill and returns an error. +Has no effect if `FinalityTagsEnabled` = false + ## EVM.KeySpecific ```toml [[EVM.KeySpecific]] diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index feaf546f022..3de2d695085 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -365,6 +365,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index b37fed41150..b3f86a37786 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -365,6 +365,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index 6ae02ab38f4..94105facc31 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -365,6 +365,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index df0118bbbbf..60b5a60b418 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -355,6 +355,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index edb07fd5e4f..46db768e8e9 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -362,6 +362,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index 54de3227a9e..70c5e2e4781 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -361,6 +361,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagSupportDisabled = false [EVM.NodePool] PollFailureThreshold = 5