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

CCIP-4158 Initial AddChain changeset #15319

Closed
wants to merge 7 commits into from
Closed
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
21 changes: 13 additions & 8 deletions deployment/ccip/changeset/active_candidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,11 @@ func TestActiveCandidate(t *testing.T) {
ccdeploy.TransferAllOwnership(t, state, tenv.HomeChainSel, e)
acceptOwnershipProposal, err := ccdeploy.GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors())
require.NoError(t, err)
acceptOwnershipExec := commonchangeset.SignProposal(t, e, acceptOwnershipProposal)
acceptOwnershipExec, err := commonchangeset.SignProposal(e, acceptOwnershipProposal)
require.NoError(t, err)
for _, sel := range e.AllChainSelectors() {
commonchangeset.ExecuteProposal(t, e, acceptOwnershipExec, state.Chains[sel].Timelock, sel)
err = commonchangeset.ExecuteProposal(e, acceptOwnershipExec, state.Chains[sel].Timelock, sel)
require.NoError(t, err)
}
// Apply the accept ownership proposal to all the chains.

Expand Down Expand Up @@ -140,8 +142,9 @@ func TestActiveCandidate(t *testing.T) {
Batch: setCommitCandidateOp,
}}, "set new candidates on commit plugin", 0)
require.NoError(t, err)
setCommitCandidateSigned := commonchangeset.SignProposal(t, e, setCommitCandidateProposal)
commonchangeset.ExecuteProposal(t, e, setCommitCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel)
setCommitCandidateSigned, err := commonchangeset.SignProposal(e, setCommitCandidateProposal)
require.NoError(t, err)
require.NoError(t, commonchangeset.ExecuteProposal(e, setCommitCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel))

// create the op for the commit plugin as well
setExecCandidateOp, err := ccdeploy.SetCandidateOnExistingDon(
Expand All @@ -158,8 +161,9 @@ func TestActiveCandidate(t *testing.T) {
Batch: setExecCandidateOp,
}}, "set new candidates on commit and exec plugins", 0)
require.NoError(t, err)
setExecCandidateSigned := commonchangeset.SignProposal(t, e, setExecCandidateProposal)
commonchangeset.ExecuteProposal(t, e, setExecCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel)
setExecCandidateSigned, err := commonchangeset.SignProposal(e, setExecCandidateProposal)
require.NoError(t, err)
require.NoError(t, commonchangeset.ExecuteProposal(e, setExecCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel))

// check setup was successful by confirming number of nodes from cap reg
donInfo, err = state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID)
Expand All @@ -185,8 +189,9 @@ func TestActiveCandidate(t *testing.T) {
Batch: promoteOps,
}}, "promote candidates and revoke actives", 0)
require.NoError(t, err)
promoteSigned := commonchangeset.SignProposal(t, e, promoteProposal)
commonchangeset.ExecuteProposal(t, e, promoteSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel)
promoteSigned, err := commonchangeset.SignProposal(e, promoteProposal)
require.NoError(t, err)
require.NoError(t, commonchangeset.ExecuteProposal(e, promoteSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel))
// [NEW ACTIVE, NO CANDIDATE] done promoting

// [NEW ACTIVE, NO CANDIDATE] check onchain state
Expand Down
19 changes: 10 additions & 9 deletions deployment/ccip/changeset/add_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestAddChainInbound(t *testing.T) {
// We deploy to the rest.
initialDeploy := e.Env.AllChainSelectorsExcluding([]uint64{newChain})
newAddresses := deployment.NewMemoryAddressBook()
err = ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy)
err = ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy, nil)
require.NoError(t, err)
require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses))

