diff --git a/.changeset/sour-owls-grab.md b/.changeset/sour-owls-grab.md new file mode 100644 index 0000000000..a45cd3da66 --- /dev/null +++ b/.changeset/sour-owls-grab.md @@ -0,0 +1,7 @@ +--- +"chainlink": patch +--- + +Added config option `HeadTracker.FinalityTagBypass` 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 bc7a4910b3..5191648e71 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) @@ -337,9 +337,23 @@ 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.FinalityTagBypass() { + 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 019aa9847d..e0eb422672 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 + FinalityTagBypass() 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 c46f5b72e6..8bc1ff188a 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) FinalityTagBypass() bool { + return *h.c.FinalityTagBypass +} + +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 34de754de2..9ee794e770 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 + FinalityTagBypass() 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 ddf9817958..69f6ea0875 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.FinalityTagBypass()) + 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 a326881bdd..a835c0bec5 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 + FinalityTagBypass *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.FinalityTagBypass; v != nil { + t.FinalityTagBypass = 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 b9fb2f2624..d48bfbea63 100644 --- a/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml +++ b/core/chains/evm/config/toml/defaults/Avalanche_Fuji.toml @@ -16,3 +16,6 @@ PriceMin = '25 gwei' [GasEstimator.BlockHistory] BlockHistorySize = 24 + +[HeadTracker] +FinalityTagBypass = 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 52bce72653..6309f39c0d 100644 --- a/core/chains/evm/config/toml/defaults/BSC_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/BSC_Testnet.toml @@ -28,6 +28,7 @@ BlockHistorySize = 24 [HeadTracker] HistoryDepth = 100 SamplingInterval = '1s' +FinalityTagBypass = false [OCR] DatabaseTimeout = '2s' diff --git a/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml b/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml index 82c71306e1..281dd51b50 100644 --- a/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Ethereum_Sepolia.toml @@ -13,3 +13,6 @@ TransactionPercentile = 50 [OCR2.Automation] GasLimit = 10500000 + +[HeadTracker] +FinalityTagBypass = false diff --git a/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml b/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml index 11a70bbf07..ac5e18a09b 100644 --- a/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml +++ b/core/chains/evm/config/toml/defaults/Linea_Sepolia.toml @@ -10,4 +10,4 @@ PriceMin = '1 wei' ResendAfterThreshold = '3m' [HeadTracker] -HistoryDepth = 1000 +HistoryDepth = 1000 \ No newline at end of file diff --git a/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml b/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml index 76b4da4bdb..2c3fc606a7 100644 --- a/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml +++ b/core/chains/evm/config/toml/defaults/WeMix_Testnet.toml @@ -13,3 +13,6 @@ ContractConfirmations = 1 [GasEstimator] EIP1559DynamicFees = true TipCapDefault = '100 gwei' + +[HeadTracker] +FinalityTagBypass = false diff --git a/core/chains/evm/config/toml/defaults/fallback.toml b/core/chains/evm/config/toml/defaults/fallback.toml index eb94ea4a75..a38bf5c901 100644 --- a/core/chains/evm/config/toml/defaults/fallback.toml +++ b/core/chains/evm/config/toml/defaults/fallback.toml @@ -55,6 +55,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +FinalityTagBypass = 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 e53ea0cd62..2deeaa3528 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) FinalityTagBypass() 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 bf2b984b54..b0d9a50da5 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 + FinalityTagBypass *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.FinalityTagBypass != nil { + c.EVM[0].HeadTracker.FinalityTagBypass = opts.FinalityTagBypass + } }) 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), FinalityTagBypass: 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), FinalityTagBypass: 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), FinalityTagBypass: 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), FinalityTagBypass: 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), FinalityTagBypass: ptr(true)}, + }, + { + Name: "Happy path (Chain FT is disabled & HeadTracker's FT is enabled, but ignored)", + Opts: opts{FinalityTagEnable: ptr(false), FinalityTagBypass: ptr(false)}, + }, + { + Name: "Happy path (Chain FT is enabled & HeadTracker's FT is disabled)", + Opts: opts{FinalityTagEnable: ptr(true), FinalityTagBypass: 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 0039c9ac27..745a69b377 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -302,6 +302,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 +# FinalityTagBypass 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 +FinalityTagBypass = 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 3425e3489f..98e36d764f 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -25,6 +25,7 @@ import ( "github.com/smartcontractkit/chainlink-solana/pkg/solana" 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" @@ -571,9 +572,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, + FinalityTagBypass: ptr[bool](false), + MaxAllowedFinalityDepth: ptr[uint32](1500), }, NodePool: evmcfg.NodePool{ @@ -1031,6 +1034,8 @@ TransactionPercentile = 15 HistoryDepth = 15 MaxBufferSize = 17 SamplingInterval = '1h0m0s' +MaxAllowedFinalityDepth = 1500 +FinalityTagBypass = false [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' @@ -1263,7 +1268,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 @@ -1271,6 +1276,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 5fdef3d604..5db9eaef83 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -333,6 +333,8 @@ TransactionPercentile = 15 HistoryDepth = 15 MaxBufferSize = 17 SamplingInterval = '1h0m0s' +MaxAllowedFinalityDepth = 1500 +FinalityTagBypass = false [[EVM.KeySpecific]] Key = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' diff --git a/core/services/chainlink/testdata/config-invalid.toml b/core/services/chainlink/testdata/config-invalid.toml index 7d1ed17c3c..40a4419fa2 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 01beacb0c8..73ea1d075f 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -310,6 +310,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 @@ -401,6 +403,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 @@ -486,6 +490,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 5c27817556..067b0d0b09 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -332,6 +332,8 @@ TransactionPercentile = 15 HistoryDepth = 15 MaxBufferSize = 17 SamplingInterval = '1h0m0s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = 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 01beacb0c8..73ea1d075f 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -310,6 +310,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 @@ -401,6 +403,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 @@ -486,6 +490,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c886d54db4..56990e284a 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1796,6 +1796,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -1881,6 +1883,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -1966,6 +1970,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2051,6 +2057,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2137,6 +2145,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2222,6 +2232,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2307,6 +2319,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2393,6 +2407,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2478,6 +2494,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2562,6 +2580,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2646,6 +2666,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2731,6 +2753,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = false [NodePool] PollFailureThreshold = 5 @@ -2817,6 +2841,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2902,6 +2928,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -2987,6 +3015,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3072,6 +3102,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3157,6 +3189,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3242,6 +3276,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3327,6 +3363,8 @@ TransactionPercentile = 60 HistoryDepth = 400 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3412,6 +3450,8 @@ TransactionPercentile = 60 HistoryDepth = 5 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3497,6 +3537,8 @@ TransactionPercentile = 60 HistoryDepth = 5 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3582,6 +3624,8 @@ TransactionPercentile = 60 HistoryDepth = 5 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3668,6 +3712,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3753,6 +3799,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -3839,6 +3887,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 2 @@ -3923,6 +3973,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4008,6 +4060,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4092,6 +4146,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4177,6 +4233,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4262,6 +4320,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = false [NodePool] PollFailureThreshold = 5 @@ -4346,6 +4406,8 @@ TransactionPercentile = 60 HistoryDepth = 10 MaxBufferSize = 100 SamplingInterval = '0s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4430,6 +4492,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4515,6 +4579,8 @@ TransactionPercentile = 60 HistoryDepth = 400 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4599,6 +4665,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4684,6 +4752,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4770,6 +4840,8 @@ TransactionPercentile = 60 HistoryDepth = 600 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4854,6 +4926,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -4939,6 +5013,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5024,6 +5100,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5110,6 +5188,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 2 @@ -5196,6 +5276,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5281,6 +5363,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5366,6 +5450,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = false [NodePool] PollFailureThreshold = 5 @@ -5451,6 +5537,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5536,6 +5624,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5620,6 +5710,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5704,6 +5796,8 @@ TransactionPercentile = 60 HistoryDepth = 1000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5788,6 +5882,8 @@ TransactionPercentile = 60 HistoryDepth = 350 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5873,6 +5969,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -5958,6 +6056,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6043,6 +6143,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6127,6 +6229,8 @@ TransactionPercentile = 60 HistoryDepth = 2000 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6213,6 +6317,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 4 @@ -6298,6 +6404,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6384,6 +6492,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6470,6 +6580,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6556,6 +6668,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6642,6 +6756,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6727,6 +6843,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6812,6 +6930,8 @@ TransactionPercentile = 60 HistoryDepth = 50 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -6897,6 +7017,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = false [NodePool] PollFailureThreshold = 5 @@ -6982,6 +7104,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -7068,6 +7192,8 @@ TransactionPercentile = 60 HistoryDepth = 300 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 4 @@ -7153,6 +7279,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -7238,6 +7366,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [NodePool] PollFailureThreshold = 5 @@ -7833,6 +7963,8 @@ Setting it lower will tend to set lower gas prices. HistoryDepth = 100 # Default MaxBufferSize = 3 # Default SamplingInterval = '1s' # Default +FinalityTagBypass = true # Default +MaxAllowedFinalityDepth = 10000 # Default ``` The head tracker continually listens for new heads from the chain. @@ -7863,6 +7995,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. +### FinalityTagBypass +```toml +FinalityTagBypass = true # Default +``` +FinalityTagBypass 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 49805a75da..718dc8acc4 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -366,6 +366,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = 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 0ce375997f..4401b3bbc8 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -366,6 +366,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = 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 f2195ed7a5..6a0d1cab3a 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -366,6 +366,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index b655c9b3b6..efd5392237 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -356,6 +356,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index d4b9a038a8..a8c53aa405 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -363,6 +363,8 @@ TransactionPercentile = 50 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index f4f08c9019..5fe319f935 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -362,6 +362,8 @@ TransactionPercentile = 60 HistoryDepth = 100 MaxBufferSize = 3 SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true [EVM.NodePool] PollFailureThreshold = 5