Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to hydrate contract from the capability registry view #15309

Merged
merged 9 commits into from
Nov 25, 2024
87 changes: 87 additions & 0 deletions deployment/common/test/changeset/capability_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
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"
)

type HydrateConfig struct {
ChainID uint64
}

// HydrateCapabilityRegistry deploys a new capabilities registry contract and hydrates it with the provided data.
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)
}
chain, ok := env.Chains[chainSelector]
if !ok {
return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID)
}
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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@connorwstein it's not straightforward to reuse the existing changeset that deploys/configures our capability registry because it does too much stuff (and need to be refactored to support mcms as discussed in slack)

i'd like to move forward with this approach here so we can use the tool downstream

@vyzaldysanchez please file a ticket to refactor this logic into calls to bite-sizes changesets. and write in that ticket that we need to implement the changesets first.

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.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)
}

nodesParams, err := v.NodesToNodesParams()
if err != nil {
return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err)
}
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)
}

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.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)
}
}

return deployedContract, nil
}
45 changes: 45 additions & 0 deletions deployment/common/test/changeset/capability_registry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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
cfg := HydrateConfig{ChainID: chainID}
env := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{
Bootstraps: 1,
Chains: 1,
Nodes: 4,
})
hydrated, err := HydrateCapabilityRegistry(t, capabilityRegistryView, env, cfg)
require.NoError(t, err)
require.NotNil(t, hydrated)
hydratedCapView, err := v1_0.GenerateCapabilityRegistryView(hydrated)
require.NoError(t, err)

// Setting address/owner values to be the same in order to compare the views
hydratedCapView.Address = capabilityRegistryView.Address
hydratedCapView.Owner = capabilityRegistryView.Owner
b1, err := capabilityRegistryView.MarshalJSON()
require.NoError(t, err)
b2, err := hydratedCapView.MarshalJSON()
require.NoError(t, err)
require.Equal(t, string(b1), string(b2))
}
Loading
Loading