From 8107d685eb11afa59e2a98c7b6f50fc0f428e9fe Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Tue, 19 Nov 2024 12:31:12 -0400 Subject: [PATCH 1/9] Adds `Hydrate()` functionality to `CapabilityRegistryView` --- deployment/common/view/v1_0/capreg.go | 161 +++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) diff --git a/deployment/common/view/v1_0/capreg.go b/deployment/common/view/v1_0/capreg.go index 2ddd5a13463..ceb1217f57a 100644 --- a/deployment/common/view/v1_0/capreg.go +++ b/deployment/common/view/v1_0/capreg.go @@ -10,8 +10,10 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/view/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) @@ -140,6 +142,163 @@ func (v CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, er return out, nil } +type HydrateConfig struct { + lggr logger.Logger + ChainID uint64 +} + +func (v CapabilityRegistryView) Hydrate(env deployment.Environment, cfg HydrateConfig) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { + chain, ok := env.Chains[cfg.ChainID] + if !ok { + return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID) + } + deployedContract, err := deployment.DeployContract( + cfg.lggr, chain, env.ExistingAddresses, + func(chain deployment.Chain) deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { + crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( + chain.DeployerKey, + chain.Client, + ) + return deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ + Address: crAddr, Contract: cr, Tx: tx, Err: err2, + Tv: deployment.NewTypeAndVersion("CapabilitiesRegistry", deployment.Version1_0_0), + } + }, + ) + if err != nil { + return nil, fmt.Errorf("failed to deploy contract: %w", err) + } + + nodesParams, err := v.nodesToNodesParams() + if err != nil { + return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err) + } + tx, err := deployedContract.Contract.AddNodes(chain.DeployerKey, nodesParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add nodes: %w", err) + } + + capabilitiesParams := v.capabilitiesToCapabilitiesParams() + tx, err = deployedContract.Contract.AddCapabilities(chain.DeployerKey, capabilitiesParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add capabilities: %w", err) + } + + nopsParams := v.nopsToNopsParams() + for _, nop := range v.Nops { + nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ + Admin: nop.Admin, + Name: nop.Name, + }) + } + tx, err = deployedContract.Contract.AddNodeOperators(chain.DeployerKey, nopsParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add node operators: %w", err) + } + + for _, don := range v.Dons { + cfgs, err := v.capabilityConfigToCapabilityConfigParams(don) + if err != nil { + return nil, fmt.Errorf("failed to convert capability configurations to capability configuration params: %w", err) + } + var peerIds [][32]byte + for _, id := range don.NodeP2PIds { + peerIds = append(peerIds, id) + } + tx, err = deployedContract.Contract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add don: %w", err) + } + } + + return deployedContract, nil +} + +func (v CapabilityRegistryView) nodesToNodesParams() ([]capabilities_registry.CapabilitiesRegistryNodeParams, error) { + var nodesParams []capabilities_registry.CapabilitiesRegistryNodeParams + for _, node := range v.Nodes { + signer, err := hexTo32Bytes(node.Signer) + if err != nil { + return nil, err + } + encryptionPubKey, err := hexTo32Bytes(node.EncryptionPublicKey) + if err != nil { + return nil, err + } + capIDs := make([][32]byte, len(node.CapabilityIDs)) + for i, id := range node.CapabilityIDs { + cid, err := hexTo32Bytes(id) + if err != nil { + return nil, err + } + capIDs[i] = cid + } + nodesParams = append(nodesParams, capabilities_registry.CapabilitiesRegistryNodeParams{ + Signer: signer, + P2pId: node.P2pId, + EncryptionPublicKey: encryptionPubKey, + NodeOperatorId: node.NodeOperatorID, + HashedCapabilityIds: capIDs, + }) + } + + return nodesParams, nil +} + +func (v CapabilityRegistryView) capabilitiesToCapabilitiesParams() []capabilities_registry.CapabilitiesRegistryCapability { + var capabilitiesParams []capabilities_registry.CapabilitiesRegistryCapability + for _, capability := range v.Capabilities { + capabilitiesParams = append(capabilitiesParams, capabilities_registry.CapabilitiesRegistryCapability{ + LabelledName: capability.LabelledName, + Version: capability.Version, + CapabilityType: capability.CapabilityType, + ResponseType: capability.ResponseType, + ConfigurationContract: capability.ConfigurationContract, + }) + } + return capabilitiesParams +} + +func (v CapabilityRegistryView) nopsToNopsParams() []capabilities_registry.CapabilitiesRegistryNodeOperator { + var nopsParams []capabilities_registry.CapabilitiesRegistryNodeOperator + for _, nop := range v.Nops { + nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ + Admin: nop.Admin, + Name: nop.Name, + }) + } + return nopsParams +} + +func (v CapabilityRegistryView) capabilityConfigToCapabilityConfigParams(don DonView) ([]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration, error) { + var cfgs []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration + for _, cfg := range don.CapabilityConfigurations { + cid, err := hexTo32Bytes(cfg.ID) + if err != nil { + return nil, err + } + config, err := hex.DecodeString(cfg.Config) + if err != nil { + return nil, err + } + cfgs = append(cfgs, capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + CapabilityId: cid, + Config: config, + }) + } + return cfgs, nil +} + +func hexTo32Bytes(val string) ([32]byte, error) { + var out [32]byte + b, err := hex.DecodeString(val) + if err != nil { + return out, err + } + copy(out[:], b) + return out, nil +} + // CapabilityView is a serialization-friendly view of a capability in the capabilities registry. type CapabilityView struct { ID string `json:"id"` // hex 32 bytes @@ -272,7 +431,7 @@ func NewNodeView(n capabilities_registry.INodeInfoProviderNodeInfo) NodeView { ConfigCount: n.ConfigCount, WorkflowDONID: n.WorkflowDONId, Signer: hex.EncodeToString(n.Signer[:]), - P2pId: p2pkey.PeerID(n.P2pId), + P2pId: n.P2pId, EncryptionPublicKey: hex.EncodeToString(n.EncryptionPublicKey[:]), }, NodeOperatorID: n.NodeOperatorId, From 1e7b80e8da9a60f439f615a40ae8a26195ce2e6e Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Tue, 19 Nov 2024 13:02:30 -0400 Subject: [PATCH 2/9] Extracts hydration functionality into a `common` package --- .../common/changeset/capability_registry.go | 83 +++++++++++++++++++ deployment/common/view/v1_0/capreg.go | 82 +----------------- 2 files changed, 87 insertions(+), 78 deletions(-) create mode 100644 deployment/common/changeset/capability_registry.go diff --git a/deployment/common/changeset/capability_registry.go b/deployment/common/changeset/capability_registry.go new file mode 100644 index 00000000000..0397759b36e --- /dev/null +++ b/deployment/common/changeset/capability_registry.go @@ -0,0 +1,83 @@ +package changeset + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +type HydrateConfig struct { + lggr logger.Logger + ChainID uint64 +} + +// HydrateCapabilityRegistry deploys a new capabilities registry contract and hydrates it with the provided data. +func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Environment, cfg HydrateConfig) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { + chain, ok := env.Chains[cfg.ChainID] + if !ok { + return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID) + } + deployedContract, err := deployment.DeployContract( + cfg.lggr, chain, env.ExistingAddresses, + func(chain deployment.Chain) deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { + crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( + chain.DeployerKey, + chain.Client, + ) + return deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ + Address: crAddr, Contract: cr, Tx: tx, Err: err2, + Tv: deployment.NewTypeAndVersion("CapabilitiesRegistry", deployment.Version1_0_0), + } + }, + ) + if err != nil { + return nil, fmt.Errorf("failed to deploy contract: %w", err) + } + + nodesParams, err := v.NodesToNodesParams() + if err != nil { + return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err) + } + tx, err := deployedContract.Contract.AddNodes(chain.DeployerKey, nodesParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add nodes: %w", err) + } + + capabilitiesParams := v.CapabilitiesToCapabilitiesParams() + tx, err = deployedContract.Contract.AddCapabilities(chain.DeployerKey, capabilitiesParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add capabilities: %w", err) + } + + nopsParams := v.NopsToNopsParams() + for _, nop := range v.Nops { + nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ + Admin: nop.Admin, + Name: nop.Name, + }) + } + tx, err = deployedContract.Contract.AddNodeOperators(chain.DeployerKey, nopsParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add node operators: %w", err) + } + + for _, don := range v.Dons { + cfgs, err := v.CapabilityConfigToCapabilityConfigParams(don) + if err != nil { + return nil, fmt.Errorf("failed to convert capability configurations to capability configuration params: %w", err) + } + var peerIds [][32]byte + for _, id := range don.NodeP2PIds { + peerIds = append(peerIds, id) + } + tx, err = deployedContract.Contract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) + if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + return nil, fmt.Errorf("failed to add don: %w", err) + } + } + + return deployedContract, nil +} diff --git a/deployment/common/view/v1_0/capreg.go b/deployment/common/view/v1_0/capreg.go index ceb1217f57a..bc19f33048b 100644 --- a/deployment/common/view/v1_0/capreg.go +++ b/deployment/common/view/v1_0/capreg.go @@ -10,10 +10,8 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/view/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) @@ -142,79 +140,7 @@ func (v CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, er return out, nil } -type HydrateConfig struct { - lggr logger.Logger - ChainID uint64 -} - -func (v CapabilityRegistryView) Hydrate(env deployment.Environment, cfg HydrateConfig) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { - chain, ok := env.Chains[cfg.ChainID] - if !ok { - return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID) - } - deployedContract, err := deployment.DeployContract( - cfg.lggr, chain, env.ExistingAddresses, - func(chain deployment.Chain) deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { - crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( - chain.DeployerKey, - chain.Client, - ) - return deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ - Address: crAddr, Contract: cr, Tx: tx, Err: err2, - Tv: deployment.NewTypeAndVersion("CapabilitiesRegistry", deployment.Version1_0_0), - } - }, - ) - if err != nil { - return nil, fmt.Errorf("failed to deploy contract: %w", err) - } - - nodesParams, err := v.nodesToNodesParams() - if err != nil { - return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err) - } - tx, err := deployedContract.Contract.AddNodes(chain.DeployerKey, nodesParams) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { - return nil, fmt.Errorf("failed to add nodes: %w", err) - } - - capabilitiesParams := v.capabilitiesToCapabilitiesParams() - tx, err = deployedContract.Contract.AddCapabilities(chain.DeployerKey, capabilitiesParams) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { - return nil, fmt.Errorf("failed to add capabilities: %w", err) - } - - nopsParams := v.nopsToNopsParams() - for _, nop := range v.Nops { - nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ - Admin: nop.Admin, - Name: nop.Name, - }) - } - tx, err = deployedContract.Contract.AddNodeOperators(chain.DeployerKey, nopsParams) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { - return nil, fmt.Errorf("failed to add node operators: %w", err) - } - - for _, don := range v.Dons { - cfgs, err := v.capabilityConfigToCapabilityConfigParams(don) - if err != nil { - return nil, fmt.Errorf("failed to convert capability configurations to capability configuration params: %w", err) - } - var peerIds [][32]byte - for _, id := range don.NodeP2PIds { - peerIds = append(peerIds, id) - } - tx, err = deployedContract.Contract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { - return nil, fmt.Errorf("failed to add don: %w", err) - } - } - - return deployedContract, nil -} - -func (v CapabilityRegistryView) nodesToNodesParams() ([]capabilities_registry.CapabilitiesRegistryNodeParams, error) { +func (v CapabilityRegistryView) NodesToNodesParams() ([]capabilities_registry.CapabilitiesRegistryNodeParams, error) { var nodesParams []capabilities_registry.CapabilitiesRegistryNodeParams for _, node := range v.Nodes { signer, err := hexTo32Bytes(node.Signer) @@ -245,7 +171,7 @@ func (v CapabilityRegistryView) nodesToNodesParams() ([]capabilities_registry.Ca return nodesParams, nil } -func (v CapabilityRegistryView) capabilitiesToCapabilitiesParams() []capabilities_registry.CapabilitiesRegistryCapability { +func (v CapabilityRegistryView) CapabilitiesToCapabilitiesParams() []capabilities_registry.CapabilitiesRegistryCapability { var capabilitiesParams []capabilities_registry.CapabilitiesRegistryCapability for _, capability := range v.Capabilities { capabilitiesParams = append(capabilitiesParams, capabilities_registry.CapabilitiesRegistryCapability{ @@ -259,7 +185,7 @@ func (v CapabilityRegistryView) capabilitiesToCapabilitiesParams() []capabilitie return capabilitiesParams } -func (v CapabilityRegistryView) nopsToNopsParams() []capabilities_registry.CapabilitiesRegistryNodeOperator { +func (v CapabilityRegistryView) NopsToNopsParams() []capabilities_registry.CapabilitiesRegistryNodeOperator { var nopsParams []capabilities_registry.CapabilitiesRegistryNodeOperator for _, nop := range v.Nops { nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ @@ -270,7 +196,7 @@ func (v CapabilityRegistryView) nopsToNopsParams() []capabilities_registry.Capab return nopsParams } -func (v CapabilityRegistryView) capabilityConfigToCapabilityConfigParams(don DonView) ([]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration, error) { +func (v CapabilityRegistryView) CapabilityConfigToCapabilityConfigParams(don DonView) ([]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration, error) { var cfgs []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration for _, cfg := range don.CapabilityConfigurations { cid, err := hexTo32Bytes(cfg.ID) From 3d1351eea8cd0021354fd4e811c66b19437a4826 Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Wed, 20 Nov 2024 12:42:25 -0400 Subject: [PATCH 3/9] Add `UnmarshalJSON` functionality to `CapabilityRegistryView` --- .../common/changeset/capability_registry.go | 12 +++-- deployment/common/view/v1_0/capreg.go | 44 ++++++++++++++++--- deployment/common/view/v1_0/capreg_test.go | 3 +- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/deployment/common/changeset/capability_registry.go b/deployment/common/changeset/capability_registry.go index 0397759b36e..012b0df313e 100644 --- a/deployment/common/changeset/capability_registry.go +++ b/deployment/common/changeset/capability_registry.go @@ -3,25 +3,29 @@ package changeset import ( "fmt" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) type HydrateConfig struct { - lggr logger.Logger ChainID uint64 } // HydrateCapabilityRegistry deploys a new capabilities registry contract and hydrates it with the provided data. func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Environment, cfg HydrateConfig) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { - chain, ok := env.Chains[cfg.ChainID] + chainSelector, err := chainsel.SelectorFromChainId(cfg.ChainID) + if err != nil { + return nil, fmt.Errorf("failed to get chain selector from chain id: %w", err) + } + chain, ok := env.Chains[chainSelector] if !ok { return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID) } deployedContract, err := deployment.DeployContract( - cfg.lggr, chain, env.ExistingAddresses, + env.Logger, chain, env.ExistingAddresses, func(chain deployment.Chain) deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( chain.DeployerKey, diff --git a/deployment/common/view/v1_0/capreg.go b/deployment/common/view/v1_0/capreg.go index bc19f33048b..3274cc4e97f 100644 --- a/deployment/common/view/v1_0/capreg.go +++ b/deployment/common/view/v1_0/capreg.go @@ -26,7 +26,7 @@ type CapabilityRegistryView struct { // MarshalJSON marshals the CapabilityRegistryView to JSON. It includes the Capabilities, Nodes, Nops, and Dons // and a denormalized summary of the Dons with their associated Nodes and Capabilities, which is useful for a high-level view -func (v CapabilityRegistryView) MarshalJSON() ([]byte, error) { +func (v *CapabilityRegistryView) MarshalJSON() ([]byte, error) { // Alias to avoid recursive calls type Alias struct { types.ContractMetaData @@ -51,6 +51,36 @@ func (v CapabilityRegistryView) MarshalJSON() ([]byte, error) { return json.MarshalIndent(&a, "", " ") } +// UnmarshalJSON unmarshals the CapabilityRegistryView from JSON. Since the CapabilityRegistryView doesn't hold a DonCapabilities field, +// it is not unmarshaled. +func (v *CapabilityRegistryView) UnmarshalJSON(data []byte) error { + // Alias to avoid recursive calls + type Alias struct { + types.ContractMetaData + Capabilities []CapabilityView `json:"capabilities,omitempty"` + Nodes []NodeView `json:"nodes,omitempty"` + Nops []NopView `json:"nops,omitempty"` + Dons []DonView `json:"dons,omitempty"` + DonCapabilities []DonDenormalizedView `json:"don_capabilities_summary,omitempty"` + } + a := Alias{ + ContractMetaData: v.ContractMetaData, + Capabilities: v.Capabilities, + Nodes: v.Nodes, + Nops: v.Nops, + Dons: v.Dons, + } + if err := json.Unmarshal(data, &a); err != nil { + return err + } + v.ContractMetaData = a.ContractMetaData + v.Capabilities = a.Capabilities + v.Nodes = a.Nodes + v.Nops = a.Nops + v.Dons = a.Dons + return nil +} + // GenerateCapabilityRegistryView generates a CapRegView from a CapabilitiesRegistry contract. func GenerateCapabilityRegistryView(capReg *capabilities_registry.CapabilitiesRegistry) (CapabilityRegistryView, error) { tv, err := types.NewContractMetaData(capReg, capReg.Address()) @@ -112,7 +142,7 @@ type DonDenormalizedView struct { // Nodes and Capabilities. This is a useful form of the CapabilityRegistryView, but it is not definitive. // The full CapRegView should be used for the most accurate information as it can contain // Capabilities and Nodes the are not associated with any Don. -func (v CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, error) { +func (v *CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, error) { var out []DonDenormalizedView for _, don := range v.Dons { var nodes []NodeDenormalizedView @@ -140,7 +170,7 @@ func (v CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, er return out, nil } -func (v CapabilityRegistryView) NodesToNodesParams() ([]capabilities_registry.CapabilitiesRegistryNodeParams, error) { +func (v *CapabilityRegistryView) NodesToNodesParams() ([]capabilities_registry.CapabilitiesRegistryNodeParams, error) { var nodesParams []capabilities_registry.CapabilitiesRegistryNodeParams for _, node := range v.Nodes { signer, err := hexTo32Bytes(node.Signer) @@ -171,7 +201,7 @@ func (v CapabilityRegistryView) NodesToNodesParams() ([]capabilities_registry.Ca return nodesParams, nil } -func (v CapabilityRegistryView) CapabilitiesToCapabilitiesParams() []capabilities_registry.CapabilitiesRegistryCapability { +func (v *CapabilityRegistryView) CapabilitiesToCapabilitiesParams() []capabilities_registry.CapabilitiesRegistryCapability { var capabilitiesParams []capabilities_registry.CapabilitiesRegistryCapability for _, capability := range v.Capabilities { capabilitiesParams = append(capabilitiesParams, capabilities_registry.CapabilitiesRegistryCapability{ @@ -185,7 +215,7 @@ func (v CapabilityRegistryView) CapabilitiesToCapabilitiesParams() []capabilitie return capabilitiesParams } -func (v CapabilityRegistryView) NopsToNopsParams() []capabilities_registry.CapabilitiesRegistryNodeOperator { +func (v *CapabilityRegistryView) NopsToNopsParams() []capabilities_registry.CapabilitiesRegistryNodeOperator { var nopsParams []capabilities_registry.CapabilitiesRegistryNodeOperator for _, nop := range v.Nops { nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ @@ -196,7 +226,7 @@ func (v CapabilityRegistryView) NopsToNopsParams() []capabilities_registry.Capab return nopsParams } -func (v CapabilityRegistryView) CapabilityConfigToCapabilityConfigParams(don DonView) ([]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration, error) { +func (v *CapabilityRegistryView) CapabilityConfigToCapabilityConfigParams(don DonView) ([]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration, error) { var cfgs []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration for _, cfg := range don.CapabilityConfigurations { cid, err := hexTo32Bytes(cfg.ID) @@ -413,7 +443,7 @@ func NewNopView(nop capabilities_registry.CapabilitiesRegistryNodeOperator) NopV } } -func (v CapabilityRegistryView) nodeDenormalizedView(n NodeView) (NodeDenormalizedView, error) { +func (v *CapabilityRegistryView) nodeDenormalizedView(n NodeView) (NodeDenormalizedView, error) { nop, err := nodeNop(n, v.Nops) if err != nil { return NodeDenormalizedView{}, err diff --git a/deployment/common/view/v1_0/capreg_test.go b/deployment/common/view/v1_0/capreg_test.go index 8ba7b880364..2f58034a619 100644 --- a/deployment/common/view/v1_0/capreg_test.go +++ b/deployment/common/view/v1_0/capreg_test.go @@ -4,9 +4,10 @@ import ( "math/big" "testing" + "github.com/stretchr/testify/assert" + "github.com/smartcontractkit/chainlink/deployment/common/view/types" cr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/stretchr/testify/assert" ) func TestCapRegView_Denormalize(t *testing.T) { From a582991b175240e9fb5b8c6d225e54b74be9046f Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Wed, 20 Nov 2024 13:39:11 -0400 Subject: [PATCH 4/9] Adds test - WIP --- .../common/changeset/capability_registry.go | 35 +- .../changeset/capability_registry_test.go | 34 ++ .../testdata/capability_registry_view.json | 455 ++++++++++++++++++ 3 files changed, 507 insertions(+), 17 deletions(-) create mode 100644 deployment/common/changeset/capability_registry_test.go create mode 100644 deployment/common/changeset/testdata/capability_registry_view.json diff --git a/deployment/common/changeset/capability_registry.go b/deployment/common/changeset/capability_registry.go index 012b0df313e..9ae7ea6364c 100644 --- a/deployment/common/changeset/capability_registry.go +++ b/deployment/common/changeset/capability_registry.go @@ -7,6 +7,7 @@ import ( "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" + "github.com/smartcontractkit/chainlink/deployment/keystone" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) @@ -41,31 +42,31 @@ func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Env return nil, fmt.Errorf("failed to deploy contract: %w", err) } - nodesParams, err := v.NodesToNodesParams() - if err != nil { - return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err) + nopsParams := v.NopsToNopsParams() + for _, nop := range v.Nops { + nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ + Admin: nop.Admin, + Name: nop.Name, + }) } - tx, err := deployedContract.Contract.AddNodes(chain.DeployerKey, nodesParams) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { - return nil, fmt.Errorf("failed to add nodes: %w", err) + tx, err := deployedContract.Contract.AddNodeOperators(chain.DeployerKey, nopsParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { + return nil, fmt.Errorf("failed to add node operators: %w", err) } capabilitiesParams := v.CapabilitiesToCapabilitiesParams() tx, err = deployedContract.Contract.AddCapabilities(chain.DeployerKey, capabilitiesParams) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add capabilities: %w", err) } - nopsParams := v.NopsToNopsParams() - for _, nop := range v.Nops { - nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ - Admin: nop.Admin, - Name: nop.Name, - }) + nodesParams, err := v.NodesToNodesParams() + if err != nil { + return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err) } - tx, err = deployedContract.Contract.AddNodeOperators(chain.DeployerKey, nopsParams) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { - return nil, fmt.Errorf("failed to add node operators: %w", err) + tx, err = deployedContract.Contract.AddNodes(chain.DeployerKey, nodesParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { + return nil, fmt.Errorf("failed to add nodes: %w", err) } for _, don := range v.Dons { @@ -78,7 +79,7 @@ func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Env peerIds = append(peerIds, id) } tx, err = deployedContract.Contract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) - if _, err = deployment.ConfirmIfNoError(chain, tx, err); err != nil { + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add don: %w", err) } } diff --git a/deployment/common/changeset/capability_registry_test.go b/deployment/common/changeset/capability_registry_test.go new file mode 100644 index 00000000000..e6f8050b64a --- /dev/null +++ b/deployment/common/changeset/capability_registry_test.go @@ -0,0 +1,34 @@ +package changeset + +import ( + "encoding/json" + "os" + "testing" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestHydrateCapabilityRegistry(t *testing.T) { + b, err := os.ReadFile("testdata/capability_registry_view.json") + require.NoError(t, err) + require.NotEmpty(t, b) + var capabilityRegistryView v1_0.CapabilityRegistryView + require.NoError(t, json.Unmarshal(b, &capabilityRegistryView)) + + chainID := chainsel.TEST_90000001.EvmChainID + 1 + cfg := HydrateConfig{ChainID: chainID} + env := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Bootstraps: 1, + Chains: 2, + Nodes: 4, + }) + hydrated, err := HydrateCapabilityRegistry(capabilityRegistryView, env, cfg) + require.NoError(t, err) + require.NotNil(t, hydrated) +} diff --git a/deployment/common/changeset/testdata/capability_registry_view.json b/deployment/common/changeset/testdata/capability_registry_view.json new file mode 100644 index 00000000000..fef22a7b4dc --- /dev/null +++ b/deployment/common/changeset/testdata/capability_registry_view.json @@ -0,0 +1,455 @@ +{ + "typeAndVersion": "CapabilitiesRegistry 1.1.0", + "address": "0x65a097a74769fe1c415993f45d9b56ffffb65807", + "owner": "0x61050aeba13a5f7ba0b06cac4e1aee625fe4a640", + "capabilities": [ + { + "id": "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483", + "labelled_name": "write_ethereum-testnet-sepolia", + "version": "1.0.0", + "capability_type": 3, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + }, + { + "id": "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a", + "labelled_name": "streams-trigger", + "version": "1.0.0", + "capability_type": 0, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + }, + { + "id": "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b", + "labelled_name": "offchain_reporting", + "version": "1.0.0", + "capability_type": 2, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ], + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "f36818345fb18549bd24305c79f2f28d80d25710000000000000000000000000", + "p2p_id": "p2p_12D3KooWGVWpMrCZDotqSYWj8xqb1i5kNecpoarczpQoSAHdqwj8", + "encryption_public_key": "986707930499b85ab01705aa8d5cd99dca40926db3fa1728e6b58d25fddfe46b", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "a0e11229b4b5d40d299f7f4b3348a1b16f5f3dd3000000000000000000000000", + "p2p_id": "p2p_12D3KooWPsGKEe34m9X8qiWVpa6VEcjdvhbygJRLKXdVEr3r96PH", + "encryption_public_key": "10c77049880fe0924f463763789985a0f76e09f82fc6f39943684b2dd05b98bf", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "3f871cd7c34e50320934b6ba9b90b249363fd378000000000000000000000000", + "p2p_id": "p2p_12D3KooWLjKKWLhYkr68PH9FaZZR93WbJuohWWcTfA9JeY1UPoJa", + "encryption_public_key": "5cf5abd0349b27cde43ad1a55aa3b02a5518aa6eed365bd65ca5e0e2cbfdaa5a", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "d7a432ce8f23c410302e7577de9973ccbca29576000000000000000000000000", + "p2p_id": "p2p_12D3KooWRG3rsPdQyWCPsQukUF5JqFLdPqVVXvEfG2PAPBbqdRXp", + "encryption_public_key": "c10cead34374ba20704a05ca0369018b41778a0297adb85554cdd6e5955bf4b6", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "f1d2b3d13c46b0c1ded96534aabd6bae61934e3f000000000000000000000000", + "p2p_id": "p2p_12D3KooWD1uj8Y9Phdr1yScfbBy1Q9ebedMVBjMUBLW4m4XnEzGF", + "encryption_public_key": "5fc3dae131da5b0ac5474ad029e3a6c547e17249a6266427d5eea1f529b6488b", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "afabd7685010d619ee6614e732b15e898c293426000000000000000000000000", + "p2p_id": "p2p_12D3KooWE8ymezL2wxXcZdhznnBkVNcBRbtxVfNx1vppu7Z7zfnd", + "encryption_public_key": "8a2aef988ccc85d985d12270c5263032b9a7c71a86430e7b3c30a2f493462aee", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "4bad6c33b85ba3bbbada74c93a7a719962456af8000000000000000000000000", + "p2p_id": "p2p_12D3KooWSEF7cqkbMrS6uCo6xzCsfcPgquN652mZijmay8e3pn5R", + "encryption_public_key": "cf8e0e8c830f733dd5992076d0adaeb34c97410dd5d8d04afccad88070b07f20", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "078cb3bca763a11a0c79df636b018311d9e36954000000000000000000000000", + "p2p_id": "p2p_12D3KooWAumheDZJdc3in1qiYGAQESTUm1nAWGA59eQPb3wuFHJa", + "encryption_public_key": "c8f45b74982037dd52eeb3df5295c7769757c72cde9a930fc82cb72caf0085ad", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "7621630d4f33e02f659445974060df375c126e82000000000000000000000000", + "p2p_id": "p2p_12D3KooWF1XmgvoLx45H3iGc9jD4mK7X1mctYmhZCqw5h1S1sXtA", + "encryption_public_key": "f8d7485910b56c9521dea1beb3d50151917bae18e131ad311ef90300318b8110", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "b5599a0a8aa99860997e42d650c3dc1ac767a4b1000000000000000000000000", + "p2p_id": "p2p_12D3KooWFBsQE8gCZndyefzCZG6KHyjoeii7o7ff171tQHsGYq1p", + "encryption_public_key": "4081aacba87f07ea54c32517a9b661963a5fed5fbfd2042ff0823293d8fbd523", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "2067cc4ec71978974265e578eb9b5c62cccc0d33000000000000000000000000", + "p2p_id": "p2p_12D3KooWKYQ51iqiS99MWfE8gwy7P1sN8oL4WboWLPxHRo8duc28", + "encryption_public_key": "533bfbd913615823cbb93251f27f3cbdd035a732c0a68ad49081b37a702fe4a1", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "cd08a4d5934c41a389c2bd7b6fadfb1dace5f110000000000000000000000000", + "p2p_id": "p2p_12D3KooWMQjP7pp8ecxMSMd3Y3NocDsHt7g64bd7iGJhCr35gkby", + "encryption_public_key": "9ee181448ef55e381217ec959375fb302eba62e61006e4c9467832836cc8640e", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + } + ], + "nops": [ + { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + }, + { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + }, + { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + ], + "dons": [ + { + "id": 1, + "config_count": 1, + "f": 1, + "is_public": true, + "accepts_workflows": true, + "node_p2p_ids": [ + "p2p_12D3KooWAumheDZJdc3in1qiYGAQESTUm1nAWGA59eQPb3wuFHJa", + "p2p_12D3KooWE8ymezL2wxXcZdhznnBkVNcBRbtxVfNx1vppu7Z7zfnd", + "p2p_12D3KooWGVWpMrCZDotqSYWj8xqb1i5kNecpoarczpQoSAHdqwj8", + "p2p_12D3KooWSEF7cqkbMrS6uCo6xzCsfcPgquN652mZijmay8e3pn5R" + ], + "capability_configurations": [ + { + "id": "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b", + "config": "0a00" + } + ] + }, + { + "id": 2, + "config_count": 1, + "f": 1, + "is_public": true, + "node_p2p_ids": [ + "p2p_12D3KooWF1XmgvoLx45H3iGc9jD4mK7X1mctYmhZCqw5h1S1sXtA", + "p2p_12D3KooWFBsQE8gCZndyefzCZG6KHyjoeii7o7ff171tQHsGYq1p", + "p2p_12D3KooWKYQ51iqiS99MWfE8gwy7P1sN8oL4WboWLPxHRo8duc28", + "p2p_12D3KooWPsGKEe34m9X8qiWVpa6VEcjdvhbygJRLKXdVEr3r96PH" + ], + "capability_configurations": [ + { + "id": "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483", + "config": "0a001a1a0a187369676e65645f7265706f72742e5369676e617475726573" + } + ] + }, + { + "id": 3, + "config_count": 1, + "f": 1, + "is_public": true, + "node_p2p_ids": [ + "p2p_12D3KooWD1uj8Y9Phdr1yScfbBy1Q9ebedMVBjMUBLW4m4XnEzGF", + "p2p_12D3KooWLjKKWLhYkr68PH9FaZZR93WbJuohWWcTfA9JeY1UPoJa", + "p2p_12D3KooWMQjP7pp8ecxMSMd3Y3NocDsHt7g64bd7iGJhCr35gkby", + "p2p_12D3KooWRG3rsPdQyWCPsQukUF5JqFLdPqVVXvEfG2PAPBbqdRXp" + ], + "capability_configurations": [ + { + "id": "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a", + "config": "0a00120a0a0208141202083c1802" + } + ] + } + ], + "don_capabilities_summary": [ + { + "don": { + "id": 1, + "config_count": 1, + "f": 1, + "is_public": true, + "accepts_workflows": true + }, + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "f36818345fb18549bd24305c79f2f28d80d25710000000000000000000000000", + "p2p_id": "p2p_12D3KooWGVWpMrCZDotqSYWj8xqb1i5kNecpoarczpQoSAHdqwj8", + "encryption_public_key": "986707930499b85ab01705aa8d5cd99dca40926db3fa1728e6b58d25fddfe46b", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "afabd7685010d619ee6614e732b15e898c293426000000000000000000000000", + "p2p_id": "p2p_12D3KooWE8ymezL2wxXcZdhznnBkVNcBRbtxVfNx1vppu7Z7zfnd", + "encryption_public_key": "8a2aef988ccc85d985d12270c5263032b9a7c71a86430e7b3c30a2f493462aee", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "4bad6c33b85ba3bbbada74c93a7a719962456af8000000000000000000000000", + "p2p_id": "p2p_12D3KooWSEF7cqkbMrS6uCo6xzCsfcPgquN652mZijmay8e3pn5R", + "encryption_public_key": "cf8e0e8c830f733dd5992076d0adaeb34c97410dd5d8d04afccad88070b07f20", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "078cb3bca763a11a0c79df636b018311d9e36954000000000000000000000000", + "p2p_id": "p2p_12D3KooWAumheDZJdc3in1qiYGAQESTUm1nAWGA59eQPb3wuFHJa", + "encryption_public_key": "c8f45b74982037dd52eeb3df5295c7769757c72cde9a930fc82cb72caf0085ad", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + } + ], + "capabilities": [ + { + "id": "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b", + "labelled_name": "offchain_reporting", + "version": "1.0.0", + "capability_type": 2, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ] + }, + { + "don": { + "id": 2, + "config_count": 1, + "f": 1, + "is_public": true + }, + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "a0e11229b4b5d40d299f7f4b3348a1b16f5f3dd3000000000000000000000000", + "p2p_id": "p2p_12D3KooWPsGKEe34m9X8qiWVpa6VEcjdvhbygJRLKXdVEr3r96PH", + "encryption_public_key": "10c77049880fe0924f463763789985a0f76e09f82fc6f39943684b2dd05b98bf", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "7621630d4f33e02f659445974060df375c126e82000000000000000000000000", + "p2p_id": "p2p_12D3KooWF1XmgvoLx45H3iGc9jD4mK7X1mctYmhZCqw5h1S1sXtA", + "encryption_public_key": "f8d7485910b56c9521dea1beb3d50151917bae18e131ad311ef90300318b8110", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "b5599a0a8aa99860997e42d650c3dc1ac767a4b1000000000000000000000000", + "p2p_id": "p2p_12D3KooWFBsQE8gCZndyefzCZG6KHyjoeii7o7ff171tQHsGYq1p", + "encryption_public_key": "4081aacba87f07ea54c32517a9b661963a5fed5fbfd2042ff0823293d8fbd523", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "2067cc4ec71978974265e578eb9b5c62cccc0d33000000000000000000000000", + "p2p_id": "p2p_12D3KooWKYQ51iqiS99MWfE8gwy7P1sN8oL4WboWLPxHRo8duc28", + "encryption_public_key": "533bfbd913615823cbb93251f27f3cbdd035a732c0a68ad49081b37a702fe4a1", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + } + ], + "capabilities": [ + { + "id": "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483", + "labelled_name": "write_ethereum-testnet-sepolia", + "version": "1.0.0", + "capability_type": 3, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ] + }, + { + "don": { + "id": 3, + "config_count": 1, + "f": 1, + "is_public": true + }, + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "3f871cd7c34e50320934b6ba9b90b249363fd378000000000000000000000000", + "p2p_id": "p2p_12D3KooWLjKKWLhYkr68PH9FaZZR93WbJuohWWcTfA9JeY1UPoJa", + "encryption_public_key": "5cf5abd0349b27cde43ad1a55aa3b02a5518aa6eed365bd65ca5e0e2cbfdaa5a", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "d7a432ce8f23c410302e7577de9973ccbca29576000000000000000000000000", + "p2p_id": "p2p_12D3KooWRG3rsPdQyWCPsQukUF5JqFLdPqVVXvEfG2PAPBbqdRXp", + "encryption_public_key": "c10cead34374ba20704a05ca0369018b41778a0297adb85554cdd6e5955bf4b6", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "f1d2b3d13c46b0c1ded96534aabd6bae61934e3f000000000000000000000000", + "p2p_id": "p2p_12D3KooWD1uj8Y9Phdr1yScfbBy1Q9ebedMVBjMUBLW4m4XnEzGF", + "encryption_public_key": "5fc3dae131da5b0ac5474ad029e3a6c547e17249a6266427d5eea1f529b6488b", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "cd08a4d5934c41a389c2bd7b6fadfb1dace5f110000000000000000000000000", + "p2p_id": "p2p_12D3KooWMQjP7pp8ecxMSMd3Y3NocDsHt7g64bd7iGJhCr35gkby", + "encryption_public_key": "9ee181448ef55e381217ec959375fb302eba62e61006e4c9467832836cc8640e", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + } + ], + "capabilities": [ + { + "id": "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a", + "labelled_name": "streams-trigger", + "version": "1.0.0", + "capability_type": 0, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ] + } + ] +} \ No newline at end of file From e354c593feca326b504e9aea330b711edbe80e68 Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Wed, 20 Nov 2024 16:12:01 -0400 Subject: [PATCH 5/9] Completes tests comparing capability registry views --- .../common/changeset/capability_registry.go | 6 ----- .../changeset/capability_registry_test.go | 23 ++++++++++++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/deployment/common/changeset/capability_registry.go b/deployment/common/changeset/capability_registry.go index 9ae7ea6364c..f52431e434c 100644 --- a/deployment/common/changeset/capability_registry.go +++ b/deployment/common/changeset/capability_registry.go @@ -43,12 +43,6 @@ func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Env } nopsParams := v.NopsToNopsParams() - for _, nop := range v.Nops { - nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ - Admin: nop.Admin, - Name: nop.Name, - }) - } tx, err := deployedContract.Contract.AddNodeOperators(chain.DeployerKey, nopsParams) if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add node operators: %w", err) diff --git a/deployment/common/changeset/capability_registry_test.go b/deployment/common/changeset/capability_registry_test.go index e6f8050b64a..ac059a7388f 100644 --- a/deployment/common/changeset/capability_registry_test.go +++ b/deployment/common/changeset/capability_registry_test.go @@ -5,12 +5,14 @@ import ( "os" "testing" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -31,4 +33,23 @@ func TestHydrateCapabilityRegistry(t *testing.T) { hydrated, err := HydrateCapabilityRegistry(capabilityRegistryView, env, cfg) require.NoError(t, err) require.NotNil(t, hydrated) + + chainSelector, err := chainsel.SelectorFromChainId(chainID) + require.NoError(t, err) + chain, ok := env.Chains[chainSelector] + require.True(t, ok) + capabilityRegistry, err := capabilities_registry.NewCapabilitiesRegistry(hydrated.Address, chain.Client) + require.NoError(t, err) + require.NotNil(t, capabilityRegistry) + capView, err := v1_0.GenerateCapabilityRegistryView(capabilityRegistry) + require.NoError(t, err) + + // Setting address/owner values to be the same in order to compare the views + capView.Address = capabilityRegistryView.Address + capView.Owner = capabilityRegistryView.Owner + b1, err := capabilityRegistryView.MarshalJSON() + require.NoError(t, err) + b2, err := capView.MarshalJSON() + require.NoError(t, err) + require.Equal(t, string(b1), string(b2)) } From 3dff4e002bd3cb65eb7501fb8a2a1ef665d88f1a Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Thu, 21 Nov 2024 12:47:52 -0400 Subject: [PATCH 6/9] Refactors to use existing deployment logic --- .../changeset/capability_registry.go | 27 +++++++------------ .../changeset/capability_registry_test.go | 19 ++++--------- .../testdata/capability_registry_view.json | 0 .../keystone/changeset/deploy_registry.go | 13 ++++----- .../changeset/deploy_registry_test.go | 3 ++- deployment/keystone/changeset/view_test.go | 3 ++- deployment/keystone/contract_set.go | 12 +++++---- 7 files changed, 32 insertions(+), 45 deletions(-) rename deployment/common/{ => test}/changeset/capability_registry.go (67%) rename deployment/common/{ => test}/changeset/capability_registry_test.go (63%) rename deployment/common/{ => test}/changeset/testdata/capability_registry_view.json (100%) diff --git a/deployment/common/changeset/capability_registry.go b/deployment/common/test/changeset/capability_registry.go similarity index 67% rename from deployment/common/changeset/capability_registry.go rename to deployment/common/test/changeset/capability_registry.go index f52431e434c..332c8abbca1 100644 --- a/deployment/common/changeset/capability_registry.go +++ b/deployment/common/test/changeset/capability_registry.go @@ -2,12 +2,14 @@ package changeset import ( "fmt" + "testing" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/keystone" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) @@ -16,7 +18,8 @@ type HydrateConfig struct { } // HydrateCapabilityRegistry deploys a new capabilities registry contract and hydrates it with the provided data. -func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Environment, cfg HydrateConfig) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { +func HydrateCapabilityRegistry(t *testing.T, v v1_0.CapabilityRegistryView, env deployment.Environment, cfg HydrateConfig) (*capabilities_registry.CapabilitiesRegistry, error) { + t.Helper() chainSelector, err := chainsel.SelectorFromChainId(cfg.ChainID) if err != nil { return nil, fmt.Errorf("failed to get chain selector from chain id: %w", err) @@ -25,31 +28,19 @@ func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Env if !ok { return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID) } - deployedContract, err := deployment.DeployContract( - env.Logger, chain, env.ExistingAddresses, - func(chain deployment.Chain) deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry] { - crAddr, tx, cr, err2 := capabilities_registry.DeployCapabilitiesRegistry( - chain.DeployerKey, - chain.Client, - ) - return deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ - Address: crAddr, Contract: cr, Tx: tx, Err: err2, - Tv: deployment.NewTypeAndVersion("CapabilitiesRegistry", deployment.Version1_0_0), - } - }, - ) + _, deployedContract, err := changeset.DeployCapabilityRegistry(env, chainSelector) if err != nil { return nil, fmt.Errorf("failed to deploy contract: %w", err) } nopsParams := v.NopsToNopsParams() - tx, err := deployedContract.Contract.AddNodeOperators(chain.DeployerKey, nopsParams) + tx, err := deployedContract.AddNodeOperators(chain.DeployerKey, nopsParams) if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add node operators: %w", err) } capabilitiesParams := v.CapabilitiesToCapabilitiesParams() - tx, err = deployedContract.Contract.AddCapabilities(chain.DeployerKey, capabilitiesParams) + tx, err = deployedContract.AddCapabilities(chain.DeployerKey, capabilitiesParams) if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add capabilities: %w", err) } @@ -58,7 +49,7 @@ func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Env if err != nil { return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err) } - tx, err = deployedContract.Contract.AddNodes(chain.DeployerKey, nodesParams) + tx, err = deployedContract.AddNodes(chain.DeployerKey, nodesParams) if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add nodes: %w", err) } @@ -72,7 +63,7 @@ func HydrateCapabilityRegistry(v v1_0.CapabilityRegistryView, env deployment.Env for _, id := range don.NodeP2PIds { peerIds = append(peerIds, id) } - tx, err = deployedContract.Contract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) + tx, err = deployedContract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add don: %w", err) } diff --git a/deployment/common/changeset/capability_registry_test.go b/deployment/common/test/changeset/capability_registry_test.go similarity index 63% rename from deployment/common/changeset/capability_registry_test.go rename to deployment/common/test/changeset/capability_registry_test.go index ac059a7388f..9a5b2534082 100644 --- a/deployment/common/changeset/capability_registry_test.go +++ b/deployment/common/test/changeset/capability_registry_test.go @@ -12,7 +12,6 @@ import ( "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/environment/memory" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -30,26 +29,18 @@ func TestHydrateCapabilityRegistry(t *testing.T) { Chains: 2, Nodes: 4, }) - hydrated, err := HydrateCapabilityRegistry(capabilityRegistryView, env, cfg) + hydrated, err := HydrateCapabilityRegistry(t, capabilityRegistryView, env, cfg) require.NoError(t, err) require.NotNil(t, hydrated) - - chainSelector, err := chainsel.SelectorFromChainId(chainID) - require.NoError(t, err) - chain, ok := env.Chains[chainSelector] - require.True(t, ok) - capabilityRegistry, err := capabilities_registry.NewCapabilitiesRegistry(hydrated.Address, chain.Client) - require.NoError(t, err) - require.NotNil(t, capabilityRegistry) - capView, err := v1_0.GenerateCapabilityRegistryView(capabilityRegistry) + hydratedCapView, err := v1_0.GenerateCapabilityRegistryView(hydrated) require.NoError(t, err) // Setting address/owner values to be the same in order to compare the views - capView.Address = capabilityRegistryView.Address - capView.Owner = capabilityRegistryView.Owner + hydratedCapView.Address = capabilityRegistryView.Address + hydratedCapView.Owner = capabilityRegistryView.Owner b1, err := capabilityRegistryView.MarshalJSON() require.NoError(t, err) - b2, err := capView.MarshalJSON() + b2, err := hydratedCapView.MarshalJSON() require.NoError(t, err) require.Equal(t, string(b1), string(b2)) } diff --git a/deployment/common/changeset/testdata/capability_registry_view.json b/deployment/common/test/changeset/testdata/capability_registry_view.json similarity index 100% rename from deployment/common/changeset/testdata/capability_registry_view.json rename to deployment/common/test/changeset/testdata/capability_registry_view.json diff --git a/deployment/keystone/changeset/deploy_registry.go b/deployment/keystone/changeset/deploy_registry.go index 2c08e5ca8b7..7f0817793bf 100644 --- a/deployment/keystone/changeset/deploy_registry.go +++ b/deployment/keystone/changeset/deploy_registry.go @@ -5,21 +5,22 @@ import ( "github.com/smartcontractkit/chainlink/deployment" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) -func DeployCapabilityRegistry(env deployment.Environment, config interface{}) (deployment.ChangesetOutput, error) { +func DeployCapabilityRegistry(env deployment.Environment, config interface{}) (deployment.ChangesetOutput, *capabilities_registry.CapabilitiesRegistry, error) { registrySelector, ok := config.(uint64) if !ok { - return deployment.ChangesetOutput{}, deployment.ErrInvalidConfig + return deployment.ChangesetOutput{}, nil, deployment.ErrInvalidConfig } chain, ok := env.Chains[registrySelector] if !ok { - return deployment.ChangesetOutput{}, fmt.Errorf("chain not found in environment") + return deployment.ChangesetOutput{}, nil, fmt.Errorf("chain not found in environment") } ab := deployment.NewMemoryAddressBook() - err := kslib.DeployCapabilitiesRegistry(env.Logger, chain, ab) + capReg, err := kslib.DeployCapabilitiesRegistry(env.Logger, chain, ab) if err != nil { - return deployment.ChangesetOutput{}, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) + return deployment.ChangesetOutput{}, nil, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) } - return deployment.ChangesetOutput{AddressBook: ab}, nil + return deployment.ChangesetOutput{AddressBook: ab}, capReg, nil } diff --git a/deployment/keystone/changeset/deploy_registry_test.go b/deployment/keystone/changeset/deploy_registry_test.go index 6aa383ef68c..1914429b7f2 100644 --- a/deployment/keystone/changeset/deploy_registry_test.go +++ b/deployment/keystone/changeset/deploy_registry_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" ) @@ -22,7 +23,7 @@ func TestDeployCapabilityRegistry(t *testing.T) { env := memory.NewMemoryEnvironment(t, lggr, zapcore.DebugLevel, cfg) registrySel := env.AllChainSelectors()[0] - resp, err := changeset.DeployCapabilityRegistry(env, registrySel) + resp, _, err := changeset.DeployCapabilityRegistry(env, registrySel) require.NoError(t, err) require.NotNil(t, resp) // capabilities registry should be deployed on chain 0 diff --git a/deployment/keystone/changeset/view_test.go b/deployment/keystone/changeset/view_test.go index 2d4569dfbec..2ccc5786e91 100644 --- a/deployment/keystone/changeset/view_test.go +++ b/deployment/keystone/changeset/view_test.go @@ -7,6 +7,7 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" ) @@ -17,7 +18,7 @@ func TestKeystoneView(t *testing.T) { Chains: 2, }) registryChain := env.AllChainSelectors()[0] - resp, err := DeployCapabilityRegistry(env, registryChain) + resp, _, err := DeployCapabilityRegistry(env, registryChain) require.NoError(t, err) require.NotNil(t, resp) require.NoError(t, env.ExistingAddresses.Merge(resp.AddressBook)) diff --git a/deployment/keystone/contract_set.go b/deployment/keystone/contract_set.go index a0446dcfce0..97b9979c559 100644 --- a/deployment/keystone/contract_set.go +++ b/deployment/keystone/contract_set.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) type deployContractsRequest struct { @@ -28,7 +30,7 @@ func deployContractsToChain(lggr logger.Logger, req deployContractsRequest) (*de // cap reg and ocr3 only deployed on registry chain if req.isRegistryChain { - err := DeployCapabilitiesRegistry(lggr, req.chain, resp.AddressBook) + _, err := DeployCapabilitiesRegistry(lggr, req.chain, resp.AddressBook) if err != nil { return nil, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) } @@ -46,18 +48,18 @@ func deployContractsToChain(lggr logger.Logger, req deployContractsRequest) (*de // DeployCapabilitiesRegistry deploys the CapabilitiesRegistry contract to the chain // and saves the address in the address book. This mutates the address book. -func DeployCapabilitiesRegistry(lggr logger.Logger, chain deployment.Chain, ab deployment.AddressBook) error { +func DeployCapabilitiesRegistry(lggr logger.Logger, chain deployment.Chain, ab deployment.AddressBook) (*capabilities_registry.CapabilitiesRegistry, error) { capabilitiesRegistryDeployer := CapabilitiesRegistryDeployer{lggr: lggr} capabilitiesRegistryResp, err := capabilitiesRegistryDeployer.Deploy(DeployRequest{Chain: chain}) if err != nil { - return fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) + return nil, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) } err = ab.Save(chain.Selector, capabilitiesRegistryResp.Address.String(), capabilitiesRegistryResp.Tv) if err != nil { - return fmt.Errorf("failed to save CapabilitiesRegistry: %w", err) + return nil, fmt.Errorf("failed to save CapabilitiesRegistry: %w", err) } lggr.Infof("Deployed %s chain selector %d addr %s", capabilitiesRegistryResp.Tv.String(), chain.Selector, capabilitiesRegistryResp.Address.String()) - return nil + return capabilitiesRegistryDeployer.Contract(), nil } // DeployOCR3 deploys the OCR3Capability contract to the chain From 12eb0f89d237e225343f53ac427103801c5d0691 Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Fri, 22 Nov 2024 12:49:39 -0400 Subject: [PATCH 7/9] Gets deployed contract from contract sets --- .../common/test/changeset/capability_registry.go | 16 +++++++++++++++- .../test/changeset/capability_registry_test.go | 7 +++---- .../keystone/capability_registry_deployer.go | 1 + deployment/keystone/changeset/deploy_registry.go | 15 ++++++++------- .../keystone/changeset/deploy_registry_test.go | 2 +- deployment/keystone/changeset/view_test.go | 2 +- deployment/keystone/contract_set.go | 11 +++++------ deployment/keystone/state.go | 1 + 8 files changed, 35 insertions(+), 20 deletions(-) diff --git a/deployment/common/test/changeset/capability_registry.go b/deployment/common/test/changeset/capability_registry.go index 332c8abbca1..28ee711dc75 100644 --- a/deployment/common/test/changeset/capability_registry.go +++ b/deployment/common/test/changeset/capability_registry.go @@ -28,11 +28,25 @@ func HydrateCapabilityRegistry(t *testing.T, v v1_0.CapabilityRegistryView, env if !ok { return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID) } - _, deployedContract, err := changeset.DeployCapabilityRegistry(env, chainSelector) + changesetOutput, err := changeset.DeployCapabilityRegistry(env, chainSelector) if err != nil { return nil, fmt.Errorf("failed to deploy contract: %w", err) } + resp, err := keystone.GetContractSets(env.Logger, &keystone.GetContractSetsRequest{ + Chains: env.Chains, + AddressBook: changesetOutput.AddressBook, + }) + if err != nil { + return nil, fmt.Errorf("failed to get contract sets: %w", err) + } + cs, ok := resp.ContractSets[chainSelector] + if !ok { + return nil, fmt.Errorf("failed to get contract set for chain selector: %d, chain ID: %d", chainSelector, cfg.ChainID) + } + + deployedContract := cs.CapabilitiesRegistry + nopsParams := v.NopsToNopsParams() tx, err := deployedContract.AddNodeOperators(chain.DeployerKey, nopsParams) if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { diff --git a/deployment/common/test/changeset/capability_registry_test.go b/deployment/common/test/changeset/capability_registry_test.go index 9a5b2534082..13871871657 100644 --- a/deployment/common/test/changeset/capability_registry_test.go +++ b/deployment/common/test/changeset/capability_registry_test.go @@ -5,11 +5,10 @@ import ( "os" "testing" + chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" - chainsel "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -22,11 +21,11 @@ func TestHydrateCapabilityRegistry(t *testing.T) { var capabilityRegistryView v1_0.CapabilityRegistryView require.NoError(t, json.Unmarshal(b, &capabilityRegistryView)) - chainID := chainsel.TEST_90000001.EvmChainID + 1 + chainID := chainsel.TEST_90000001.EvmChainID cfg := HydrateConfig{ChainID: chainID} env := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ Bootstraps: 1, - Chains: 2, + Chains: 1, Nodes: 4, }) hydrated, err := HydrateCapabilityRegistry(t, capabilityRegistryView, env, cfg) diff --git a/deployment/keystone/capability_registry_deployer.go b/deployment/keystone/capability_registry_deployer.go index efe1d23f11f..a4648c27905 100644 --- a/deployment/keystone/capability_registry_deployer.go +++ b/deployment/keystone/capability_registry_deployer.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) diff --git a/deployment/keystone/changeset/deploy_registry.go b/deployment/keystone/changeset/deploy_registry.go index 7f0817793bf..3ad8a84ade1 100644 --- a/deployment/keystone/changeset/deploy_registry.go +++ b/deployment/keystone/changeset/deploy_registry.go @@ -5,22 +5,23 @@ import ( "github.com/smartcontractkit/chainlink/deployment" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) -func DeployCapabilityRegistry(env deployment.Environment, config interface{}) (deployment.ChangesetOutput, *capabilities_registry.CapabilitiesRegistry, error) { +var _ deployment.ChangeSet[interface{}] = DeployCapabilityRegistry + +func DeployCapabilityRegistry(env deployment.Environment, config interface{}) (deployment.ChangesetOutput, error) { registrySelector, ok := config.(uint64) if !ok { - return deployment.ChangesetOutput{}, nil, deployment.ErrInvalidConfig + return deployment.ChangesetOutput{}, deployment.ErrInvalidConfig } chain, ok := env.Chains[registrySelector] if !ok { - return deployment.ChangesetOutput{}, nil, fmt.Errorf("chain not found in environment") + return deployment.ChangesetOutput{}, fmt.Errorf("chain not found in environment") } ab := deployment.NewMemoryAddressBook() - capReg, err := kslib.DeployCapabilitiesRegistry(env.Logger, chain, ab) + err := kslib.DeployCapabilitiesRegistry(env.Logger, chain, ab) if err != nil { - return deployment.ChangesetOutput{}, nil, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) + return deployment.ChangesetOutput{}, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) } - return deployment.ChangesetOutput{AddressBook: ab}, capReg, nil + return deployment.ChangesetOutput{AddressBook: ab}, nil } diff --git a/deployment/keystone/changeset/deploy_registry_test.go b/deployment/keystone/changeset/deploy_registry_test.go index 1914429b7f2..9abf357f2a8 100644 --- a/deployment/keystone/changeset/deploy_registry_test.go +++ b/deployment/keystone/changeset/deploy_registry_test.go @@ -23,7 +23,7 @@ func TestDeployCapabilityRegistry(t *testing.T) { env := memory.NewMemoryEnvironment(t, lggr, zapcore.DebugLevel, cfg) registrySel := env.AllChainSelectors()[0] - resp, _, err := changeset.DeployCapabilityRegistry(env, registrySel) + resp, err := changeset.DeployCapabilityRegistry(env, registrySel) require.NoError(t, err) require.NotNil(t, resp) // capabilities registry should be deployed on chain 0 diff --git a/deployment/keystone/changeset/view_test.go b/deployment/keystone/changeset/view_test.go index 2ccc5786e91..023b4462549 100644 --- a/deployment/keystone/changeset/view_test.go +++ b/deployment/keystone/changeset/view_test.go @@ -18,7 +18,7 @@ func TestKeystoneView(t *testing.T) { Chains: 2, }) registryChain := env.AllChainSelectors()[0] - resp, _, err := DeployCapabilityRegistry(env, registryChain) + resp, err := DeployCapabilityRegistry(env, registryChain) require.NoError(t, err) require.NotNil(t, resp) require.NoError(t, env.ExistingAddresses.Merge(resp.AddressBook)) diff --git a/deployment/keystone/contract_set.go b/deployment/keystone/contract_set.go index 97b9979c559..ccd89f6905f 100644 --- a/deployment/keystone/contract_set.go +++ b/deployment/keystone/contract_set.go @@ -6,7 +6,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) type deployContractsRequest struct { @@ -30,7 +29,7 @@ func deployContractsToChain(lggr logger.Logger, req deployContractsRequest) (*de // cap reg and ocr3 only deployed on registry chain if req.isRegistryChain { - _, err := DeployCapabilitiesRegistry(lggr, req.chain, resp.AddressBook) + err := DeployCapabilitiesRegistry(lggr, req.chain, resp.AddressBook) if err != nil { return nil, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) } @@ -48,18 +47,18 @@ func deployContractsToChain(lggr logger.Logger, req deployContractsRequest) (*de // DeployCapabilitiesRegistry deploys the CapabilitiesRegistry contract to the chain // and saves the address in the address book. This mutates the address book. -func DeployCapabilitiesRegistry(lggr logger.Logger, chain deployment.Chain, ab deployment.AddressBook) (*capabilities_registry.CapabilitiesRegistry, error) { +func DeployCapabilitiesRegistry(lggr logger.Logger, chain deployment.Chain, ab deployment.AddressBook) error { capabilitiesRegistryDeployer := CapabilitiesRegistryDeployer{lggr: lggr} capabilitiesRegistryResp, err := capabilitiesRegistryDeployer.Deploy(DeployRequest{Chain: chain}) if err != nil { - return nil, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) + return fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) } err = ab.Save(chain.Selector, capabilitiesRegistryResp.Address.String(), capabilitiesRegistryResp.Tv) if err != nil { - return nil, fmt.Errorf("failed to save CapabilitiesRegistry: %w", err) + return fmt.Errorf("failed to save CapabilitiesRegistry: %w", err) } lggr.Infof("Deployed %s chain selector %d addr %s", capabilitiesRegistryResp.Tv.String(), chain.Selector, capabilitiesRegistryResp.Address.String()) - return capabilitiesRegistryDeployer.Contract(), nil + return nil } // DeployOCR3 deploys the OCR3Capability contract to the chain diff --git a/deployment/keystone/state.go b/deployment/keystone/state.go index 33200a40e02..68f2ab97a5d 100644 --- a/deployment/keystone/state.go +++ b/deployment/keystone/state.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" common_v1_0 "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/keystone/view" From bab657e4bd5654fe1951d3cc02a5ea4a6c27c6c1 Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Fri, 22 Nov 2024 13:18:19 -0400 Subject: [PATCH 8/9] Uses uint64 type annotation --- deployment/keystone/changeset/deploy_registry.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/deployment/keystone/changeset/deploy_registry.go b/deployment/keystone/changeset/deploy_registry.go index 3ad8a84ade1..e9b142812d7 100644 --- a/deployment/keystone/changeset/deploy_registry.go +++ b/deployment/keystone/changeset/deploy_registry.go @@ -7,13 +7,9 @@ import ( kslib "github.com/smartcontractkit/chainlink/deployment/keystone" ) -var _ deployment.ChangeSet[interface{}] = DeployCapabilityRegistry +var _ deployment.ChangeSet[uint64] = DeployCapabilityRegistry -func DeployCapabilityRegistry(env deployment.Environment, config interface{}) (deployment.ChangesetOutput, error) { - registrySelector, ok := config.(uint64) - if !ok { - return deployment.ChangesetOutput{}, deployment.ErrInvalidConfig - } +func DeployCapabilityRegistry(env deployment.Environment, registrySelector uint64) (deployment.ChangesetOutput, error) { chain, ok := env.Chains[registrySelector] if !ok { return deployment.ChangesetOutput{}, fmt.Errorf("chain not found in environment") From 54745bc3a4231a22fb8c607e1fac0467605a21c5 Mon Sep 17 00:00:00 2001 From: vyzaldysanchez Date: Mon, 25 Nov 2024 12:25:24 -0400 Subject: [PATCH 9/9] Moves implementation to `keystone/test` --- .../{common => keystone}/test/changeset/capability_registry.go | 0 .../test/changeset/capability_registry_test.go | 3 ++- .../test/changeset/testdata/capability_registry_view.json | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename deployment/{common => keystone}/test/changeset/capability_registry.go (100%) rename deployment/{common => keystone}/test/changeset/capability_registry_test.go (99%) rename deployment/{common => keystone}/test/changeset/testdata/capability_registry_view.json (100%) diff --git a/deployment/common/test/changeset/capability_registry.go b/deployment/keystone/test/changeset/capability_registry.go similarity index 100% rename from deployment/common/test/changeset/capability_registry.go rename to deployment/keystone/test/changeset/capability_registry.go diff --git a/deployment/common/test/changeset/capability_registry_test.go b/deployment/keystone/test/changeset/capability_registry_test.go similarity index 99% rename from deployment/common/test/changeset/capability_registry_test.go rename to deployment/keystone/test/changeset/capability_registry_test.go index 13871871657..765c95ff294 100644 --- a/deployment/common/test/changeset/capability_registry_test.go +++ b/deployment/keystone/test/changeset/capability_registry_test.go @@ -5,10 +5,11 @@ import ( "os" "testing" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/deployment/common/test/changeset/testdata/capability_registry_view.json b/deployment/keystone/test/changeset/testdata/capability_registry_view.json similarity index 100% rename from deployment/common/test/changeset/testdata/capability_registry_view.json rename to deployment/keystone/test/changeset/testdata/capability_registry_view.json