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

deployment/ccip/changeset: mcms optional ccip home cses #15658

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions deployment/ccip/changeset/accept_ownership_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) {
dest := allChains[1]

timelockContracts := map[uint64]*proposalutils.TimelockExecutionContracts{
source: &proposalutils.TimelockExecutionContracts{
source: {
Timelock: state.Chains[source].Timelock,
CallProxy: state.Chains[source].CallProxy,
},
dest: &proposalutils.TimelockExecutionContracts{
dest: {
Timelock: state.Chains[dest].Timelock,
CallProxy: state.Chains[dest].CallProxy,
},
Expand Down
170 changes: 1 addition & 169 deletions deployment/ccip/changeset/cs_add_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,14 @@ import (

"github.com/smartcontractkit/chainlink-ccip/chainconfig"
"github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"

"github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal"
"github.com/smartcontractkit/chainlink/deployment/common/proposalutils"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"

"github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock"

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp"
)
Expand Down Expand Up @@ -136,135 +132,6 @@ func NewChainInboundChangeset(
}, nil
}

type AddDonAndSetCandidateChangesetConfig struct {
HomeChainSelector uint64
FeedChainSelector uint64
NewChainSelector uint64
PluginType types.PluginType
NodeIDs []string
CCIPOCRParams CCIPOCRParams
}

func (a AddDonAndSetCandidateChangesetConfig) Validate(e deployment.Environment, state CCIPOnChainState) (deployment.Nodes, error) {
if a.HomeChainSelector == 0 {
return nil, fmt.Errorf("HomeChainSelector must be set")
}
if a.FeedChainSelector == 0 {
return nil, fmt.Errorf("FeedChainSelector must be set")
}
if a.NewChainSelector == 0 {
return nil, fmt.Errorf("ocr config chain selector must be set")
}
if a.PluginType != types.PluginTypeCCIPCommit &&
a.PluginType != types.PluginTypeCCIPExec {
return nil, fmt.Errorf("PluginType must be set to either CCIPCommit or CCIPExec")
}
// TODO: validate token config
if len(a.NodeIDs) == 0 {
return nil, fmt.Errorf("nodeIDs must be set")
}
nodes, err := deployment.NodeInfo(a.NodeIDs, e.Offchain)
if err != nil {
return nil, fmt.Errorf("get node info: %w", err)
}

// check that chain config is set up for the new chain
chainConfig, err := state.Chains[a.HomeChainSelector].CCIPHome.GetChainConfig(nil, a.NewChainSelector)
if err != nil {
return nil, fmt.Errorf("get all chain configs: %w", err)
}

// FChain should never be zero if a chain config is set in CCIPHome
if chainConfig.FChain == 0 {
return nil, fmt.Errorf("chain config not set up for new chain %d", a.NewChainSelector)
}

err = a.CCIPOCRParams.Validate()
if err != nil {
return nil, fmt.Errorf("invalid ccip ocr params: %w", err)
}

if e.OCRSecrets.IsEmpty() {
return nil, fmt.Errorf("OCR secrets must be set")
}

return nodes, nil
}

// AddDonAndSetCandidateChangeset adds new DON for destination to home chain
// and sets the commit plugin config as candidateConfig for the don.
func AddDonAndSetCandidateChangeset(
e deployment.Environment,
cfg AddDonAndSetCandidateChangesetConfig,
) (deployment.ChangesetOutput, error) {
state, err := LoadOnchainState(e)
if err != nil {
return deployment.ChangesetOutput{}, err
}

nodes, err := cfg.Validate(e, state)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("%w: %w", deployment.ErrInvalidConfig, err)
}

newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome(
e.OCRSecrets,
state.Chains[cfg.NewChainSelector].OffRamp,
e.Chains[cfg.NewChainSelector],
nodes.NonBootstraps(),
state.Chains[cfg.HomeChainSelector].RMNHome.Address(),
cfg.CCIPOCRParams.OCRParameters,
cfg.CCIPOCRParams.CommitOffChainConfig,
cfg.CCIPOCRParams.ExecuteOffChainConfig,
)
if err != nil {
return deployment.ChangesetOutput{}, err
}
latestDon, err := internal.LatestCCIPDON(state.Chains[cfg.HomeChainSelector].CapabilityRegistry)
if err != nil {
return deployment.ChangesetOutput{}, err
}
commitConfig, ok := newDONArgs[cfg.PluginType]
if !ok {
return deployment.ChangesetOutput{}, fmt.Errorf("missing commit plugin in ocr3Configs")
}
donID := latestDon.Id + 1
addDonOp, err := newDonWithCandidateOp(
donID, commitConfig,
state.Chains[cfg.HomeChainSelector].CapabilityRegistry,
nodes.NonBootstraps(),
)
if err != nil {
return deployment.ChangesetOutput{}, err
}

var (
timelocksPerChain = map[uint64]common.Address{
cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].Timelock.Address(),
}
proposerMCMSes = map[uint64]*gethwrappers.ManyChainMultiSig{
cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].ProposerMcm,
}
)
prop, err := proposalutils.BuildProposalFromBatches(
timelocksPerChain,
proposerMCMSes,
[]timelock.BatchChainOperation{{
ChainIdentifier: mcms.ChainIdentifier(cfg.HomeChainSelector),
Batch: []mcms.Operation{addDonOp},
}},
"setCandidate for commit and AddDon on new Chain",
0, // minDelay
)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to build proposal from batch: %w", err)
}

