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

Soft migration to Generalize Multinode client for EVM BCI-2286 #11369

Merged
merged 12 commits into from
Nov 28, 2023
2 changes: 1 addition & 1 deletion core/chains/evm/client/chain_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (c *chainClient) BlockByNumber(ctx context.Context, number *big.Int) (b *ty
}

func (c *chainClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
return c.multiNode.CallContext(ctx, result, method)
return c.multiNode.CallContext(ctx, result, method, args...)
}

func (c *chainClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
Expand Down
2 changes: 2 additions & 0 deletions core/chains/evm/client/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ var (
//go:generate mockery --quiet --name Node --output ../mocks/ --case=underscore

// Node represents a client that connects to an ethereum-compatible RPC node
// Deprecated: use chainClient instead
type Node interface {
Start(ctx context.Context) error
Close() error
Expand Down Expand Up @@ -133,6 +134,7 @@ type rawclient struct {

// Node represents one ethereum node.
// It must have a ws url and may have a http url
// Deprecated: use chainClient instead
type node struct {
services.StateMachine
lfcLog logger.Logger
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/client/node_fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ var (

// NodeState represents the current state of the node
// Node is a FSM (finite state machine)
// Deprecated: nodeState is now internal for common/client
type NodeState int

func (n NodeState) String() string {
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/client/node_selector_highest_head.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

type highestHeadNodeSelector []Node

// Deprecated: use corresponding function from common/client
func NewHighestHeadNodeSelector(nodes []Node) NodeSelector {
return highestHeadNodeSelector(nodes)
}
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/client/node_selector_priority_level.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type nodeWithPriority struct {
priority int32
}

// Deprecated: use corresponding function from common/client
func NewPriorityLevelNodeSelector(nodes []Node) NodeSelector {
return &priorityLevelNodeSelector{
nodes: nodes,
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/client/node_selector_round_robin.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type roundRobinSelector struct {
roundRobinCount atomic.Uint32
}

// Deprecated: use corresponding function from common/client
func NewRoundRobinSelector(nodes []Node) NodeSelector {
return &roundRobinSelector{
nodes: nodes,
Expand Down
1 change: 1 addition & 0 deletions core/chains/evm/client/node_selector_total_difficulty.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

type totalDifficultyNodeSelector []Node

// Deprecated: use corresponding function from common/client
func NewTotalDifficultyNodeSelector(nodes []Node) NodeSelector {
return totalDifficultyNodeSelector(nodes)
}
Expand Down
60 changes: 19 additions & 41 deletions core/chains/legacyevm/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/services"
"github.com/smartcontractkit/chainlink-common/pkg/types"

commonclient "github.com/smartcontractkit/chainlink/v2/common/client"
commonconfig "github.com/smartcontractkit/chainlink/v2/common/config"
"github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
Expand Down Expand Up @@ -220,11 +221,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod
if !cfg.EVMRPCEnabled() {
client = evmclient.NewNullClient(chainID, l)
} else if opts.GenEthClient == nil {
var err2 error
client, err2 = newEthClientFromChain(cfg.EVM().NodePool(), cfg.EVM().NodeNoNewHeadsThreshold(), l, chainID, chainType, nodes)
if err2 != nil {
return nil, fmt.Errorf("failed to instantiate eth client for chain with ID %s: %w", cfg.EVM().ChainID().String(), err2)
}
client = newEthClientFromCfg(cfg.EVM().NodePool(), cfg.EVM().NodeNoNewHeadsThreshold(), l, chainID, chainType, nodes)
} else {
client = opts.GenEthClient(chainID)
}
Expand Down Expand Up @@ -474,46 +471,27 @@ func (c *chain) Logger() logger.Logger { return c.logger }
func (c *chain) BalanceMonitor() monitor.BalanceMonitor { return c.balanceMonitor }
func (c *chain) GasEstimator() gas.EvmFeeEstimator { return c.gasEstimator }

func newEthClientFromChain(cfg evmconfig.NodePool, noNewHeadsThreshold time.Duration, lggr logger.Logger, chainID *big.Int, chainType commonconfig.ChainType, nodes []*toml.Node) (evmclient.Client, error) {
var primaries []evmclient.Node
var sendonlys []evmclient.SendOnlyNode
func newEthClientFromCfg(cfg evmconfig.NodePool, noNewHeadsThreshold time.Duration, lggr logger.Logger, chainID *big.Int, chainType commonconfig.ChainType, nodes []*toml.Node) evmclient.Client {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we renamed this method?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method has no arguments with name or type chain (except chainID), so it felt weird to name it FromChain.
But I do not mind renaming it back to the newEthClientFromChain

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, sounds reasonable

var empty url.URL
var primaries []commonclient.Node[*big.Int, *evmtypes.Head, evmclient.RPCCLient]
var sendonlys []commonclient.SendOnlyNode[*big.Int, evmclient.RPCCLient]
for i, node := range nodes {
if node.SendOnly != nil && *node.SendOnly {
sendonly := evmclient.NewSendOnlyNode(lggr, (url.URL)(*node.HTTPURL), *node.Name, chainID)
name := fmt.Sprintf("eth-sendonly-rpc-%d", i)
rpc := evmclient.NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), name, int32(i), chainID,
commonclient.Secondary)
sendonly := commonclient.NewSendOnlyNode[*big.Int, evmclient.RPCCLient](lggr, (url.URL)(*node.HTTPURL),
*node.Name, chainID, rpc)
sendonlys = append(sendonlys, sendonly)
} else {
primary, err := newPrimary(cfg, noNewHeadsThreshold, lggr, node, int32(i), chainID)
if err != nil {
return nil, err
}
primaries = append(primaries, primary)
name := fmt.Sprintf("eth-primary-rpc-%d", i)
rpc := evmclient.NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), name, int32(i),
chainID, commonclient.Primary)
primaryNode := commonclient.NewNode[*big.Int, *evmtypes.Head, evmclient.RPCCLient](cfg, noNewHeadsThreshold,
lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, *node.Order,
rpc, "EVM")
primaries = append(primaries, primaryNode)
}
}
return evmclient.NewClientWithNodes(lggr, cfg.SelectionMode(), cfg.LeaseDuration(), noNewHeadsThreshold, primaries, sendonlys, chainID, chainType)
return evmclient.NewChainClient(lggr, cfg.SelectionMode(), cfg.LeaseDuration(), noNewHeadsThreshold, primaries, sendonlys, chainID, chainType)
}

func newPrimary(cfg evmconfig.NodePool, noNewHeadsThreshold time.Duration, lggr logger.Logger, n *toml.Node, id int32, chainID *big.Int) (evmclient.Node, error) {
if n.SendOnly != nil && *n.SendOnly {
return nil, errors.New("cannot cast send-only node to primary")
}

return evmclient.NewNode(cfg, noNewHeadsThreshold, lggr, (url.URL)(*n.WSURL), (*url.URL)(n.HTTPURL), *n.Name, id, chainID, *n.Order), nil
}

// TODO-1663: replace newEthClientFromChain with the function below once client.go is deprecated.
//func newEthClientFromChain(cfg evmconfig.NodePool, noNewHeadsThreshold time.Duration, lggr logger.Logger, chainID *big.Int, chainType config.ChainType, nodes []*toml.Node) evmclient.Client {
// var empty url.URL
// var primaries []commonclient.Node[*big.Int, *evmtypes.Head, evmclient.RPCCLient]
// var sendonlys []commonclient.SendOnlyNode[*big.Int, evmclient.RPCCLient]
// for i, node := range nodes {
// if node.SendOnly != nil && *node.SendOnly {
// rpc := evmclient.NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), fmt.Sprintf("eth-sendonly-rpc-%d", i), int32(i), chainID, commontypes.Primary)
// sendonly := commonclient.NewSendOnlyNode[*big.Int, evmclient.RPCCLient](lggr, (url.URL)(*node.HTTPURL), *node.Name, chainID, rpc)
// sendonlys = append(sendonlys, sendonly)
// } else {
// rpc := evmclient.NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), fmt.Sprintf("eth-sendonly-rpc-%d", i), int32(i), chainID, commontypes.Primary)
// primaries = append(primaries, commonclient.NewNode[*big.Int, *evmtypes.Head, evmclient.RPCCLient](cfg, noNewHeadsThreshold, lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, *node.Order, rpc, "EVM"))
// }
// }
// return evmclient.NewChainClient(lggr, cfg.SelectionMode(), cfg.LeaseDuration(), noNewHeadsThreshold, primaries, sendonlys, chainID, chainType)
//}
Loading