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

resurrect update don changeset #15112

Merged
merged 6 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions deployment/environment/clo/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package clo

import (
jd "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node"
"github.com/smartcontractkit/chainlink/deployment/environment/clo/models"
)

// NewChainConfig creates a new JobDistributor ChainConfig from a clo model NodeChainConfig
func NewChainConfig(chain *models.NodeChainConfig) *jd.ChainConfig {
return &jd.ChainConfig{
Chain: &jd.Chain{
Id: chain.Network.ChainID,
Type: jd.ChainType_CHAIN_TYPE_EVM, // TODO: support other chain types
},

AccountAddress: chain.AccountAddress,
AdminAddress: chain.AdminAddress,
Ocr2Config: &jd.OCR2Config{
Enabled: chain.Ocr2Config.Enabled,
P2PKeyBundle: &jd.OCR2Config_P2PKeyBundle{
PeerId: chain.Ocr2Config.P2pKeyBundle.PeerID,
PublicKey: chain.Ocr2Config.P2pKeyBundle.PublicKey,
},
OcrKeyBundle: &jd.OCR2Config_OCRKeyBundle{
BundleId: chain.Ocr2Config.OcrKeyBundle.BundleID,
OnchainSigningAddress: chain.Ocr2Config.OcrKeyBundle.OnchainSigningAddress,
OffchainPublicKey: chain.Ocr2Config.OcrKeyBundle.OffchainPublicKey,
ConfigPublicKey: chain.Ocr2Config.OcrKeyBundle.ConfigPublicKey,
},
},
}
}
1 change: 0 additions & 1 deletion deployment/keystone/changeset/append_node_capbilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,5 @@ func (req *AppendNodeCapabilitiesRequest) convert(e deployment.Environment) (*in
Chain: registryChain,
Registry: registry,
P2pToCapabilities: req.P2pToCapabilities,
NopToNodes: req.NopToNodes,
}, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,12 @@ type AppendNodeCapabilitiesRequest struct {
Registry *kcr.CapabilitiesRegistry

P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability
NopToNodes map[kcr.CapabilitiesRegistryNodeOperator][]*P2PSignerEnc
}