return deployment.ChangesetOutput{
Proposals: []timelock.MCMSWithTimelockProposal{*prop},
}, nil
}

func applyChainConfigUpdatesOp(
e deployment.Environment,
state CCIPOnChainState,
Expand Down Expand Up @@ -304,38 +171,3 @@ func applyChainConfigUpdatesOp(
Value: big.NewInt(0),
}, nil
}

// newDonWithCandidateOp sets the candidate commit config by calling setCandidate on CCIPHome contract through the AddDON call on CapReg contract
// This should be done first before calling any other UpdateDON calls
// This proposes to set up OCR3 config for the commit plugin for the DON
func newDonWithCandidateOp(
donID uint32,
pluginConfig ccip_home.CCIPHomeOCR3Config,
capReg *capabilities_registry.CapabilitiesRegistry,
nodes deployment.Nodes,
) (mcms.Operation, error) {
encodedSetCandidateCall, err := internal.CCIPHomeABI.Pack(
"setCandidate",
donID,
pluginConfig.PluginType,
pluginConfig,
[32]byte{},
)
if err != nil {
return mcms.Operation{}, fmt.Errorf("pack set candidate call: %w", err)
}
addDonTx, err := capReg.AddDON(deployment.SimTransactOpts(), nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{
{
CapabilityId: internal.CCIPCapabilityID,
Config: encodedSetCandidateCall,
},
}, false, false, nodes.DefaultF())
if err != nil {
return mcms.Operation{}, fmt.Errorf("could not generate add don tx w/ commit config: %w", err)
}
return mcms.Operation{
To: capReg.Address(),
Data: addDonTx.Data(),
Value: big.NewInt(0),
}, nil
}
43 changes: 21 additions & 22 deletions deployment/ccip/changeset/cs_add_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,16 +179,9 @@ func TestAddChainInbound(t *testing.T) {

assertTimelockOwnership(t, e, initialDeploy, state)

nodes, err := deployment.NodeInfo(e.Env.NodeIDs, e.Env.Offchain)
require.NoError(t, err)

// TODO This currently is not working - Able to send the request here but request gets stuck in execution
// Send a new message and expect that this is delivered once the chain is completely set up as inbound
//TestSendRequest(t, e.Env, state, initialDeploy[0], newChain, true)
var nodeIDs []string
for _, node := range nodes {
nodeIDs = append(nodeIDs, node.NodeID)
}

_, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*proposalutils.TimelockExecutionContracts{
e.HomeChainSel: {
Expand All @@ -203,45 +196,51 @@ func TestAddChainInbound(t *testing.T) {
{
Changeset: commonchangeset.WrapChangeSet(AddDonAndSetCandidateChangeset),
Config: AddDonAndSetCandidateChangesetConfig{
HomeChainSelector: e.HomeChainSel,
FeedChainSelector: e.FeedChainSel,
NewChainSelector: newChain,
PluginType: types.PluginTypeCCIPCommit,
NodeIDs: nodeIDs,
CCIPOCRParams: DefaultOCRParams(
e.FeedChainSel,
tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9),
nil,
),
SetCandidateChangesetConfig: SetCandidateChangesetConfig{
HomeChainSelector: e.HomeChainSel,
FeedChainSelector: e.FeedChainSel,
DONChainSelector: newChain,
PluginType: types.PluginTypeCCIPCommit,
CCIPOCRParams: DefaultOCRParams(
e.FeedChainSel,
tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9),
nil,
),
MCMS: &MCMSConfig{
MinDelay: 0,
},
},
},
},
{
Changeset: commonchangeset.WrapChangeSet(SetCandidatePluginChangeset),
Config: AddDonAndSetCandidateChangesetConfig{
Changeset: commonchangeset.WrapChangeSet(SetCandidateChangeset),
Config: SetCandidateChangesetConfig{
HomeChainSelector: e.HomeChainSel,
FeedChainSelector: e.FeedChainSel,
NewChainSelector: newChain,
DONChainSelector: newChain,
PluginType: types.PluginTypeCCIPExec,
NodeIDs: nodeIDs,
CCIPOCRParams: DefaultOCRParams(
e.FeedChainSel,
tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9),
nil,
),
MCMS: &MCMSConfig{
MinDelay: 0,
},
},
},
{
Changeset: commonchangeset.WrapChangeSet(PromoteAllCandidatesChangeset),
Config: PromoteAllCandidatesChangesetConfig{
HomeChainSelector: e.HomeChainSel,
DONChainSelector: newChain,
NodeIDs: nodeIDs,
MCMS: &MCMSConfig{
MinDelay: 0,
},
},
},
})
require.NoError(t, err)

// verify if the configs are updated
require.NoError(t, ValidateCCIPHomeConfigSetUp(
Expand Down
Loading
Loading