Skip to content

Commit

Permalink
Extract MCMS
Browse files Browse the repository at this point in the history
  • Loading branch information
connorwstein committed Nov 18, 2024
1 parent 452a99e commit 946a725
Show file tree
Hide file tree
Showing 16 changed files with 633 additions and 323 deletions.
18 changes: 9 additions & 9 deletions deployment/ccip/changeset/active_candidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job"

ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip"
commondeploy "github.com/smartcontractkit/chainlink/deployment/common/changeset"

"github.com/smartcontractkit/chainlink/v2/core/logger"
)
Expand All @@ -43,7 +44,6 @@ func TestActiveCandidate(t *testing.T) {
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: tokenConfig,
MCMSConfig: ccdeploy.NewTestMCMSConfig(t, e),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
Expand Down Expand Up @@ -114,9 +114,9 @@ func TestActiveCandidate(t *testing.T) {
ccdeploy.TransferAllOwnership(t, state, homeCS, e)
acceptOwnershipProposal, err := ccdeploy.GenerateAcceptOwnershipProposal(state, homeCS, e.AllChainSelectors())
require.NoError(t, err)
acceptOwnershipExec := ccdeploy.SignProposal(t, e, acceptOwnershipProposal)
acceptOwnershipExec := commondeploy.SignProposal(t, e, acceptOwnershipProposal)
for _, sel := range e.AllChainSelectors() {
ccdeploy.ExecuteProposal(t, e, acceptOwnershipExec, state, sel)
commondeploy.ExecuteProposal(t, e, acceptOwnershipExec, state.Chains[sel].Timelock, sel)
}
// Apply the accept ownership proposal to all the chains.

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

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

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

// [NEW ACTIVE, NO CANDIDATE] check onchain state
Expand Down
8 changes: 4 additions & 4 deletions deployment/ccip/changeset/add_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip"
commondeployment "github.com/smartcontractkit/chainlink/deployment/common/changeset"

"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"

Expand Down Expand Up @@ -44,7 +45,6 @@ func TestAddChainInbound(t *testing.T) {
FeedChainSel: e.FeedChainSel,
ChainsToDeploy: initialDeploy,
TokenConfig: tokenConfig,
MCMSConfig: ccipdeployment.NewTestMCMSConfig(t, e.Env),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
Expand Down Expand Up @@ -74,7 +74,7 @@ func TestAddChainInbound(t *testing.T) {
ccipdeployment.FeeTokenContracts{
LinkToken: state.Chains[newChain].LinkToken,
Weth9: state.Chains[newChain].Weth9,
}, ccipdeployment.NewTestMCMSConfig(t, e.Env), rmnHome)
}, rmnHome)
require.NoError(t, err)
require.NoError(t, e.Env.ExistingAddresses.Merge(newChainAddresses))
state, err = ccipdeployment.LoadOnchainState(e.Env)
Expand Down Expand Up @@ -112,10 +112,10 @@ func TestAddChainInbound(t *testing.T) {

acceptOwnershipProposal, err := ccipdeployment.GenerateAcceptOwnershipProposal(state, e.HomeChainSel, initialDeploy)
require.NoError(t, err)
acceptOwnershipExec := ccipdeployment.SignProposal(t, e.Env, acceptOwnershipProposal)
acceptOwnershipExec := commondeployment.SignProposal(t, e.Env, acceptOwnershipProposal)
// Apply the accept ownership proposal to all the chains.
for _, sel := range initialDeploy {
ccipdeployment.ExecuteProposal(t, e.Env, acceptOwnershipExec, state, sel)
commondeployment.ExecuteProposal(t, e.Env, acceptOwnershipExec, state.Chains[sel].Timelock, sel)
}
for _, chain := range initialDeploy {
owner, err2 := state.Chains[chain].OnRamp.Owner(nil)
Expand Down
1 change: 0 additions & 1 deletion deployment/ccip/changeset/home_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ 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.
func DeployHomeChain(env deployment.Environment, cfg DeployHomeChainConfig) (deployment.ChangesetOutput, error) {

err := cfg.Validate()
if err != nil {
return deployment.ChangesetOutput{}, errors.Wrapf(deployment.ErrInvalidConfig, "%v", err)
Expand Down
2 changes: 1 addition & 1 deletion deployment/ccip/changeset/initial_deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

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

"github.com/smartcontractkit/chainlink/deployment"

ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip"
Expand Down Expand Up @@ -33,7 +34,6 @@ func TestInitialDeploy(t *testing.T) {
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds),
MCMSConfig: ccdeploy.NewTestMCMSConfig(t, e),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
Expand Down
126 changes: 9 additions & 117 deletions deployment/ccip/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/config"
owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers"

"github.com/smartcontractkit/chainlink-common/pkg/logger"

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/registry_module_owner_custom"
Expand Down Expand Up @@ -65,9 +62,6 @@ type DeployCCIPContractConfig struct {
FeedChainSel uint64
ChainsToDeploy []uint64
TokenConfig TokenConfig
// I believe it makes sense to have the same signers across all chains
// since that's the point MCMS.
MCMSConfig MCMSConfig
// For setting OCR configuration
OCRSecrets deployment.OCRSecrets
}
Expand Down Expand Up @@ -140,7 +134,7 @@ func DeployCCIPContracts(e deployment.Environment, ab deployment.AddressBook, c
err = DeployChainContracts(e, chain, ab, FeeTokenContracts{
LinkToken: existingState.Chains[chainSel].LinkToken,
Weth9: existingState.Chains[chainSel].Weth9,
}, c.MCMSConfig, rmnHome)
}, rmnHome)
if err != nil {
return err
}
Expand Down Expand Up @@ -189,113 +183,6 @@ func DeployCCIPContracts(e deployment.Environment, ab deployment.AddressBook, c
return nil
}

type MCMSConfig struct {
Admin config.Config
Canceller config.Config
Bypasser config.Config
Proposer config.Config
Executors []common.Address
}

func DeployMCMSWithConfig(
contractType deployment.ContractType,
lggr logger.Logger,
chain deployment.Chain,
ab deployment.AddressBook,
mcmConfig config.Config,
) (*deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig], error) {
groupQuorums, groupParents, signerAddresses, signerGroups := mcmConfig.ExtractSetConfigInputs()
mcm, err := deployment.DeployContract(lggr, chain, ab,
func(chain deployment.Chain) deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig] {
mcmAddr, tx, mcm, err2 := owner_helpers.DeployManyChainMultiSig(
chain.DeployerKey,
chain.Client,
)
return deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig]{
mcmAddr, mcm, tx, deployment.NewTypeAndVersion(contractType, deployment.Version1_0_0), err2,
}
})
if err != nil {
lggr.Errorw("Failed to deploy mcm", "err", err)
return mcm, err
}
mcmsTx, err := mcm.Contract.SetConfig(chain.DeployerKey,
signerAddresses,
signerGroups, // Signer 1 is int group 0 (root group) with quorum 1.
groupQuorums,
groupParents,
false,
)
if _, err := deployment.ConfirmIfNoError(chain, mcmsTx, err); err != nil {
lggr.Errorw("Failed to confirm mcm config", "err", err)
return mcm, err
}
return mcm, nil
}

type MCMSContracts struct {
Admin *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig]
Canceller *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig]
Bypasser *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig]
Proposer *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig]
Timelock *deployment.ContractDeploy[*owner_helpers.RBACTimelock]
}

