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

testing #15380

Draft
wants to merge 13 commits into
base: develop
Choose a base branch
from
52 changes: 47 additions & 5 deletions deployment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"math/big"
"sort"
"strings"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -21,6 +22,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 @@ -222,11 +224,14 @@ func (n Nodes) BootstrapLocators() []string {

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

func (n Node) OCRConfigForChainDetails(details chain_selectors.ChainDetails) (OCRConfig, bool) {
Expand Down Expand Up @@ -269,17 +274,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(nodeIDs[0], "p2p_")
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 @@ -294,7 +332,6 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) {
// Might make sense to change proto as peerID/multiAddr is 1-1 with nodeID?
peerID = MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId)
multiAddr = chainConfig.Ocr2Config.Multiaddr
adminAddr = chainConfig.AdminAddress
if chainConfig.Ocr2Config.IsBootstrap {
// NOTE: Assume same peerID for all chains.
// Might make sense to change proto as peerID is 1-1 with nodeID?
Expand Down Expand Up @@ -326,6 +363,8 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) {
return nil, err
}
case nodev1.ChainType_CHAIN_TYPE_EVM:
// NOTE: Assume same adminAddr for all chains. We always use EVM addr
adminAddr = chainConfig.AdminAddress
details, err = chain_selectors.GetChainDetailsByChainIDAndFamily(chainConfig.Chain.Id, chain_selectors.FamilyEVM)
if err != nil {
return nil, err
Expand All @@ -337,12 +376,15 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) {
selToOCRConfig[details] = ocrConfig
}
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
26 changes: 20 additions & 6 deletions deployment/environment/memory/job_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,28 +190,42 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode
if err != nil {
return nil, err
}
chainID, err := chainsel.ChainIdFromSelector(selector)
if err != nil {
return nil, err
}

if family == chainsel.FamilyEVM {
// already handled above
continue
}

var chainID string

var ocrtype chaintype.ChainType
switch family {
case chainsel.FamilyEVM:
ocrtype = chaintype.EVM
cid, err := chainsel.ChainIdFromSelector(selector)
if err != nil {
return nil, err
}
chainID = strconv.Itoa(int(cid))
case chainsel.FamilySolana:
ocrtype = chaintype.Solana
cid, err := chainsel.SolanaChainIdFromSelector(selector)
if err != nil {
return nil, err
}
chainID = cid
case chainsel.FamilyStarknet:
ocrtype = chaintype.StarkNet
// TODO: support cid
case chainsel.FamilyCosmos:
ocrtype = chaintype.Cosmos
// TODO: support cid
case chainsel.FamilyAptos:
ocrtype = chaintype.Aptos
cid, err := chainsel.AptosChainIdFromSelector(selector)
if err != nil {
return nil, err
}
chainID = strconv.Itoa(int(cid))
default:
panic(fmt.Sprintf("Unsupported chain family %v", family))
}
Expand Down Expand Up @@ -244,7 +258,7 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode

chainConfigs = append(chainConfigs, &nodev1.ChainConfig{
Chain: &nodev1.Chain{
Id: strconv.Itoa(int(chainID)),
Id: chainID,
Type: ctype,
},
AccountAddress: "", // TODO: support AccountAddress
Expand Down
4 changes: 4 additions & 0 deletions deployment/environment/memory/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ func NewNode(
) *Node {
evmchains := make(map[uint64]EVMChain)
for _, chain := range chains {
// we're only mapping evm chains here
if family, err := chainsel.GetSelectorFamily(chain.Selector); err != nil || family != chainsel.FamilyEVM {
continue
}
evmChainID, err := chainsel.ChainIdFromSelector(chain.Selector)
if err != nil {
t.Fatal(err)
Expand Down
90 changes: 48 additions & 42 deletions deployment/keystone/changeset/internal/update_don_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ package internal_test

import (
"bytes"
"encoding/hex"
"fmt"
"math/big"
"sort"
"strconv"
"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 +24,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 +103,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 +175,36 @@ 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,
},
},
registryChainID, err := chainsel.ChainIdFromSelector(registryChain.Selector)
if err != nil {
panic(err)
}
registryChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(strconv.Itoa(int(registryChainID)), chainsel.FamilyEVM)
if err != nil {
panic(err)
}

signingAddr, err := hex.DecodeString(cfg.signingAddr)
require.NoError(t, err)

var pubkey [32]byte
if _, err := hex.Decode(pubkey[:], []byte(cfg.pubKey)); err != nil {
panic(fmt.Sprintf("failed to decode pubkey %s: %v", pubkey, err))
}

return deployment.Node{
NodeID: cfg.id,
PeerID: cfg.p2p.PeerID(),
CSAKey: cfg.pubKey,
AdminAddr: cfg.admin.String(),
SelToOCRConfig: map[chainsel.ChainDetails]deployment.OCRConfig{
registryChainDetails: {
OnchainPublicKey: signingAddr,
PeerID: cfg.p2p.PeerID(),
ConfigEncryptionPublicKey: pubkey,
},
},
}
Expand All @@ -214,10 +228,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 +245,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 +274,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 +296,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 All @@ -299,11 +313,3 @@ func testDon(t *testing.T, don kslib.DonInfo) kstest.Don {
CapabilityConfigs: capabilityConfigs,
}
}

func newP2PSignerEnc(signer [32]byte, p2pkey p2pkey.PeerID, encryptionPublicKey [32]byte) *internal.P2PSignerEnc {
return &internal.P2PSignerEnc{
Signer: signer,
P2PKey: p2pkey,
EncryptionPublicKey: encryptionPublicKey,
}
}
Loading
Loading