func (req *AppendNodeCapabilitiesRequest) Validate() error {
if len(req.P2pToCapabilities) == 0 {
return fmt.Errorf("p2pToCapabilities is empty")
}
if len(req.NopToNodes) == 0 {
return fmt.Errorf("nopToNodes is empty")
}
if req.Registry == nil {
return fmt.Errorf("registry is nil")
}
Expand Down Expand Up @@ -59,7 +55,6 @@ func AppendNodeCapabilitiesImpl(lggr logger.Logger, req *AppendNodeCapabilitiesR
Chain: req.Chain,
Registry: req.Registry,
P2pToCapabilities: capsByPeer,
NopToNodes: req.NopToNodes,
}
resp, err := UpdateNodes(lggr, updateNodesReq)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ func TestAppendNodeCapabilities(t *testing.T) {
},
},
},
NopToNodes: nopToNodes,
},
},
want: deployment.ChangesetOutput{},
Expand All @@ -93,7 +92,6 @@ func TestAppendNodeCapabilities(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// chagen the name and args to be mor egeneral
setupResp := kstest.SetupTestRegistry(t, lggr, tt.args.initialState)

tt.args.req.Registry = setupResp.Registry
Expand Down
116 changes: 101 additions & 15 deletions deployment/keystone/changeset/internal/test/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,30 @@ import (

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"

capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/values"
"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/environment/memory"

kslib "github.com/smartcontractkit/chainlink/deployment/keystone"
internal "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"
)

type Don struct {
Name string
P2PIDs []p2pkey.PeerID
CapabilityConfigs []internal.CapabilityConfig
}
type SetupTestRegistryRequest struct {
P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability
NopToNodes map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc
DonToNodes map[string][]*internal.P2PSignerEnc
Dons []Don
}

type SetupTestRegistryResponse struct {
Expand Down Expand Up @@ -59,21 +68,32 @@ func SetupTestRegistry(t *testing.T, lggr logger.Logger, req *SetupTestRegistryR
}
require.Len(t, registeredCapabilities, len(expectedDeduped))

// add the nodes with the phony capabilities. cannot register a node without a capability and capability must exist
// to do this make an initial phony request and extract the node params
initialp2pToCapabilities := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability)
// make the nodes and register node
var nodeParams []kcr.CapabilitiesRegistryNodeParams
initialp2pToCapabilities := make(map[p2pkey.PeerID][][32]byte)
for p2pID := range req.P2pToCapabilities {
initialp2pToCapabilities[p2pID] = vanillaCapabilities(registeredCapabilities)
initialp2pToCapabilities[p2pID] = mustCapabilityIds(t, registry, registeredCapabilities)
}
phonyRequest := &internal.UpdateNodesRequest{
Chain: chain,
Registry: registry,
P2pToCapabilities: req.P2pToCapabilities,
NopToNodes: req.NopToNodes,
// create node with initial capabilities assigned to nop
for i, nop := range nops {
if _, exists := req.NopToNodes[nop]; !exists {
require.Fail(t, "missing nopToNodes for %s", nop.Name)
}
for _, p2pSignerEnc := range req.NopToNodes[nop] {
nodeParams = append(nodeParams, kcr.CapabilitiesRegistryNodeParams{
Signer: p2pSignerEnc.Signer,
P2pId: p2pSignerEnc.P2PKey,
EncryptionPublicKey: p2pSignerEnc.EncryptionPublicKey,
HashedCapabilityIds: initialp2pToCapabilities[p2pSignerEnc.P2PKey],
NodeOperatorId: uint32(i + 1), // nopid in contract is 1-indexed
})
}
}
nodeParams, err := phonyRequest.NodeParams()
require.NoError(t, err)
addNodes(t, lggr, chain, registry, nodeParams)

// add the Dons
addDons(t, lggr, chain, registry, capCache, req.Dons)

return &SetupTestRegistryResponse{
Registry: registry,
Chain: chain,
Expand Down Expand Up @@ -108,6 +128,50 @@ func addNodes(t *testing.T, lggr logger.Logger, chain deployment.Chain, registry
require.NoError(t, err)
}

func addDons(t *testing.T, lggr logger.Logger, chain deployment.Chain, registry *kcr.CapabilitiesRegistry, capCache *CapabilityCache, dons []Don) {
for _, don := range dons {
acceptsWorkflows := false
// lookup the capabilities
var capConfigs []kcr.CapabilitiesRegistryCapabilityConfiguration
for _, ccfg := range don.CapabilityConfigs {
var cc = kcr.CapabilitiesRegistryCapabilityConfiguration{
CapabilityId: [32]byte{},
Config: ccfg.Config,
}
if cc.Config == nil {
cc.Config = defaultCapConfig(t, ccfg.Capability)
}
var exists bool
//var cc kcr.CapabilitiesRegistryCapabilityConfiguration{}
cc.CapabilityId, exists = capCache.Get(ccfg.Capability)
require.True(t, exists, "capability not found in cache %v", ccfg.Capability)
capConfigs = append(capConfigs, cc)
if ccfg.Capability.CapabilityType == 2 { // ocr3 capabilities
acceptsWorkflows = true
}
}
// add the don
isPublic := true
f := len(don.P2PIDs)/3 + 1
tx, err := registry.AddDON(chain.DeployerKey, internal.PeerIDsToBytes(don.P2PIDs), capConfigs, isPublic, acceptsWorkflows, uint8(f))
if err != nil {
err2 := kslib.DecodeErr(kcr.CapabilitiesRegistryABI, err)
require.Fail(t, fmt.Sprintf("failed to call AddDON: %s: %s", err, err2))
}
_, err = chain.Confirm(tx)
require.NoError(t, err)
}
}

func defaultCapConfig(t *testing.T, cap kcr.CapabilitiesRegistryCapability) []byte {
empty := &capabilitiespb.CapabilityConfig{
DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(),
}
emptyb, err := proto.Marshal(empty)
require.NoError(t, err)
return emptyb
}

// CapabilityCache tracks registered capabilities by name
type CapabilityCache struct {
t *testing.T
Expand All @@ -120,6 +184,10 @@ func NewCapabiltyCache(t *testing.T) *CapabilityCache {
nameToId: make(map[string][32]byte),
}
}
func (cc *CapabilityCache) Get(cap kcr.CapabilitiesRegistryCapability) ([32]byte, bool) {
id, exists := cc.nameToId[kslib.CapabilityID(cap)]
return id, exists
}

// AddCapabilities adds the capabilities to the registry and returns the registered capabilities
// if the capability is already registered, it will not be re-registered
Expand Down Expand Up @@ -182,10 +250,28 @@ func testChain(t *testing.T) deployment.Chain {
return chain
}

func vanillaCapabilities(rcs []kslib.RegisteredCapability) []kcr.CapabilitiesRegistryCapability {
out := make([]kcr.CapabilitiesRegistryCapability, len(rcs))
func capabilityIds(registry *capabilities_registry.CapabilitiesRegistry, rcs []kslib.RegisteredCapability) ([][32]byte, error) {
out := make([][32]byte, len(rcs))
for i := range rcs {
out[i] = rcs[i].CapabilitiesRegistryCapability
id, err := registry.GetHashedCapabilityId(&bind.CallOpts{}, rcs[i].LabelledName, rcs[i].Version)
if err != nil {
return nil, fmt.Errorf("failed to get capability id: %w", err)
}
out[i] = id
}
return out, nil
}

func mustCapabilityIds(t *testing.T, registry *capabilities_registry.CapabilitiesRegistry, rcs []kslib.RegisteredCapability) [][32]byte {
t.Helper()
out, err := capabilityIds(registry, rcs)
require.NoError(t, err)
return out
}

func MustCapabilityId(t *testing.T, registry *capabilities_registry.CapabilitiesRegistry, cap capabilities_registry.CapabilitiesRegistryCapability) [32]byte {
t.Helper()
id, err := registry.GetHashedCapabilityId(&bind.CallOpts{}, cap.LabelledName, cap.Version)
require.NoError(t, err)
return id
}
Loading
Loading