// DeployMCMSContracts deploys the MCMS contracts for the given configuration
// as well as the timelock.
func DeployMCMSContracts(
lggr logger.Logger,
chain deployment.Chain,
ab deployment.AddressBook,
mcmConfig MCMSConfig,
) (*MCMSContracts, error) {
adminMCM, err := DeployMCMSWithConfig(AdminManyChainMultisig, lggr, chain, ab, mcmConfig.Admin)
if err != nil {
return nil, err
}
bypasser, err := DeployMCMSWithConfig(BypasserManyChainMultisig, lggr, chain, ab, mcmConfig.Bypasser)
if err != nil {
return nil, err
}
canceller, err := DeployMCMSWithConfig(CancellerManyChainMultisig, lggr, chain, ab, mcmConfig.Canceller)
if err != nil {
return nil, err
}
proposer, err := DeployMCMSWithConfig(ProposerManyChainMultisig, lggr, chain, ab, mcmConfig.Proposer)
if err != nil {
return nil, err
}

timelock, err := deployment.DeployContract(lggr, chain, ab,
func(chain deployment.Chain) deployment.ContractDeploy[*owner_helpers.RBACTimelock] {
timelock, tx2, cc, err2 := owner_helpers.DeployRBACTimelock(
chain.DeployerKey,
chain.Client,
big.NewInt(0), // minDelay
adminMCM.Address,
[]common.Address{proposer.Address}, // proposers
mcmConfig.Executors, //executors
[]common.Address{canceller.Address}, // cancellers
[]common.Address{bypasser.Address}, // bypassers
)
return deployment.ContractDeploy[*owner_helpers.RBACTimelock]{
timelock, cc, tx2, deployment.NewTypeAndVersion(RBACTimelock, deployment.Version1_0_0), err2,
}
})
if err != nil {
lggr.Errorw("Failed to deploy timelock", "err", err)
return nil, err
}
lggr.Infow("deployed timelock", "addr", timelock.Address)
return &MCMSContracts{
Admin: adminMCM,
Canceller: canceller,
Bypasser: bypasser,
Proposer: proposer,
Timelock: timelock,
}, nil
}