Expand All @@ -59,7 +59,7 @@ func TestAddChainInbound(t *testing.T) {
require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook))
newAddresses = deployment.NewMemoryAddressBook()
tokenConfig := ccipdeployment.NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds)
err = ccipdeployment.DeployCCIPContracts(e.Env, newAddresses, ccipdeployment.DeployCCIPContractConfig{
err = ccipdeployment.DeployCCIPContracts(e.Env, newAddresses, ccipdeployment.InitialAddChainConfig{
HomeChainSel: e.HomeChainSel,
FeedChainSel: e.FeedChainSel,
ChainsToDeploy: initialDeploy,
Expand Down Expand Up @@ -94,7 +94,7 @@ func TestAddChainInbound(t *testing.T) {
require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook))

newAddresses = deployment.NewMemoryAddressBook()
err = ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, []uint64{newChain})
err = ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, []uint64{newChain}, nil)
require.NoError(t, err)
require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses))
newAddresses = deployment.NewMemoryAddressBook()
Expand Down Expand Up @@ -137,10 +137,11 @@ func TestAddChainInbound(t *testing.T) {

acceptOwnershipProposal, err := ccipdeployment.GenerateAcceptOwnershipProposal(state, e.HomeChainSel, initialDeploy)
require.NoError(t, err)
acceptOwnershipExec := commonchangeset.SignProposal(t, e.Env, acceptOwnershipProposal)
acceptOwnershipExec, err := commonchangeset.SignProposal(e.Env, acceptOwnershipProposal)
require.NoError(t, err)
// Apply the accept ownership proposal to all the chains.
for _, sel := range initialDeploy {
commonchangeset.ExecuteProposal(t, e.Env, acceptOwnershipExec, state.Chains[sel].Timelock, sel)
require.NoError(t, commonchangeset.ExecuteProposal(e.Env, acceptOwnershipExec, state.Chains[sel].Timelock, sel))
}
for _, chain := range initialDeploy {
owner, err2 := state.Chains[chain].OnRamp.Owner(nil)
Expand All @@ -160,7 +161,7 @@ func TestAddChainInbound(t *testing.T) {
// Generate and sign inbound proposal to new 4th chain.
chainInboundChangeset, err := NewChainInboundChangeset(e.Env, state, e.HomeChainSel, newChain, initialDeploy)
require.NoError(t, err)
ccipdeployment.ProcessChangeset(t, e.Env, chainInboundChangeset)
require.NoError(t, ccipdeployment.ProcessChangeset(e.Env, chainInboundChangeset))

// 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
Expand All @@ -169,17 +170,17 @@ func TestAddChainInbound(t *testing.T) {
t.Logf("Executing add don and set candidate proposal for commit plugin on chain %d", newChain)
addDonChangeset, err := AddDonAndSetCandidateChangeset(state, e.Env, nodes, deployment.XXXGenerateTestOCRSecrets(), e.HomeChainSel, e.FeedChainSel, newChain, tokenConfig, types.PluginTypeCCIPCommit)
require.NoError(t, err)
ccipdeployment.ProcessChangeset(t, e.Env, addDonChangeset)
require.NoError(t, ccipdeployment.ProcessChangeset(e.Env, addDonChangeset))

t.Logf("Executing promote candidate proposal for exec plugin on chain %d", newChain)
setCandidateForExecChangeset, err := SetCandidatePluginChangeset(state, e.Env, nodes, deployment.XXXGenerateTestOCRSecrets(), e.HomeChainSel, e.FeedChainSel, newChain, tokenConfig, types.PluginTypeCCIPExec)
require.NoError(t, err)
ccipdeployment.ProcessChangeset(t, e.Env, setCandidateForExecChangeset)
require.NoError(t, ccipdeployment.ProcessChangeset(e.Env, setCandidateForExecChangeset))

t.Logf("Executing promote candidate proposal for both commit and exec plugins on chain %d", newChain)
donPromoteChangeset, err := PromoteAllCandidatesChangeset(state, e.HomeChainSel, newChain, nodes)
require.NoError(t, err)
ccipdeployment.ProcessChangeset(t, e.Env, donPromoteChangeset)
require.NoError(t, ccipdeployment.ProcessChangeset(e.Env, donPromoteChangeset))

// verify if the configs are updated
require.NoError(t, ccipdeployment.ValidateCCIPHomeConfigSetUp(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import (

"github.com/ethereum/go-ethereum/common"

<<<<<<< HEAD:deployment/ccip/changeset/composite_changeset_apply_test.go
=======
jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job"

commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset"
commontypes "github.com/smartcontractkit/chainlink/deployment/common/types"

>>>>>>> b2de0542a6dd1e50ffc3b15b7c16fef4dd059a8f:deployment/ccip/changeset/initial_deploy_test.go
"github.com/smartcontractkit/chainlink/deployment"
ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip"

Expand All @@ -30,10 +33,41 @@ func TestInitialDeploy(t *testing.T) {

state, err := ccdeploy.LoadOnchainState(tenv.Env)
require.NoError(t, err)
output, err := DeployPrerequisites(e, DeployPrerequisiteConfig{
ChainSelectors: tenv.Env.AllChainSelectors(),
})
mcmsCfg := ccdeploy.NewTestMCMSConfig(t, e)
changesets := []deployment.ChangesetApplication{
{
Changeset: deployment.WrapChangeSet(DeployPrerequisites),
Config: DeployPrerequisiteConfig{
ChainSelectors: tenv.Env.AllChainSelectors(),
},
},
{
Changeset: deployment.WrapChangeSet(DeployChainContracts),
Config: DeployChainContractsConfig{
ChainSelectors: tenv.Env.AllChainSelectors(),
HomeChainSelector: tenv.HomeChainSel,
MCMSCfg: mcmsCfg,
},
},
{
Changeset: deployment.WrapChangeSet(InitialAddChain),
Config: ccdeploy.InitialAddChainConfig{
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds),
MCMSConfig: mcmsCfg,
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
},
},
{
Changeset: deployment.WrapChangeSet(CCIPCapabilityJobspec),
},
}
tenv.Env, err = ccdeploy.ApplyChangesets(ctx, tenv.Env, changesets)
require.NoError(t, err)
<<<<<<< HEAD:deployment/ccip/changeset/composite_changeset_apply_test.go
=======
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook))

cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
Expand All @@ -60,25 +94,12 @@ func TestInitialDeploy(t *testing.T) {
require.NoError(t, err)
// Get new state after migration.
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook))
>>>>>>> b2de0542a6dd1e50ffc3b15b7c16fef4dd059a8f:deployment/ccip/changeset/initial_deploy_test.go
state, err = ccdeploy.LoadOnchainState(e)
require.NoError(t, err)
require.NotNil(t, state.Chains[tenv.HomeChainSel].LinkToken)
// Ensure capreg logs are up to date.
ccdeploy.ReplayLogs(t, e.Offchain, tenv.ReplayBlocks)

// Apply the jobs.
for nodeID, jobs := range output.JobSpecs {
for _, job := range jobs {
// Note these auto-accept
_, err := e.Offchain.ProposeJob(ctx,
&jobv1.ProposeJobRequest{
NodeId: nodeID,
Spec: job,
})
require.NoError(t, err)
}
}

// Add all lanes
require.NoError(t, ccdeploy.AddLanesForAll(e, state))
// Need to keep track of the block number for each chain so that event subscription can be done from that block.
Expand Down
5 changes: 5 additions & 0 deletions deployment/ccip/changeset/deploy_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import (

var _ deployment.ChangeSet[DeployChainContractsConfig] = DeployChainContracts

// DeployChainContracts deploys all new CCIP v1.6 or later contracts for the given chains.
// It returns the new addresses for the contracts.
// If there is an error, it will return the successfully deployed addresses and the error so that the caller can call the
// changeset again with the same input to retry the failed deployment.
// Caller should update the environment's address book with the returned addresses.
func DeployChainContracts(env deployment.Environment, c DeployChainContractsConfig) (deployment.ChangesetOutput, error) {
newAddresses := deployment.NewMemoryAddressBook()
err := ccipdeployment.DeployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors)
Expand Down
1 change: 1 addition & 0 deletions deployment/ccip/changeset/home_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
var _ deployment.ChangeSet[DeployHomeChainConfig] = DeployHomeChain

// DeployHomeChain is a separate changeset because it is a standalone deployment performed once in home chain for the entire CCIP deployment.
// Caller should update the environment's address book with the returned addresses.
func DeployHomeChain(env deployment.Environment, cfg DeployHomeChainConfig) (deployment.ChangesetOutput, error) {
err := cfg.Validate()
if err != nil {
Expand Down
34 changes: 34 additions & 0 deletions deployment/ccip/changeset/initial_add_chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package changeset

import (
"fmt"

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

"github.com/smartcontractkit/chainlink/deployment"
ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip"
)

var InitialAddChainCS deployment.ChangeSet[ccipdeployment.InitialAddChainConfig] = InitialAddChain

// InitialAddChain enables new chains as destination for CCIP
// It performs the following steps:
// - AddChainConfig + AddDON (candidate->primary promotion i.e. init) on the home chain
// - SetOCR3Config on the remote chain
// InitialAddChain assumes that the home chain is already enabled and all CCIP contracts are already deployed.
func InitialAddChain(env deployment.Environment, c ccipdeployment.InitialAddChainConfig) (deployment.ChangesetOutput, error) {
if err := c.Validate(); err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("invalid InitialAddChainConfig: %w", err)
}
newAddresses := deployment.NewMemoryAddressBook()
err := ccipdeployment.InitialAddChain(env, newAddresses, c)
if err != nil {
env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "newAddresses", newAddresses)
return deployment.ChangesetOutput{AddressBook: newAddresses}, deployment.MaybeDataErr(err)
}
return deployment.ChangesetOutput{
Proposals: []timelock.MCMSWithTimelockProposal{},
AddressBook: newAddresses,
JobSpecs: nil,
}, nil
}
30 changes: 0 additions & 30 deletions deployment/ccip/changeset/initial_deploy.go

This file was deleted.

4 changes: 3 additions & 1 deletion deployment/ccip/changeset/jobspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (
ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip"
)

func Jobspec(env deployment.Environment, _ any) (deployment.ChangesetOutput, error) {
// CCIPCapabilityJobspec returns the job specs for the CCIP capability.
// The caller needs to propose these job specs to the offchain system.
func CCIPCapabilityJobspec(env deployment.Environment, _ any) (deployment.ChangesetOutput, error) {
js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain)
if err != nil {
return deployment.ChangesetOutput{}, errors.Wrapf(err, "failed to create job specs")
Expand Down
2 changes: 1 addition & 1 deletion deployment/ccip/changeset/jobspec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestJobSpecChangeset(t *testing.T) {
Chains: 1,
Nodes: 4,
})
output, err := Jobspec(e, nil)
output, err := CCIPCapabilityJobspec(e, nil)
require.NoError(t, err)
require.NotNil(t, output.JobSpecs)
nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain)
Expand Down
12 changes: 10 additions & 2 deletions deployment/ccip/changeset/prerequisites.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ var (

// DeployPrerequisites deploys the pre-requisite contracts for CCIP
// pre-requisite contracts are the contracts which can be reused from previous versions of CCIP
// Or the contracts which are already deployed on the chain ( for example, tokens, feeds, etc)
// Caller should update the environment's address book with the returned addresses.
func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfig) (deployment.ChangesetOutput, error) {
err := cfg.Validate()
if err != nil {
return deployment.ChangesetOutput{}, errors.Wrapf(deployment.ErrInvalidConfig, "%v", err)
}
ab := deployment.NewMemoryAddressBook()
err = ccipdeployment.DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors)
err = ccipdeployment.DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors, cfg.USDCEnabledChainSelectors)
if err != nil {
env.Logger.Errorw("Failed to deploy prerequisite contracts", "err", err, "addressBook", ab)
return deployment.ChangesetOutput{
Expand All @@ -38,7 +40,8 @@ func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfi
}

type DeployPrerequisiteConfig struct {
ChainSelectors []uint64
ChainSelectors []uint64
USDCEnabledChainSelectors []uint64
// TODO handle tokens and feeds in prerequisite config
Tokens map[ccipdeployment.TokenSymbol]common.Address
Feeds map[ccipdeployment.TokenSymbol]common.Address
Expand All @@ -50,5 +53,10 @@ func (c DeployPrerequisiteConfig) Validate() error {
return fmt.Errorf("invalid chain selector: %d - %w", cs, err)
}
}
for _, cs := range c.USDCEnabledChainSelectors {
if err := deployment.IsValidChainSelector(cs); err != nil {
return fmt.Errorf("invalid chain selector: %d - %w", cs, err)
}
}
return nil
}
2 changes: 2 additions & 0 deletions deployment/ccip/changeset/save_existing.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func (cfg ExistingContractsConfig) Validate() error {
return nil
}

// SaveExistingContracts saves the existing contracts to the address book.
// Caller should update the environment's address book with the returned addresses.
func SaveExistingContracts(env deployment.Environment, cfg ExistingContractsConfig) (deployment.ChangesetOutput, error) {
err := cfg.Validate()
if err != nil {
Expand Down
Loading