Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change difficulty from Big to BigInt #11388

Merged
merged 14 commits into from
Nov 29, 2023
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
Loading