Skip to content

Commit

Permalink
Feature/bci 2996 local finality violation (#13048)
Browse files Browse the repository at this point in the history
* implement RPCClient changes

* simplify interception of RPC's view on chain

* Remove redundant changes

* remove redundant changes

* do not pick RPC as active if it's lagging on finalized block

* fix race

* minor refactor

* Added FinalizedBlockOffset to config

* HeadTracker support of FinalizedBlockOffset

* fix lint issues

* switch logpoller to head tracker

* remove redundant changes

* fix build

* Capture latest chain info on RPC level to avoid race on state transition if we are communicating with RPC with highest finalized block

* EnforceRepeatableRead config option

* ensure HeadTracked does not miss block if it's committed  between initialHead processing and subscription

* hot fix flakey test

* fix build & changeset

* remove outdated test

* fix headtracker tests

* use polling in head tracker to get latest finalized block

* fix relay

* regen mocks

* use proper context in the LogPoller's latestBlocks

* fix flaky test

* fixes for changes from develop branch

* replace panic with FailNow

* report dead node only if it's dead for long enough

* fix racy test

* rollback foundry change caused by merge with develop

* use active node as source of HighestChainInfo to reduce number of transitions to nodeStateFinalizedBlockOutOfSync

* optimised loading of latest finalized block

* fix merge conflicts

* make generate

* simplify capturing of app layer observations

* ensure logpoller is not affected by FinalityTagBypass

* fix comment

* reset keystone to develop

* reset keystone

* reset to develop

* ungoimport

* move newChainIDSubForwarder into the test

* fix typo

* Move deathDeclarationDelay to config

* Comments adjustments

* fix merge issues

* regen mocks

* fix multinode flaky test

* refactor SetTotalDifficultyIfGt to MaxTotalDifficulty

* Use softer language in LatestFinalizedBlock comments

Co-authored-by: Dimitris Grigoriou <[email protected]>

* nits

* Ensure HistoryDepth is >= FinalizedBlockOffset

* regen mocks with newer version

---------

Co-authored-by: Dimitris Grigoriou <[email protected]>
Co-authored-by: Domino Valdano <[email protected]>
  • Loading branch information
3 people authored Jun 28, 2024
1 parent 363e829 commit 3f8c00a
Show file tree
Hide file tree
Showing 88 changed files with 2,654 additions and 978 deletions.
9 changes: 9 additions & 0 deletions .changeset/dull-ants-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"chainlink": patch
---

Fixed local finality violation caused by an RPC lagging behind on latest finalized block.

Added `EVM.FinalizedBlockOffset` and `EVM.NodePool.EnforceRepeatableRead` config options.
With `EnforceRepeatableRead = true`, RPC is considered healthy only if its most recent finalized block is larger or equal to the highest finalized block observed by the Node minus `FinalizedBlockOffset`.
#bugfix
17 changes: 17 additions & 0 deletions common/client/ctx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package client

import "context"

type multiNodeContextKey int

const (
contextKeyHeathCheckRequest multiNodeContextKey = iota + 1
)

func CtxAddHealthCheckFlag(ctx context.Context) context.Context {
return context.WithValue(ctx, contextKeyHeathCheckRequest, struct{}{})
}

func CtxIsHeathCheckRequest(ctx context.Context) bool {
return ctx.Value(contextKeyHeathCheckRequest) != nil
}
16 changes: 16 additions & 0 deletions common/client/ctx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package client

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
)

func TestContext(t *testing.T) {
ctx := tests.Context(t)
assert.False(t, CtxIsHeathCheckRequest(ctx), "expected false for test context")
ctx = CtxAddHealthCheckFlag(ctx)
assert.True(t, CtxIsHeathCheckRequest(ctx), "expected context to contain the healthcheck flag")
}
51 changes: 38 additions & 13 deletions common/client/mock_node_client_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 30 additions & 18 deletions common/client/mock_node_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 70 additions & 0 deletions common/client/mock_pool_chain_info_provider_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 38 additions & 13 deletions common/client/mock_rpc_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions common/client/mocks/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package mocks
import "time"

type ChainConfig struct {
IsFinalityTagEnabled bool
FinalityDepthVal uint32
NoNewHeadsThresholdVal time.Duration
IsFinalityTagEnabled bool
FinalityDepthVal uint32
NoNewHeadsThresholdVal time.Duration
FinalizedBlockOffsetVal uint32
}

func (t ChainConfig) NodeNoNewHeadsThreshold() time.Duration {
Expand All @@ -19,3 +20,7 @@ func (t ChainConfig) FinalityDepth() uint32 {
func (t ChainConfig) FinalityTagEnabled() bool {
return t.IsFinalityTagEnabled
}

func (t ChainConfig) FinalizedBlockOffset() uint32 {
return t.FinalizedBlockOffsetVal
}
Loading

0 comments on commit 3f8c00a

Please sign in to comment.