func DeployFeeTokensToChains(lggr logger.Logger, ab deployment.AddressBook, chains map[uint64]deployment.Chain) error {
for _, chain := range chains {
_, err := DeployFeeTokens(lggr, chain, ab)
Expand Down Expand Up @@ -360,11 +247,16 @@ func DeployChainContracts(
chain deployment.Chain,
ab deployment.AddressBook,
contractConfig FeeTokenContracts,
mcmsConfig MCMSConfig,
rmnHome *rmn_home.RMNHome,
) error {
mcmsContracts, err := DeployMCMSContracts(e.Logger, chain, ab, mcmsConfig)
chainAddresses, err := e.ExistingAddresses.AddressesForChain(chain.Selector)
if err != nil {
e.Logger.Errorw("Failed to get chain addresses", "err", err)
return err
}
state, err := LoadChainState(chain, chainAddresses)
if err != nil {
e.Logger.Errorw("Failed to load chain state", "err", err)
return err
}
ccipReceiver, err := deployment.DeployContract(e.Logger, chain, ab,
Expand Down Expand Up @@ -546,7 +438,7 @@ func DeployChainContracts(
LinkToken: contractConfig.LinkToken.Address(),
TokenPriceStalenessThreshold: uint32(24 * 60 * 60),
},
[]common.Address{mcmsContracts.Timelock.Address}, // timelock should be able to update, ramps added after
[]common.Address{state.Timelock.Address()}, // timelock should be able to update, ramps added after
[]common.Address{contractConfig.Weth9.Address(), contractConfig.LinkToken.Address()}, // fee tokens
[]fee_quoter.FeeQuoterTokenPriceFeedUpdate{},
[]fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, // TODO: tokens
Expand Down
1 change: 0 additions & 1 deletion deployment/ccip/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ func TestDeployCCIPContracts(t *testing.T) {
FeedChainSel: feedChainSel,
ChainsToDeploy: e.AllChainSelectors(),
TokenConfig: NewTokenConfig(),
MCMSConfig: NewTestMCMSConfig(t, e),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
Expand Down
Loading

0 comments on commit 946a725

Please sign in to comment.