Skip to content

Commit

Permalink
wip - need to re-impl setup
Browse files Browse the repository at this point in the history
  • Loading branch information
krehermann committed Jan 31, 2025
1 parent 8af9a90 commit b5fd079
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 310 deletions.
6 changes: 0 additions & 6 deletions deployment/keystone/changeset/compatiblity.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,6 @@ type DONToRegister = internal.DONToRegister
// NOP is a node operator profile, required to register a node with the capabilities registry
type NOP = internal.NOP

// ConfigureContractsRequest is a request to configure ALL the contracts
type ConfigureContractsRequest = internal.ConfigureContractsRequest

// ConfigureContractsResponse is a response to configure ALL the contracts
type ConfigureContractsResponse = internal.ConfigureContractsResponse

// DonCapabilities is a set of capabilities hosted by a set of node operators
// in is in a convenient form to handle the CLO representation of the nop data
type DonCapabilities = internal.DonCapabilities
Expand Down
63 changes: 1 addition & 62 deletions deployment/keystone/changeset/configure_contracts.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package changeset

import (
"context"
"fmt"

"github.com/smartcontractkit/chainlink-common/pkg/logger"

"github.com/smartcontractkit/chainlink/deployment"
kslib "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal"
)
Expand All @@ -19,63 +14,7 @@ type InitialContractsCfg struct {
}

func ConfigureInitialContractsChangeset(e deployment.Environment, cfg InitialContractsCfg) (deployment.ChangesetOutput, error) {
req := &kslib.ConfigureContractsRequest{
Env: &e,
RegistryChainSel: cfg.RegistryChainSel,
Dons: cfg.Dons,
OCR3Config: cfg.OCR3Config,
}
return ConfigureInitialContracts(e.Logger, req)
}

// Deprecated: Use ConfigureInitialContractsChangeset instead.
func ConfigureInitialContracts(lggr logger.Logger, req *kslib.ConfigureContractsRequest) (deployment.ChangesetOutput, error) {
if err := req.Validate(); err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to validate request: %w", err)
}

regAddrs, err := req.Env.ExistingAddresses.AddressesForChain(req.RegistryChainSel)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("no addresses found for chain %d: %w", req.RegistryChainSel, err)
}
foundRegistry := false
foundOCR3 := false
foundForwarder := false
for _, addr := range regAddrs {
switch addr.Type {
case kslib.CapabilitiesRegistry:
foundRegistry = true
case kslib.OCR3Capability:
foundOCR3 = true
case kslib.KeystoneForwarder:
foundForwarder = true
}
}
if !foundRegistry || !foundOCR3 || !foundForwarder {
return deployment.ChangesetOutput{}, fmt.Errorf("missing contracts on registry chain %d in addressbook for changeset %s registry exists %t, ocr3 exist %t, forwarder exists %t ", req.RegistryChainSel, "0003_deploy_forwarder",
foundRegistry, foundOCR3, foundForwarder)
}
// forwarder on all chains
foundForwarder = false
for _, c := range req.Env.Chains {
addrs, err2 := req.Env.ExistingAddresses.AddressesForChain(c.Selector)
if err2 != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("no addresses found for chain %d: %w", c.Selector, err2)
}
for _, addr := range addrs {
if addr.Type == kslib.KeystoneForwarder {
foundForwarder = true
break
}
}
if !foundForwarder {
return deployment.ChangesetOutput{}, fmt.Errorf("no forwarder found for chain %d", c.Selector)
}
}
return deployment.ChangesetOutput{}, nil

resp, err := kslib.ConfigureContracts(context.TODO(), lggr, *req)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to configure contracts: %w", err)
}
return *resp.Changeset, nil
}
217 changes: 0 additions & 217 deletions deployment/keystone/changeset/internal/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
chainsel "github.com/smartcontractkit/chain-selectors"
capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"golang.org/x/exp/maps"
"google.golang.org/protobuf/proto"

"github.com/smartcontractkit/chainlink/deployment"
Expand Down Expand Up @@ -63,72 +62,6 @@ type ConfigureContractsResponse struct {
DonInfos map[string]capabilities_registry.CapabilitiesRegistryDONInfo
}

