Skip to content

Commit

Permalink
plumbing update nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
krehermann committed Dec 5, 2024
1 parent 1f44c26 commit 7e8268f
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 21 deletions.
25 changes: 14 additions & 11 deletions deployment/keystone/capability_management.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package keystone

import (
"bytes"
"fmt"

"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock"
Expand Down Expand Up @@ -54,26 +53,30 @@ func CapabilityID(c kcr.CapabilitiesRegistryCapability) string {
// contract reverts on adding the same capability twice and that would cause the whole transaction to revert
// which is very bad for us for mcms
func dedupCapabilities(registry *kcr.CapabilitiesRegistry, capabilities []kcr.CapabilitiesRegistryCapability) ([]kcr.CapabilitiesRegistryCapability, error) {
var deduped []kcr.CapabilitiesRegistryCapability
var out []kcr.CapabilitiesRegistryCapability
existing, err := registry.GetCapabilities(nil)
if err != nil {
return nil, fmt.Errorf("failed to call GetCapabilities: %w", err)
}
existingByID := make(map[[32]byte]struct{})
for _, cap := range existing {
existingByID[cap.HashedId] = struct{}{}
}
seen := make(map[string]struct{})
for _, candidate := range capabilities {
isNew := true
h, err := registry.GetHashedCapabilityId(nil, candidate.LabelledName, candidate.Version)
if err != nil {
return nil, fmt.Errorf("failed to call GetHashedCapabilityId: %w", err)
}
for _, cap := range existing {
if bytes.Equal(h[:], cap.HashedId[:]) {
isNew = false
break
}
// dedup input capabilities
if _, exists := seen[CapabilityID(candidate)]; exists {
continue
}
if isNew {
deduped = append(deduped, candidate)
seen[CapabilityID(candidate)] = struct{}{}
// dedup with respect to the registry
if _, exists := existingByID[h]; !exists {
out = append(out, candidate)
}
}
return deduped, nil
return out, nil
}
9 changes: 3 additions & 6 deletions deployment/keystone/changeset/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,13 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv {
}
var allDons = []keystone.DonCapabilities{wfDon, cwDon, assetDon}

_, err = kschangeset.ConfigureInitialContractsChangeset(env, kschangeset.InitialContractsCfg{
csOut, err := kschangeset.ConfigureInitialContractsChangeset(env, kschangeset.InitialContractsCfg{
RegistryChainSel: registryChainSel,
Dons: allDons,
OCR3Config: &ocr3Config,
})
require.NoError(t, err)
// TODO: KS-rm_deploy_opt
//require.Nil(t, csOut.AddressBook, "no new addresses should be created in configure initial contracts")
//require.NoError(t, env.ExistingAddresses.Merge(csOut.AddressBook))
require.Nil(t, csOut.AddressBook, "no new addresses should be created in configure initial contracts")

req := &keystone.GetContractSetsRequest{
Chains: env.Chains,
Expand Down Expand Up @@ -259,8 +257,7 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv {
validateDon(t, gotRegistry, assetNodes, assetDon)

if c.UseMCMS {
// TODO: mcms on all the chains, currently only on the registry chain. need to fix this for forwarders
// deploy, configure and xfer ownership of MCMS
// deploy, configure and xfer ownership of MCMS on all chains
timelockCfgs := make(map[uint64]commontypes.MCMSWithTimelockConfig)
for sel := range env.Chains {
t.Logf("Enabling MCMS on chain %d", sel)
Expand Down
1 change: 1 addition & 0 deletions deployment/keystone/changeset/internal/test/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type SetupTestRegistryRequest struct {
P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability
NopToNodes map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc
Dons []Don
// TODO maybe add support for MCMS at this level
}

type SetupTestRegistryResponse struct {
Expand Down
7 changes: 6 additions & 1 deletion deployment/keystone/changeset/internal/update_don.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"sort"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"
Expand All @@ -31,13 +32,16 @@ type UpdateDonRequest struct {

P2PIDs []p2pkey.PeerID // this is the unique identifier for the don
CapabilityConfigs []CapabilityConfig // if Config subfield is nil, a default config is used

UseMCMS bool
}

func (r *UpdateDonRequest) appendNodeCapabilitiesRequest() *AppendNodeCapabilitiesRequest {
out := &AppendNodeCapabilitiesRequest{
Chain: r.Chain,
Registry: r.Registry,
P2pToCapabilities: make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability),
UseMCMS: r.UseMCMS,
}
for _, p2pid := range r.P2PIDs {
if _, exists := out.P2pToCapabilities[p2pid]; !exists {
Expand All @@ -61,7 +65,8 @@ func (r *UpdateDonRequest) Validate() error {
}

type UpdateDonResponse struct {
DonInfo kcr.CapabilitiesRegistryDONInfo
DonInfo kcr.CapabilitiesRegistryDONInfo
Proposals []timelock.MCMSWithTimelockProposal
}

func UpdateDon(lggr logger.Logger, req *UpdateDonRequest) (*UpdateDonResponse, error) {
Expand Down
4 changes: 3 additions & 1 deletion deployment/keystone/changeset/internal/update_nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ type UpdateNodesRequest struct {
Registry *kcr.CapabilitiesRegistry

P2pToUpdates map[p2pkey.PeerID]NodeUpdate
UseMCMS bool

ContractSet kslib.ContractSet // contract set for the given chain
UseMCMS bool
}

func (req *UpdateNodesRequest) NodeParams() ([]kcr.CapabilitiesRegistryNodeParams, error) {
Expand Down
2 changes: 2 additions & 0 deletions deployment/keystone/changeset/update_node_capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type MutateNodeCapabilitiesRequest struct {
RegistryChainSel uint64

P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability
UseMCMS bool
}

func (req *MutateNodeCapabilitiesRequest) Validate() error {
Expand Down Expand Up @@ -95,6 +96,7 @@ func (req *MutateNodeCapabilitiesRequest) updateNodeCapabilitiesImplRequest(e de
Chain: registryChain,
Registry: registry,
P2pToCapabilities: req.P2pToCapabilities,
UseMCMS: req.UseMCMS,
}, nil
}

Expand Down
30 changes: 28 additions & 2 deletions deployment/keystone/changeset/update_nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,45 @@ import (
"fmt"

"github.com/smartcontractkit/chainlink/deployment"

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

var _ deployment.ChangeSet[*UpdateNodesRequest] = UpdateNodes

type UpdateNodesRequest = internal.UpdateNodesRequest
type UpdateNodesRequest struct {
RegistryChainSel uint64
P2pToUpdates map[p2pkey.PeerID]NodeUpdate

UseMCMS bool
}
type NodeUpdate = internal.NodeUpdate

// UpdateNodes updates the a set of nodes.
// This a complex action in practice that involves registering missing capabilities, adding the nodes, and updating
// the capabilities of the DON
func UpdateNodes(env deployment.Environment, req *UpdateNodesRequest) (deployment.ChangesetOutput, error) {
_, err := internal.UpdateNodes(env.Logger, req)
// extract the registry contract and chain from the environment
registryChain, ok := env.Chains[req.RegistryChainSel]
if !ok {
return deployment.ChangesetOutput{}, fmt.Errorf("registry chain selector %d does not exist in environment", req.RegistryChainSel)
}
contracts, err := kslib.GetContractSets(env.Logger, &kslib.GetContractSetsRequest{
Chains: env.Chains,
AddressBook: env.ExistingAddresses,
})
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to get contract sets: %w", err)
}

_, err = internal.UpdateNodes(env.Logger, &internal.UpdateNodesRequest{
Chain: registryChain,
Registry: contracts.ContractSets[req.RegistryChainSel].CapabilitiesRegistry,
P2pToUpdates: req.P2pToUpdates,
UseMCMS: req.UseMCMS,
})
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to update don: %w", err)
}
Expand Down

0 comments on commit 7e8268f

Please sign in to comment.