Skip to content

Commit

Permalink
Replace NodesFromJD with NodeInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
archseer committed Nov 15, 2024
1 parent 2bca70c commit dce776a
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 681 deletions.
54 changes: 46 additions & 8 deletions deployment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"math/big"
"sort"
"strconv"
"strings"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -22,6 +23,7 @@ import (
csav1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/csa"
jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job"
nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node"
"github.com/smartcontractkit/chainlink-protos/job-distributor/v1/shared/ptypes"

"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"
)
Expand Down Expand Up @@ -215,11 +217,14 @@ func (n Nodes) BootstrapLocators() []string {

type Node struct {
NodeID string
Name string
CSAKey string
SelToOCRConfig map[uint64]OCRConfig
PeerID p2pkey.PeerID
IsBootstrap bool
MultiAddr string
AdminAddr string
Labels []*ptypes.Label
}

func (n Node) FirstOCRKeybundle() OCRConfig {
Expand All @@ -238,17 +243,50 @@ func MustPeerIDFromString(s string) p2pkey.PeerID {
}

type NodeChainConfigsLister interface {
ListNodes(ctx context.Context, in *nodev1.ListNodesRequest, opts ...grpc.CallOption) (*nodev1.ListNodesResponse, error)
ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*nodev1.ListNodeChainConfigsResponse, error)
}

// Gathers all the node info through JD required to be able to set
// OCR config for example.
// OCR config for example. nodeIDs can be JD IDs or PeerIDs
func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) {
if len(nodeIDs) == 0 {
return nil, nil
}
// if nodeIDs starts with `p2p_` lookup by p2p_id instead
filterByPeerIDs := strings.HasPrefix("p2p_", nodeIDs[0])
var filter *nodev1.ListNodesRequest_Filter
if filterByPeerIDs {
selector := strings.Join(nodeIDs, ",")
filter = &nodev1.ListNodesRequest_Filter{
Enabled: 1,
Selectors: []*ptypes.Selector{
{
Key: "p2p_id",
Op: ptypes.SelectorOp_IN,
Value: &selector,
},
},
}
} else {
filter = &nodev1.ListNodesRequest_Filter{
Enabled: 1,
Ids: nodeIDs,
}

}
nodesFromJD, err := oc.ListNodes(context.Background(), &nodev1.ListNodesRequest{
Filter: filter,
})
if err != nil {
return nil, fmt.Errorf("failed to list nodes: %w", err)
}

var nodes []Node
for _, nodeID := range nodeIDs {
for _, node := range nodesFromJD.GetNodes() {
// TODO: Filter should accept multiple nodes
nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{
NodeIds: []string{nodeID},
NodeIds: []string{node.Id},
}})
if err != nil {
return nil, err
Expand All @@ -259,10 +297,6 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) {
var multiAddr string
var adminAddr string
for _, chainConfig := range nodeChainConfigs.ChainConfigs {
if chainConfig.Chain.Type == nodev1.ChainType_CHAIN_TYPE_SOLANA {
// Note supported for CCIP yet.
continue
}
// NOTE: Assume same peerID/multiAddr for all chains.
// Might make sense to change proto as peerID/multiAddr is 1-1 with nodeID?
peerID = MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId)
Expand All @@ -278,6 +312,7 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) {
if err != nil {
return nil, err
}
// TODO: this is evm specific, make it work with aptos
sel, err := chain_selectors.SelectorFromChainId(uint64(evmChainID))
if err != nil {
return nil, err
Expand All @@ -300,12 +335,15 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) {
}
}
nodes = append(nodes, Node{
NodeID: nodeID,
NodeID: node.Id,
Name: node.Name,
CSAKey: node.PublicKey,
SelToOCRConfig: selToOCRConfig,
IsBootstrap: bootstrap,
PeerID: peerID,
MultiAddr: multiAddr,
AdminAddr: adminAddr,
Labels: node.Labels,
})
}

Expand Down
64 changes: 30 additions & 34 deletions deployment/keystone/changeset/internal/update_don_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package internal_test