// ConfigureContracts configures contracts them with the given DONS and their capabilities. It optionally deploys the contracts
// but best practice is to deploy them separately and pass the address book in the request
func ConfigureContracts(ctx context.Context, lggr logger.Logger, req ConfigureContractsRequest) (*ConfigureContractsResponse, error) {
if err := req.Validate(); err != nil {
return nil, fmt.Errorf("invalid request: %w", err)
}

cfgRegistryResp, err := ConfigureRegistry(ctx, lggr, req, req.Env.ExistingAddresses)
if err != nil {
return nil, fmt.Errorf("failed to configure registry: %w", err)
}

donInfos, err := DonInfos(req.Dons, req.Env.Offchain)
if err != nil {
return nil, fmt.Errorf("failed to get don infos: %w", err)
}

// now we have the capability registry set up we need to configure the forwarder contracts and the OCR3 contract
dons, err := joinInfoAndNodes(cfgRegistryResp.DonInfos, donInfos, req.RegistryChainSel)
if err != nil {
return nil, fmt.Errorf("failed to assimilate registry to Dons: %w", err)
}
// ignore response because we are not using mcms here and therefore no proposals are returned
_, err = ConfigureForwardContracts(req.Env, ConfigureForwarderContractsRequest{
Dons: dons,
})
if err != nil {
return nil, fmt.Errorf("failed to configure forwarder contracts: %w", err)
}

err = ConfigureOCR3Contract(req.Env, req.RegistryChainSel, dons, req.OCR3Config)
if err != nil {
return nil, fmt.Errorf("failed to configure OCR3 contract: %w", err)
}

return &ConfigureContractsResponse{
Changeset: &deployment.ChangesetOutput{}, // no new addresses, proposals etc
DonInfos: cfgRegistryResp.DonInfos,
}, nil
}

// DeployContracts deploys the all the keystone contracts on all chains and returns the address book in the changeset
func DeployContracts(e *deployment.Environment, chainSel uint64) (*deployment.ChangesetOutput, error) {
lggr := e.Logger
adbook := deployment.NewMemoryAddressBook()
// deploy contracts on all chains and track the registry and ocr3 contracts
for _, chain := range e.Chains {
lggr.Infow("deploying contracts", "chain", chain.Selector)
deployResp, err := deployContractsToChain(deployContractsRequest{
chain: chain,
isRegistryChain: chain.Selector == chainSel,
},
)
if err != nil {
return nil, fmt.Errorf("failed to deploy contracts: %w", err)
}
err = adbook.Merge(deployResp.AddressBook)
if err != nil {
return nil, fmt.Errorf("failed to merge address book: %w", err)
}
}
return &deployment.ChangesetOutput{
AddressBook: adbook,
}, nil
}

