Skip to content

Commit

Permalink
Change difficulty from Big to BigInt (#11388)
Browse files Browse the repository at this point in the history
* Change difficulty from Big to BigInt

* Fix headtracker mock head

* Remove EsnureClosed

* Fix mock heads

* Fix Tracker close on txm
  • Loading branch information
dimriou authored Nov 29, 2023
1 parent 3876d9e commit f771000
Show file tree
Hide file tree
Showing 34 changed files with 188 additions and 200 deletions.
11 changes: 6 additions & 5 deletions common/client/mock_head_test.go

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

14 changes: 7 additions & 7 deletions common/client/mock_node_test.go

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

6 changes: 3 additions & 3 deletions common/client/multi_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/assets"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"
"github.com/smartcontractkit/chainlink-common/pkg/utils"

"github.com/smartcontractkit/chainlink/v2/common/config"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
"github.com/smartcontractkit/chainlink/v2/common/types"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)

var (
Expand Down Expand Up @@ -261,8 +261,8 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP

// nLiveNodes returns the number of currently alive nodes, as well as the highest block number and greatest total difficulty.
// totalDifficulty will be 0 if all nodes return nil.
func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) nLiveNodes() (nLiveNodes int, blockNumber int64, totalDifficulty *utils.Big) {
totalDifficulty = utils.NewBigI(0)
func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT]) nLiveNodes() (nLiveNodes int, blockNumber int64, totalDifficulty *big.Int) {
totalDifficulty = big.NewInt(0)
for _, n := range c.nodes {
if s, num, td := n.StateAndLatest(); s == nodeStateAlive {
nLiveNodes++
Expand Down
28 changes: 14 additions & 14 deletions common/client/multi_node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"fmt"
big "math/big"
"math/rand"
"testing"
"time"
Expand All @@ -17,14 +18,13 @@ import (

"github.com/smartcontractkit/chainlink/v2/common/config"
"github.com/smartcontractkit/chainlink/v2/common/types"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)

type multiNodeRPCClient RPC[types.ID, *utils.Big, Hashable, Hashable, any, Hashable, any, any,
type multiNodeRPCClient RPC[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any,
types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable]]

type testMultiNode struct {
*multiNode[types.ID, *utils.Big, Hashable, Hashable, any, Hashable, any, any,
*multiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any,
types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient]
}

Expand All @@ -46,19 +46,19 @@ func newTestMultiNode(t *testing.T, opts multiNodeOpts) testMultiNode {
opts.logger = logger.Test(t)
}

result := NewMultiNode[types.ID, *utils.Big, Hashable, Hashable, any, Hashable, any, any,
result := NewMultiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any,
types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient](opts.logger,
opts.selectionMode, opts.leaseDuration, opts.noNewHeadsThreshold, opts.nodes, opts.sendonlys,
opts.chainID, opts.chainType, opts.chainFamily, opts.sendOnlyErrorParser)
return testMultiNode{
result.(*multiNode[types.ID, *utils.Big, Hashable, Hashable, any, Hashable, any, any,
result.(*multiNode[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any,
types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable], multiNodeRPCClient]),
}
}

func newMultiNodeRPCClient(t *testing.T) *mockRPC[types.ID, *utils.Big, Hashable, Hashable, any, Hashable, any, any,
func newMultiNodeRPCClient(t *testing.T) *mockRPC[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any,
types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable]] {
return newMockRPC[types.ID, *utils.Big, Hashable, Hashable, any, Hashable, any, any,
return newMockRPC[types.ID, *big.Int, Hashable, Hashable, any, Hashable, any, any,
types.Receipt[Hashable, Hashable], Hashable, types.Head[Hashable]](t)
}

Expand Down Expand Up @@ -424,40 +424,40 @@ func TestMultiNode_nLiveNodes(t *testing.T) {
t.Parallel()
type nodeParams struct {
BlockNumber int64
TotalDifficulty *utils.Big
TotalDifficulty *big.Int
State nodeState
}
testCases := []struct {
Name string
ExpectedNLiveNodes int
ExpectedBlockNumber int64
ExpectedTotalDifficulty *utils.Big
ExpectedTotalDifficulty *big.Int
NodeParams []nodeParams
}{
{
Name: "no nodes",
ExpectedTotalDifficulty: utils.NewBigI(0),
ExpectedTotalDifficulty: big.NewInt(0),
},
{
Name: "Best node is not healthy",
ExpectedTotalDifficulty: utils.NewBigI(10),
ExpectedTotalDifficulty: big.NewInt(10),
ExpectedBlockNumber: 20,
ExpectedNLiveNodes: 3,
NodeParams: []nodeParams{
{
State: nodeStateOutOfSync,
BlockNumber: 1000,
TotalDifficulty: utils.NewBigI(2000),
TotalDifficulty: big.NewInt(2000),
},
{
State: nodeStateAlive,
BlockNumber: 20,
TotalDifficulty: utils.NewBigI(9),
TotalDifficulty: big.NewInt(9),
},
{
State: nodeStateAlive,
BlockNumber: 19,
TotalDifficulty: utils.NewBigI(10),
TotalDifficulty: big.NewInt(10),
},
{
State: nodeStateAlive,
Expand Down
8 changes: 4 additions & 4 deletions common/client/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package client
import (
"context"
"fmt"
"math/big"
"net/url"
"sync"
"time"
Expand All @@ -15,7 +16,6 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/services"

"github.com/smartcontractkit/chainlink/v2/common/types"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)

const QueryTimeout = 10 * time.Second
Expand Down Expand Up @@ -53,7 +53,7 @@ type Node[
// State returns nodeState
State() nodeState
// StateAndLatest returns nodeState with the latest received block number & total difficulty.
StateAndLatest() (nodeState, int64, *utils.Big)
StateAndLatest() (nodeState, int64, *big.Int)
// Name is a unique identifier for this node.
Name() string
String() string
Expand Down Expand Up @@ -90,7 +90,7 @@ type node[
state nodeState
// Each node is tracking the last received head number and total difficulty
stateLatestBlockNumber int64
stateLatestTotalDifficulty *utils.Big
stateLatestTotalDifficulty *big.Int

// nodeCtx is the node lifetime's context
nodeCtx context.Context
Expand All @@ -103,7 +103,7 @@ type node[
// 1. see how many live nodes there are in total, so we can prevent the last alive node in a pool from being
// moved to out-of-sync state. It is better to have one out-of-sync node than no nodes at all.
// 2. compare against the highest head (by number or difficulty) to ensure we don't fall behind too far.
nLiveNodes func() (count int, blockNumber int64, totalDifficulty *utils.Big)
nLiveNodes func() (count int, blockNumber int64, totalDifficulty *big.Int)
}

func NewNode[
Expand Down
7 changes: 3 additions & 4 deletions common/client/node_fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package client

import (
"fmt"
"math/big"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

"github.com/smartcontractkit/chainlink/v2/core/utils"
)

var (
Expand Down Expand Up @@ -110,7 +109,7 @@ func (n *node[CHAIN_ID, HEAD, RPC]) State() nodeState {
return n.state
}

func (n *node[CHAIN_ID, HEAD, RPC]) StateAndLatest() (nodeState, int64, *utils.Big) {
func (n *node[CHAIN_ID, HEAD, RPC]) StateAndLatest() (nodeState, int64, *big.Int) {
n.stateMu.RLock()
defer n.stateMu.RUnlock()
return n.state, n.stateLatestBlockNumber, n.stateLatestTotalDifficulty
Expand Down Expand Up @@ -182,7 +181,7 @@ func (n *node[CHAIN_ID, HEAD, RPC]) transitionToInSync(fn func()) {

// declareOutOfSync puts a node into OutOfSync state, disconnecting all current
// clients and making it unavailable for use until back in-sync.
func (n *node[CHAIN_ID, HEAD, RPC]) declareOutOfSync(isOutOfSync func(num int64, td *utils.Big) bool) {
func (n *node[CHAIN_ID, HEAD, RPC]) declareOutOfSync(isOutOfSync func(num int64, td *big.Int) bool) {
n.transitionToOutOfSync(func() {
n.lfcLog.Errorw("RPC Node is out of sync", "nodeState", n.state)
n.wg.Add(1)
Expand Down
17 changes: 10 additions & 7 deletions common/client/node_lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import (
"context"
"fmt"
"math"
"math/big"
"time"

"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
bigmath "github.com/smartcontractkit/chainlink-common/pkg/utils/big_math"

"github.com/smartcontractkit/chainlink/v2/core/utils"
)

Expand Down Expand Up @@ -49,7 +52,7 @@ func zombieNodeCheckInterval(noNewHeadsThreshold time.Duration) time.Duration {
return utils.WithJitter(interval)
}

func (n *node[CHAIN_ID, HEAD, RPC]) setLatestReceived(blockNumber int64, totalDifficulty *utils.Big) {
func (n *node[CHAIN_ID, HEAD, RPC]) setLatestReceived(blockNumber int64, totalDifficulty *big.Int) {
n.stateMu.Lock()
defer n.stateMu.Unlock()
n.stateLatestBlockNumber = blockNumber
Expand Down Expand Up @@ -216,21 +219,21 @@ func (n *node[CHAIN_ID, HEAD, RPC]) aliveLoop() {
continue
}
}
n.declareOutOfSync(func(num int64, td *utils.Big) bool { return num < highestReceivedBlockNumber })
n.declareOutOfSync(func(num int64, td *big.Int) bool { return num < highestReceivedBlockNumber })
return
}
}
}

func (n *node[CHAIN_ID, HEAD, RPC]) isOutOfSync(num int64, td *utils.Big) (outOfSync bool) {
func (n *node[CHAIN_ID, HEAD, RPC]) isOutOfSync(num int64, td *big.Int) (outOfSync bool) {
outOfSync, _ = n.syncStatus(num, td)
return
}

// syncStatus returns outOfSync true if num or td is more than SyncThresold behind the best node.
// Always returns outOfSync false for SyncThreshold 0.
// liveNodes is only included when outOfSync is true.
func (n *node[CHAIN_ID, HEAD, RPC]) syncStatus(num int64, td *utils.Big) (outOfSync bool, liveNodes int) {
func (n *node[CHAIN_ID, HEAD, RPC]) syncStatus(num int64, td *big.Int) (outOfSync bool, liveNodes int) {
if n.nLiveNodes == nil {
return // skip for tests
}
Expand All @@ -245,8 +248,8 @@ func (n *node[CHAIN_ID, HEAD, RPC]) syncStatus(num int64, td *utils.Big) (outOfS
case NodeSelectionModeHighestHead, NodeSelectionModeRoundRobin, NodeSelectionModePriorityLevel:
return num < highest-int64(threshold), ln
case NodeSelectionModeTotalDifficulty:
bigThreshold := utils.NewBigI(int64(threshold))
return td.Cmp(greatest.Sub(bigThreshold)) < 0, ln
bigThreshold := big.NewInt(int64(threshold))
return td.Cmp(bigmath.Sub(greatest, bigThreshold)) < 0, ln
default:
panic("unrecognized NodeSelectionMode: " + mode)
}
Expand All @@ -258,7 +261,7 @@ const (
)

// outOfSyncLoop takes an OutOfSync node and waits until isOutOfSync returns false to go back to live status
func (n *node[CHAIN_ID, HEAD, RPC]) outOfSyncLoop(isOutOfSync func(num int64, td *utils.Big) bool) {
func (n *node[CHAIN_ID, HEAD, RPC]) outOfSyncLoop(isOutOfSync func(num int64, td *big.Int) bool) {
defer n.wg.Done()

{
Expand Down
Loading

0 comments on commit f771000

Please sign in to comment.