import (
"bytes"
"encoding/hex"
"math/big"
"sort"
"testing"

"github.com/ethereum/go-ethereum/common"
chainsel "github.com/smartcontractkit/chain-selectors"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node"
"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/keystone"
kslib "github.com/smartcontractkit/chainlink/deployment/keystone"
Expand All @@ -22,9 +22,12 @@ import (
"github.com/stretchr/testify/require"
)

var (
registryChain = chainsel.TEST_90000001
)

func TestUpdateDon(t *testing.T) {
var (
registryChain = chainsel.TEST_90000001
// nodes
p2p_1 = p2pkey.MustNewV2XXXTestingOnly(big.NewInt(100))
pubKey_1 = "11114981a6119ca3f932cdb8c402d71a72d672adae7849f581ecff8b8e1098e7" // valid csa key
Expand Down Expand Up @@ -98,14 +101,14 @@ func TestUpdateDon(t *testing.T) {
dons: []kslib.DonInfo{
{
Name: "don 1",
Nodes: []keystone.Node{node_1, node_2, node_3, node_4},
Nodes: []deployment.Node{node_1, node_2, node_3, node_4},
Capabilities: []kcr.CapabilitiesRegistryCapability{cap_A},
},
},
nops: []keystone.NOP{
{
Name: "nop 1",
Nodes: []string{node_1.ID, node_2.ID, node_3.ID, node_4.ID},
Nodes: []string{node_1.NodeID, node_2.NodeID, node_3.NodeID, node_4.NodeID},
},
},
}
Expand Down Expand Up @@ -170,27 +173,20 @@ type minimalNodeCfg struct {
admin common.Address
}

func newNode(t *testing.T, cfg minimalNodeCfg) keystone.Node {
func newNode(t *testing.T, cfg minimalNodeCfg) deployment.Node {
t.Helper()

return keystone.Node{
ID: cfg.id,
PublicKey: &cfg.pubKey,
ChainConfigs: []*nodev1.ChainConfig{
{
Chain: &nodev1.Chain{
Id: "test chain",
Type: nodev1.ChainType_CHAIN_TYPE_EVM,
},
AdminAddress: cfg.admin.String(),
Ocr2Config: &nodev1.OCR2Config{
P2PKeyBundle: &nodev1.OCR2Config_P2PKeyBundle{
PeerId: cfg.p2p.PeerID().String(),
},
OcrKeyBundle: &nodev1.OCR2Config_OCRKeyBundle{
OnchainSigningAddress: cfg.signingAddr,
},
},
signingAddr, err := hex.DecodeString(cfg.signingAddr)
require.NoError(t, err)

return deployment.Node{
NodeID: cfg.id,
CSAKey: cfg.pubKey,
AdminAddr: cfg.admin.String(),
SelToOCRConfig: map[uint64]deployment.OCRConfig{
registryChain.Selector: {
OnchainPublicKey: signingAddr,
PeerID: cfg.p2p.PeerID(),
},
},
}
Expand All @@ -214,10 +210,10 @@ func setupUpdateDonTest(t *testing.T, lggr logger.Logger, cfg setupUpdateDonTest

func newSetupTestRegistryRequest(t *testing.T, dons []kslib.DonInfo, nops []keystone.NOP) *kstest.SetupTestRegistryRequest {
t.Helper()
nodes := make(map[string]keystone.Node)
nodes := make(map[string]deployment.Node)
for _, don := range dons {
for _, node := range don.Nodes {
nodes[node.ID] = node
nodes[node.NodeID] = node
}
}
nopsToNodes := makeNopToNodes(t, nops, nodes)
Expand All @@ -231,23 +227,23 @@ func newSetupTestRegistryRequest(t *testing.T, dons []kslib.DonInfo, nops []keys
return req
}

func makeNopToNodes(t *testing.T, nops []keystone.NOP, nodes map[string]keystone.Node) map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc {
func makeNopToNodes(t *testing.T, nops []keystone.NOP, nodes map[string]deployment.Node) map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc {
nopToNodes := make(map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc)

for _, nop := range nops {
// all chain configs are the same wrt admin address & node keys
// so we can just use the first one
crnop := kcr.CapabilitiesRegistryNodeOperator{
Name: nop.Name,
Admin: common.HexToAddress(nodes[nop.Nodes[0]].ChainConfigs[0].AdminAddress),
Admin: common.HexToAddress(nodes[nop.Nodes[0]].AdminAddr),
}
var signers []*internal.P2PSignerEnc
for _, nodeID := range nop.Nodes {
node := nodes[nodeID]
require.NotNil(t, node.PublicKey, "public key is nil %s", node.ID)
require.NotNil(t, node.CSAKey, "public key is nil %s", node.NodeID)
// all chain configs are the same wrt admin address & node keys
p, err := kscs.NewP2PSignerEncFromJD(node.ChainConfigs[0], *node.PublicKey)
require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.ID)
p, err := kscs.NewP2PSignerEnc(&node, registryChain.Selector)
require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.NodeID)
signers = append(signers, p)
}
nopToNodes[crnop] = signers
Expand All @@ -260,8 +256,8 @@ func makeP2PToCapabilities(t *testing.T, dons []kslib.DonInfo) map[p2pkey.PeerID
for _, don := range dons {
for _, node := range don.Nodes {
for _, cap := range don.Capabilities {
p, err := kscs.NewP2PSignerEncFromJD(node.ChainConfigs[0], *node.PublicKey)
require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.ID)
p, err := kscs.NewP2PSignerEnc(&node, registryChain.Selector)
require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.NodeID)
p2pToCapabilities[p.P2PKey] = append(p2pToCapabilities[p.P2PKey], cap)
}
}
Expand All @@ -282,8 +278,8 @@ func testDon(t *testing.T, don kslib.DonInfo) kstest.Don {
for _, node := range don.Nodes {
// all chain configs are the same wrt admin address & node keys
// so we can just use the first one
p, err := kscs.NewP2PSignerEncFromJD(node.ChainConfigs[0], *node.PublicKey)
require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.ID)
p, err := kscs.NewP2PSignerEnc(&node, registryChain.Selector)
require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.NodeID)
p2pids = append(p2pids, p.P2PKey)
}

Expand Down
43 changes: 0 additions & 43 deletions deployment/keystone/changeset/types.go

This file was deleted.

3 changes: 1 addition & 2 deletions deployment/keystone/changeset/update_node_capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
chainsel "github.com/smartcontractkit/chain-selectors"

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/keystone"
kslib "github.com/smartcontractkit/chainlink/deployment/keystone"
"github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal"

Expand All @@ -19,7 +18,7 @@ var _ deployment.ChangeSet[*MutateNodeCapabilitiesRequest] = UpdateNodeCapabilit

type P2PSignerEnc = internal.P2PSignerEnc

func NewP2PSignerEnc(n *keystone.Node, registryChainSel uint64) (*P2PSignerEnc, error) {
func NewP2PSignerEnc(n *deployment.Node, registryChainSel uint64) (*P2PSignerEnc, error) {
p2p, signer, enc, err := kslib.ExtractKeys(n, registryChainSel)
if err != nil {
return nil, fmt.Errorf("failed to extract keys: %w", err)
Expand Down
Loading

0 comments on commit dce776a

Please sign in to comment.