From 5f14bf09452442a21bb1cf8e44ea3c3352572961 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Mon, 9 Dec 2024 17:47:49 -0800 Subject: [PATCH 1/4] remove deployCCIPContracts --- .../ccip/changeset/cs_add_chain_test.go | 15 ++++++++- deployment/ccip/changeset/cs_deploy_chain.go | 32 ------------------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/deployment/ccip/changeset/cs_add_chain_test.go b/deployment/ccip/changeset/cs_add_chain_test.go index c8d872236c2..2873b3bf613 100644 --- a/deployment/ccip/changeset/cs_add_chain_test.go +++ b/deployment/ccip/changeset/cs_add_chain_test.go @@ -80,10 +80,23 @@ func TestAddChainInbound(t *testing.T) { for _, chain := range initialDeploy { chainConfig[chain] = DefaultOCRParams(e.FeedChainSel, nil, nil) } - err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ + newChainCfg := NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainConfigByChain: chainConfig, + } + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), + Config: DeployChainContractsConfig{ + ChainSelectors: newChainCfg.Chains(), + HomeChainSelector: newChainCfg.HomeChainSel, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), + Config: newChainCfg, + }, }) require.NoError(t, err) diff --git a/deployment/ccip/changeset/cs_deploy_chain.go b/deployment/ccip/changeset/cs_deploy_chain.go index e2762b27578..de6e4b5f466 100644 --- a/deployment/ccip/changeset/cs_deploy_chain.go +++ b/deployment/ccip/changeset/cs_deploy_chain.go @@ -65,38 +65,6 @@ func (c DeployChainContractsConfig) Validate() error { return nil } -// deployCCIPContracts assumes the following contracts are deployed: -// - Capability registry -// - CCIP home -// - RMN home -// - Fee tokens on all chains. -// and present in ExistingAddressBook. -// It then deploys the rest of the CCIP chain contracts to the selected chains -// registers the nodes with the capability registry and creates a DON for -// each new chain. -func deployCCIPContracts( - e deployment.Environment, - ab deployment.AddressBook, - c NewChainsConfig) error { - err := deployChainContractsForChains(e, ab, c.HomeChainSel, c.Chains()) - if err != nil { - e.Logger.Errorw("Failed to deploy chain contracts", "err", err) - return err - } - err = e.ExistingAddresses.Merge(ab) - if err != nil { - e.Logger.Errorw("Failed to merge address book", "err", err) - return err - } - err = configureChain(e, c) - if err != nil { - e.Logger.Errorw("Failed to add chain", "err", err) - return err - } - - return nil -} - func deployChainContractsForChains( e deployment.Environment, ab deployment.AddressBook, From e5040ff72af2042ea014af3ddfe36083c98b8ac9 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 18 Dec 2024 14:54:56 -0800 Subject: [PATCH 2/4] initial --- deployment/ccip/changeset/cs_ccip_home.go | 49 +++++++++++------------ 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/deployment/ccip/changeset/cs_ccip_home.go b/deployment/ccip/changeset/cs_ccip_home.go index 1d8c6782b76..92e6219aaee 100644 --- a/deployment/ccip/changeset/cs_ccip_home.go +++ b/deployment/ccip/changeset/cs_ccip_home.go @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commoncs "github.com/smartcontractkit/chainlink/deployment/common/changeset" @@ -111,7 +112,7 @@ type PromoteAllCandidatesChangesetConfig struct { // RemoteChainSelectors is the chain selector of the DONs that we want to promote the candidate config of. // Note that each (chain, ccip capability version) pair has a unique DON ID. - RemoteChainSelectors []uint64 + RemoteChainCfg []PromoteAllCandidatesChangesetConfigPerRemoteChain // MCMS is optional MCMS configuration, if provided the changeset will generate an MCMS proposal. // If nil, the changeset will execute the commands directly using the deployer key @@ -119,6 +120,11 @@ type PromoteAllCandidatesChangesetConfig struct { MCMS *MCMSConfig } +type PromoteAllCandidatesChangesetConfigPerRemoteChain struct { + Chain uint64 + PluginType types.PluginType +} + func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment) ([]uint32, error) { state, err := LoadOnchainState(e) if err != nil { @@ -136,53 +142,46 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment) } var donIDs []uint32 - for _, chainSelector := range p.RemoteChainSelectors { - if err := deployment.IsValidChainSelector(chainSelector); err != nil { + for _, cfg := range p.RemoteChainCfg { + if err := deployment.IsValidChainSelector(cfg.Chain); err != nil { return nil, fmt.Errorf("don chain selector invalid: %w", err) } - chainState, exists := state.Chains[chainSelector] + chainState, exists := state.Chains[cfg.Chain] if !exists { - return nil, fmt.Errorf("chain %d does not exist", chainSelector) + return nil, fmt.Errorf("chain %d does not exist", cfg.Chain) } if chainState.OffRamp == nil { // should not be possible, but a defensive check. return nil, fmt.Errorf("OffRamp contract does not exist") } + if cfg.PluginType != types.PluginTypeCCIPCommit && + cfg.PluginType != types.PluginTypeCCIPExec { + return nil, fmt.Errorf("PluginType must be set to either CCIPCommit or CCIPExec for chain %d", cfg.Chain) + } + donID, err := internal.DonIDForChain( state.Chains[p.HomeChainSelector].CapabilityRegistry, state.Chains[p.HomeChainSelector].CCIPHome, - chainSelector, + cfg.Chain, ) if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } if donID == 0 { - return nil, fmt.Errorf("don doesn't exist in CR for chain %d", p.RemoteChainSelectors) + return nil, fmt.Errorf("don doesn't exist in CR for chain %d", cfg.Chain) } // Check that candidate digest and active digest are not both zero - this is enforced onchain. - commitConfigs, err := state.Chains[p.HomeChainSelector].CCIPHome.GetAllConfigs(&bind.CallOpts{ + pluginConfigs, err := state.Chains[p.HomeChainSelector].CCIPHome.GetAllConfigs(&bind.CallOpts{ Context: e.GetContext(), - }, donID, uint8(cctypes.PluginTypeCCIPCommit)) + }, donID, uint8(cfg.PluginType)) if err != nil { - return nil, fmt.Errorf("fetching commit configs from cciphome: %w", err) - } - - execConfigs, err := state.Chains[p.HomeChainSelector].CCIPHome.GetAllConfigs(&bind.CallOpts{ - Context: e.GetContext(), - }, donID, uint8(cctypes.PluginTypeCCIPExec)) - if err != nil { - return nil, fmt.Errorf("fetching exec configs from cciphome: %w", err) - } - - if commitConfigs.ActiveConfig.ConfigDigest == [32]byte{} && - commitConfigs.CandidateConfig.ConfigDigest == [32]byte{} { - return nil, fmt.Errorf("commit active and candidate config digests are both zero") + return nil, fmt.Errorf("fetching %s configs from cciphome: %w", cfg.PluginType.String(), err) } - if execConfigs.ActiveConfig.ConfigDigest == [32]byte{} && - execConfigs.CandidateConfig.ConfigDigest == [32]byte{} { - return nil, fmt.Errorf("exec active and candidate config digests are both zero") + if pluginConfigs.ActiveConfig.ConfigDigest == [32]byte{} && + pluginConfigs.CandidateConfig.ConfigDigest == [32]byte{} { + return nil, fmt.Errorf("%s active and candidate config digests are both zero", cfg.PluginType.String()) } donIDs = append(donIDs, donID) } From 954f5b382e1e217174a26d47301c9cae357c5b86 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 18 Dec 2024 16:17:30 -0800 Subject: [PATCH 3/4] promote digest by plugin --- deployment/ccip/changeset/cs_ccip_home.go | 70 +++++++------------ .../ccip/changeset/cs_ccip_home_test.go | 9 ++- .../changeset/internal/deploy_home_chain.go | 6 ++ deployment/ccip/changeset/test_environment.go | 11 +++ 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/deployment/ccip/changeset/cs_ccip_home.go b/deployment/ccip/changeset/cs_ccip_home.go index 92e6219aaee..c981a616592 100644 --- a/deployment/ccip/changeset/cs_ccip_home.go +++ b/deployment/ccip/changeset/cs_ccip_home.go @@ -112,19 +112,15 @@ type PromoteAllCandidatesChangesetConfig struct { // RemoteChainSelectors is the chain selector of the DONs that we want to promote the candidate config of. // Note that each (chain, ccip capability version) pair has a unique DON ID. - RemoteChainCfg []PromoteAllCandidatesChangesetConfigPerRemoteChain + RemoteChainSelectors []uint64 + PluginType types.PluginType // MCMS is optional MCMS configuration, if provided the changeset will generate an MCMS proposal. // If nil, the changeset will execute the commands directly using the deployer key // of the provided environment. MCMS *MCMSConfig } -type PromoteAllCandidatesChangesetConfigPerRemoteChain struct { - Chain uint64 - PluginType types.PluginType -} - func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment) ([]uint32, error) { state, err := LoadOnchainState(e) if err != nil { @@ -141,47 +137,47 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment) return nil, err } + if p.PluginType != types.PluginTypeCCIPCommit && + p.PluginType != types.PluginTypeCCIPExec { + return nil, fmt.Errorf("PluginType must be set to either CCIPCommit or CCIPExec") + } + var donIDs []uint32 - for _, cfg := range p.RemoteChainCfg { - if err := deployment.IsValidChainSelector(cfg.Chain); err != nil { + for _, selector := range p.RemoteChainSelectors { + if err := deployment.IsValidChainSelector(selector); err != nil { return nil, fmt.Errorf("don chain selector invalid: %w", err) } - chainState, exists := state.Chains[cfg.Chain] + chainState, exists := state.Chains[selector] if !exists { - return nil, fmt.Errorf("chain %d does not exist", cfg.Chain) + return nil, fmt.Errorf("chain %d does not exist", selector) } if chainState.OffRamp == nil { // should not be possible, but a defensive check. return nil, fmt.Errorf("OffRamp contract does not exist") } - if cfg.PluginType != types.PluginTypeCCIPCommit && - cfg.PluginType != types.PluginTypeCCIPExec { - return nil, fmt.Errorf("PluginType must be set to either CCIPCommit or CCIPExec for chain %d", cfg.Chain) - } - donID, err := internal.DonIDForChain( state.Chains[p.HomeChainSelector].CapabilityRegistry, state.Chains[p.HomeChainSelector].CCIPHome, - cfg.Chain, + selector, ) if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } if donID == 0 { - return nil, fmt.Errorf("don doesn't exist in CR for chain %d", cfg.Chain) + return nil, fmt.Errorf("don doesn't exist in CR for chain %d", selector) } // Check that candidate digest and active digest are not both zero - this is enforced onchain. pluginConfigs, err := state.Chains[p.HomeChainSelector].CCIPHome.GetAllConfigs(&bind.CallOpts{ Context: e.GetContext(), - }, donID, uint8(cfg.PluginType)) + }, donID, uint8(p.PluginType)) if err != nil { - return nil, fmt.Errorf("fetching %s configs from cciphome: %w", cfg.PluginType.String(), err) + return nil, fmt.Errorf("fetching %s configs from cciphome: %w", p.PluginType.String(), err) } if pluginConfigs.ActiveConfig.ConfigDigest == [32]byte{} && pluginConfigs.CandidateConfig.ConfigDigest == [32]byte{} { - return nil, fmt.Errorf("%s active and candidate config digests are both zero", cfg.PluginType.String()) + return nil, fmt.Errorf("%s active and candidate config digests are both zero", p.PluginType.String()) } donIDs = append(donIDs, donID) } @@ -237,12 +233,13 @@ func PromoteAllCandidatesChangeset( state.Chains[cfg.HomeChainSelector].CCIPHome, nodes.NonBootstraps(), donID, + cfg.PluginType, cfg.MCMS != nil, ) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("generating promote candidate ops: %w", err) } - ops = append(ops, promoteCandidateOps...) + ops = append(ops, promoteCandidateOps) } // Disabled MCMS means that we already executed the txes, so just return early w/out the proposals. @@ -790,44 +787,27 @@ func promoteAllCandidatesForChainOps( ccipHome *ccip_home.CCIPHome, nodes deployment.Nodes, donID uint32, + pluginType cctypes.PluginType, mcmsEnabled bool, -) ([]mcms.Operation, error) { +) (mcms.Operation, error) { if donID == 0 { - return nil, fmt.Errorf("donID is zero") + return mcms.Operation{}, fmt.Errorf("donID is zero") } - var mcmsOps []mcms.Operation - updateCommitOp, err := promoteCandidateOp( + updatePluginOp, err := promoteCandidateOp( txOpts, homeChain, capReg, ccipHome, nodes, donID, - uint8(cctypes.PluginTypeCCIPCommit), + uint8(pluginType), mcmsEnabled, ) if err != nil { - return nil, fmt.Errorf("promote candidate op: %w", err) + return mcms.Operation{}, fmt.Errorf("promote candidate op for plugin %s: %w", pluginType.String(), err) } - mcmsOps = append(mcmsOps, updateCommitOp) - - updateExecOp, err := promoteCandidateOp( - txOpts, - homeChain, - capReg, - ccipHome, - nodes, - donID, - uint8(cctypes.PluginTypeCCIPExec), - mcmsEnabled, - ) - if err != nil { - return nil, fmt.Errorf("promote candidate op: %w", err) - } - mcmsOps = append(mcmsOps, updateExecOp) - - return mcmsOps, nil + return updatePluginOp, nil } type RevokeCandidateChangesetConfig struct { diff --git a/deployment/ccip/changeset/cs_ccip_home_test.go b/deployment/ccip/changeset/cs_ccip_home_test.go index b487f1acc26..6b4683ae12c 100644 --- a/deployment/ccip/changeset/cs_ccip_home_test.go +++ b/deployment/ccip/changeset/cs_ccip_home_test.go @@ -61,16 +61,17 @@ func Test_PromoteCandidate(t *testing.T) { donID, err := internal.DonIDForChain(capReg, ccipHome, dest) require.NoError(t, err) require.NotEqual(t, uint32(0), donID) + t.Logf("donID: %d", donID) candidateDigestCommitBefore, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ Context: ctx, }, donID, uint8(types.PluginTypeCCIPCommit)) require.NoError(t, err) require.Equal(t, [32]byte{}, candidateDigestCommitBefore) - candidateDigestExecBefore, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ + ActiveDigestExecBefore, err := ccipHome.GetActiveDigest(&bind.CallOpts{ Context: ctx, }, donID, uint8(types.PluginTypeCCIPExec)) require.NoError(t, err) - require.Equal(t, [32]byte{}, candidateDigestExecBefore) + require.NotEqual(t, [32]byte{}, ActiveDigestExecBefore) var mcmsConfig *MCMSConfig if tc.mcmsEnabled { @@ -78,6 +79,7 @@ func Test_PromoteCandidate(t *testing.T) { MinDelay: 0, } } + // promotes zero digest on commit and ensure exec is not affected _, err = commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ tenv.HomeChainSel: { Timelock: state.Chains[tenv.HomeChainSel].Timelock, @@ -90,6 +92,7 @@ func Test_PromoteCandidate(t *testing.T) { HomeChainSelector: tenv.HomeChainSel, RemoteChainSelectors: []uint64{dest}, MCMS: mcmsConfig, + PluginType: types.PluginTypeCCIPCommit, }, }, }) @@ -106,7 +109,7 @@ func Test_PromoteCandidate(t *testing.T) { Context: ctx, }, donID, uint8(types.PluginTypeCCIPExec)) require.NoError(t, err) - require.Equal(t, [32]byte{}, activeDigestExec) + require.Equal(t, ActiveDigestExecBefore, activeDigestExec) }) } } diff --git a/deployment/ccip/changeset/internal/deploy_home_chain.go b/deployment/ccip/changeset/internal/deploy_home_chain.go index 2c401fd8006..ad87acf1239 100644 --- a/deployment/ccip/changeset/internal/deploy_home_chain.go +++ b/deployment/ccip/changeset/internal/deploy_home_chain.go @@ -126,6 +126,12 @@ func DonIDForChain(registry *capabilities_registry.CapabilitiesRegistry, ccipHom if err != nil { return 0, fmt.Errorf("get all commit configs from cciphome: %w", err) } + if configs.ActiveConfig.ConfigDigest == [32]byte{} && configs.CandidateConfig.ConfigDigest == [32]byte{} { + configs, err = ccipHome.GetAllConfigs(nil, don.Id, uint8(types.PluginTypeCCIPExec)) + if err != nil { + return 0, fmt.Errorf("get all exec configs from cciphome: %w", err) + } + } if configs.ActiveConfig.Config.ChainSelector == chainSelector || configs.CandidateConfig.Config.ChainSelector == chainSelector { donIDs = append(donIDs, don.Id) } diff --git a/deployment/ccip/changeset/test_environment.go b/deployment/ccip/changeset/test_environment.go index 8c2ea88b276..8e590da1703 100644 --- a/deployment/ccip/changeset/test_environment.go +++ b/deployment/ccip/changeset/test_environment.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" @@ -468,6 +469,16 @@ func NewEnvironmentWithJobsAndContracts(t *testing.T, tc *TestConfigs, tEnv Test Config: PromoteAllCandidatesChangesetConfig{ HomeChainSelector: e.HomeChainSel, RemoteChainSelectors: allChains, + PluginType: types.PluginTypeCCIPCommit, + }, + }, + { + // Promote everything + Changeset: commonchangeset.WrapChangeSet(PromoteAllCandidatesChangeset), + Config: PromoteAllCandidatesChangesetConfig{ + HomeChainSelector: e.HomeChainSel, + RemoteChainSelectors: allChains, + PluginType: types.PluginTypeCCIPExec, }, }, { From 40023a38f25f7d141f5bd024386cf2cad692eaff Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 18 Dec 2024 16:19:24 -0800 Subject: [PATCH 4/4] revert --- deployment/ccip/changeset/cs_ccip_home.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deployment/ccip/changeset/cs_ccip_home.go b/deployment/ccip/changeset/cs_ccip_home.go index c981a616592..6dc47f7259e 100644 --- a/deployment/ccip/changeset/cs_ccip_home.go +++ b/deployment/ccip/changeset/cs_ccip_home.go @@ -143,13 +143,13 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment) } var donIDs []uint32 - for _, selector := range p.RemoteChainSelectors { - if err := deployment.IsValidChainSelector(selector); err != nil { + for _, chainSelector := range p.RemoteChainSelectors { + if err := deployment.IsValidChainSelector(chainSelector); err != nil { return nil, fmt.Errorf("don chain selector invalid: %w", err) } - chainState, exists := state.Chains[selector] + chainState, exists := state.Chains[chainSelector] if !exists { - return nil, fmt.Errorf("chain %d does not exist", selector) + return nil, fmt.Errorf("chain %d does not exist", chainSelector) } if chainState.OffRamp == nil { // should not be possible, but a defensive check. @@ -159,13 +159,13 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment) donID, err := internal.DonIDForChain( state.Chains[p.HomeChainSelector].CapabilityRegistry, state.Chains[p.HomeChainSelector].CCIPHome, - selector, + chainSelector, ) if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } if donID == 0 { - return nil, fmt.Errorf("don doesn't exist in CR for chain %d", selector) + return nil, fmt.Errorf("don doesn't exist in CR for chain %d", chainSelector) } // Check that candidate digest and active digest are not both zero - this is enforced onchain. pluginConfigs, err := state.Chains[p.HomeChainSelector].CCIPHome.GetAllConfigs(&bind.CallOpts{