// DonInfo is DonCapabilities, but expanded to contain node information
type DonInfo struct {
Name string
Expand Down Expand Up @@ -186,156 +119,6 @@ func GetRegistryContract(e *deployment.Environment, registryChainSel uint64) (*c
return registry, registryChain, nil
}

// ConfigureRegistry configures the registry contract with the given DONS and their capabilities
// the address book is required to contain the addresses of the deployed registry contract
func ConfigureRegistry(ctx context.Context, lggr logger.Logger, req ConfigureContractsRequest, addrBook deployment.AddressBook) (*ConfigureContractsResponse, error) {
donInfos, err := DonInfos(req.Dons, req.Env.Offchain)
if err != nil {
return nil, fmt.Errorf("failed to get don infos: %w", err)
}

// all the subsequent calls to the registry are in terms of nodes
// compute the mapping of dons to their nodes for reuse in various registry calls
donToNodes, err := mapDonsToNodes(donInfos, true, req.RegistryChainSel)
if err != nil {
return nil, fmt.Errorf("failed to map dons to nodes: %w", err)
}

// TODO: we can remove this abstractions and refactor the functions that accept them to accept []DonInfos/DonCapabilities
// they are unnecessary indirection
donToCapabilities := mapDonsToCaps(donInfos)
nopsToNodeIDs, err := nopsToNodes(donInfos, req.Dons, req.RegistryChainSel)
if err != nil {
return nil, fmt.Errorf("failed to map nops to nodes: %w", err)
}

// register capabilities
capabilitiesResp, err := RegisterCapabilities(lggr, RegisterCapabilitiesRequest{
Env: req.Env,
RegistryChainSelector: req.RegistryChainSel,
DonToCapabilities: donToCapabilities,
})
if err != nil {
return nil, fmt.Errorf("failed to register capabilities: %w", err)
}
lggr.Infow("registered capabilities", "capabilities", capabilitiesResp.DonToCapabilities)

// register node operators
nopsList := maps.Keys(nopsToNodeIDs)
nopsResp, err := RegisterNOPS(ctx, lggr, RegisterNOPSRequest{
Env: req.Env,
RegistryChainSelector: req.RegistryChainSel,
Nops: nopsList,
})
if err != nil {
return nil, fmt.Errorf("failed to register node operators: %w", err)
}
lggr.Infow("registered node operators", "nops", nopsResp.Nops)

// register nodes
nodesResp, err := RegisterNodes(lggr, &RegisterNodesRequest{
Env: req.Env,
RegistryChainSelector: req.RegistryChainSel,
NopToNodeIDs: nopsToNodeIDs,
DonToNodes: donToNodes,
DonToCapabilities: capabilitiesResp.DonToCapabilities,
Nops: nopsResp.Nops,
})
if err != nil {
return nil, fmt.Errorf("failed to register nodes: %w", err)
}
lggr.Infow("registered nodes", "nodes", nodesResp.nodeIDToParams)

// TODO: annotate nodes with node_operator_id in JD?

donsToRegister := []DONToRegister{}
for _, don := range req.Dons {
nodes, ok := donToNodes[don.Name]
if !ok {
return nil, fmt.Errorf("nodes not found for don %s", don.Name)
}
f := don.F
if f == 0 {
// TODO: fallback to a default value for compatibility - change to error
f = uint8(len(nodes) / 3)
lggr.Warnw("F not set for don - falling back to default", "don", don.Name, "f", f)
}
donsToRegister = append(donsToRegister, DONToRegister{
Name: don.Name,
F: f,
Nodes: nodes,
})
}

nodeIdToP2PID := map[string][32]byte{}
for nodeID, params := range nodesResp.nodeIDToParams {
nodeIdToP2PID[nodeID] = params.P2pId
}
// register DONS
donsResp, err := RegisterDons(lggr, RegisterDonsRequest{
Env: req.Env,
RegistryChainSelector: req.RegistryChainSel,
NodeIDToP2PID: nodeIdToP2PID,
DonToCapabilities: capabilitiesResp.DonToCapabilities,
DonsToRegister: donsToRegister,
})
if err != nil {
return nil, fmt.Errorf("failed to register DONS: %w", err)
}
lggr.Infow("registered DONs", "dons", len(donsResp.DonInfos))

return &ConfigureContractsResponse{
Changeset: &deployment.ChangesetOutput{}, // no new addresses, proposals etc
DonInfos: donsResp.DonInfos,
}, nil
}

// Depreciated: use changeset.ConfigureOCR3Contract instead
// ocr3 contract on the registry chain for the wf dons
func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, dons []RegisteredDon, cfg *OracleConfig) error {
registryChain, ok := env.Chains[chainSel]
if !ok {
return fmt.Errorf("chain %d not found in environment", chainSel)
}

contractSetsResp, err := GetContractSets(env.Logger, &GetContractSetsRequest{
Chains: env.Chains,
AddressBook: env.ExistingAddresses,
})
if err != nil {
return fmt.Errorf("failed to get contract sets: %w", err)
}

for _, don := range dons {
if !don.Info.AcceptsWorkflows {
continue
}
// only on the registry chain
contracts, ok := contractSetsResp.ContractSets[chainSel]
if !ok {
return fmt.Errorf("failed to get contract set for chain %d", chainSel)
}

contract, err := contracts.GetOCR3Contract(nil)
if err != nil {
env.Logger.Errorf("failed to get OCR3 contract: %s", err)
return fmt.Errorf("failed to get OCR3 contract: %w", err)
}

_, err = configureOCR3contract(configureOCR3Request{
cfg: cfg,
chain: registryChain,
contract: contract,
nodes: don.Nodes,
ocrSecrets: env.OCRSecrets,
})
if err != nil {
return fmt.Errorf("failed to configure OCR3 contract for don %s: %w", don.Name, err)
}
}
return nil
}

type ConfigureOCR3Resp struct {
OCR2OracleConfig
Ops *timelock.BatchChainOperation
Expand Down
25 changes: 0 additions & 25 deletions deployment/keystone/changeset/internal/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,31 +318,6 @@ func (d RegisteredDon) Signers(chainFamily string) []common.Address {
return out
}

func joinInfoAndNodes(donInfos map[string]kcr.CapabilitiesRegistryDONInfo, dons []DonInfo, registryChainSel uint64) ([]RegisteredDon, error) {
// all maps should have the same keys
nodes, err := mapDonsToNodes(dons, true, registryChainSel)
if err != nil {
return nil, fmt.Errorf("failed to map dons to capabilities: %w", err)
}
if len(donInfos) != len(nodes) {
return nil, fmt.Errorf("mismatched lengths don infos %d, nodes %d", len(donInfos), len(nodes))
}
var out []RegisteredDon
for donName, info := range donInfos {
ocr2nodes, ok := nodes[donName]
if !ok {
return nil, fmt.Errorf("nodes not found for don %s", donName)
}
out = append(out, RegisteredDon{
Name: donName,
Info: info,
Nodes: ocr2nodes,
})
}

return out, nil
}

var emptyAddr = "0x0000000000000000000000000000000000000000"

// compute the admin address from the string. If the address is empty, replaces the 0s with fs
Expand Down

0 comments on commit b5fd079

Please sign in to comment.