-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Extract MCMS to deployment/common #15288
Changes from 13 commits
946a725
29843d8
683221a
190a457
a5c2f47
9ac5955
80619cd
cd981b8
dc9acfa
727b9e4
edf7c1a
f842de1
85377d4
c6918bf
20eab5e
be8bf61
99bec3c
0df43b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,9 +16,8 @@ import ( | |
|
||
"github.com/stretchr/testify/require" | ||
|
||
jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" | ||
|
||
ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" | ||
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" | ||
|
||
"github.com/smartcontractkit/chainlink/v2/core/logger" | ||
) | ||
|
@@ -27,47 +26,10 @@ func TestActiveCandidate(t *testing.T) { | |
t.Skipf("to be enabled after latest cl-ccip is compatible") | ||
|
||
lggr := logger.TestLogger(t) | ||
ctx := ccdeploy.Context(t) | ||
tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 5, ccdeploy.MockLinkPrice, ccdeploy.MockWethPrice) | ||
tenv := ccdeploy.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5) | ||
e := tenv.Env | ||
|
||
state, err := ccdeploy.LoadOnchainState(tenv.Env) | ||
require.NoError(t, err) | ||
require.NotNil(t, state.Chains[tenv.HomeChainSel].LinkToken) | ||
|
||
feeds := state.Chains[tenv.FeedChainSel].USDFeeds | ||
tokenConfig := ccdeploy.NewTestTokenConfig(feeds) | ||
|
||
output, err := InitialDeploy(tenv.Env, ccdeploy.DeployCCIPContractConfig{ | ||
HomeChainSel: tenv.HomeChainSel, | ||
FeedChainSel: tenv.FeedChainSel, | ||
ChainsToDeploy: tenv.Env.AllChainSelectors(), | ||
TokenConfig: tokenConfig, | ||
MCMSConfig: ccdeploy.NewTestMCMSConfig(t, e), | ||
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), | ||
}) | ||
require.NoError(t, err) | ||
// Get new state after migration. | ||
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook)) | ||
state, err = ccdeploy.LoadOnchainState(tenv.Env) | ||
require.NoError(t, err) | ||
homeCS, destCS := tenv.HomeChainSel, tenv.FeedChainSel | ||
|
||
// 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)) | ||
|
@@ -111,23 +73,23 @@ func TestActiveCandidate(t *testing.T) { | |
ccdeploy.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) | ||
|
||
// transfer ownership | ||
ccdeploy.TransferAllOwnership(t, state, homeCS, e) | ||
acceptOwnershipProposal, err := ccdeploy.GenerateAcceptOwnershipProposal(state, homeCS, e.AllChainSelectors()) | ||
ccdeploy.TransferAllOwnership(t, state, tenv.HomeChainSel, e) | ||
acceptOwnershipProposal, err := ccdeploy.GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors()) | ||
require.NoError(t, err) | ||
acceptOwnershipExec := ccdeploy.SignProposal(t, e, acceptOwnershipProposal) | ||
acceptOwnershipExec := commonchangeset.SignProposal(t, e, acceptOwnershipProposal) | ||
for _, sel := range e.AllChainSelectors() { | ||
ccdeploy.ExecuteProposal(t, e, acceptOwnershipExec, state, sel) | ||
commonchangeset.ExecuteProposal(t, e, acceptOwnershipExec, state.Chains[sel].Timelock, sel) | ||
} | ||
// Apply the accept ownership proposal to all the chains. | ||
|
||
err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, homeCS, destCS, 2) | ||
err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 2) | ||
require.NoError(t, err) | ||
|
||
// [ACTIVE, CANDIDATE] setup by setting candidate through cap reg | ||
capReg, ccipHome := state.Chains[homeCS].CapabilityRegistry, state.Chains[homeCS].CCIPHome | ||
donID, err := ccdeploy.DonIDForChain(capReg, ccipHome, destCS) | ||
capReg, ccipHome := state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome | ||
donID, err := ccdeploy.DonIDForChain(capReg, ccipHome, tenv.FeedChainSel) | ||
require.NoError(t, err) | ||
donInfo, err := state.Chains[homeCS].CapabilityRegistry.GetDON(nil, donID) | ||
donInfo, err := state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) | ||
require.NoError(t, err) | ||
require.Equal(t, 5, len(donInfo.NodeP2PIds)) | ||
require.Equal(t, uint32(4), donInfo.ConfigCount) | ||
|
@@ -151,13 +113,14 @@ func TestActiveCandidate(t *testing.T) { | |
|
||
// this will construct ocr3 configurations for the | ||
// commit and exec plugin we will be using | ||
rmnHomeAddress := state.Chains[homeCS].RMNHome.Address() | ||
rmnHomeAddress := state.Chains[tenv.HomeChainSel].RMNHome.Address() | ||
tokenConfig := ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) | ||
ocr3ConfigMap, err := ccdeploy.BuildOCR3ConfigForCCIPHome( | ||
deployment.XXXGenerateTestOCRSecrets(), | ||
state.Chains[destCS].OffRamp, | ||
e.Chains[destCS], | ||
destCS, | ||
tokenConfig.GetTokenInfo(e.Logger, state.Chains[destCS].LinkToken, state.Chains[destCS].Weth9), | ||
state.Chains[tenv.FeedChainSel].OffRamp, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why feedChainSel instead of destCS? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. destCS was feedChainSel |
||
e.Chains[tenv.FeedChainSel], | ||
tenv.FeedChainSel, | ||
tokenConfig.GetTokenInfo(e.Logger, state.Chains[tenv.FeedChainSel].LinkToken, state.Chains[tenv.FeedChainSel].Weth9), | ||
nodes.NonBootstraps(), | ||
rmnHomeAddress, | ||
nil, | ||
|
@@ -166,82 +129,82 @@ func TestActiveCandidate(t *testing.T) { | |
|
||
setCommitCandidateOp, err := ccdeploy.SetCandidateOnExistingDon( | ||
ocr3ConfigMap[cctypes.PluginTypeCCIPCommit], | ||
state.Chains[homeCS].CapabilityRegistry, | ||
state.Chains[homeCS].CCIPHome, | ||
destCS, | ||
state.Chains[tenv.HomeChainSel].CapabilityRegistry, | ||
state.Chains[tenv.HomeChainSel].CCIPHome, | ||
tenv.FeedChainSel, | ||
nodes.NonBootstraps(), | ||
) | ||
require.NoError(t, err) | ||
setCommitCandidateProposal, err := ccdeploy.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ | ||
ChainIdentifier: mcms.ChainIdentifier(homeCS), | ||
ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), | ||
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 := commonchangeset.SignProposal(t, e, setCommitCandidateProposal) | ||
commonchangeset.ExecuteProposal(t, e, setCommitCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) | ||
|
||
// create the op for the commit plugin as well | ||
setExecCandidateOp, err := ccdeploy.SetCandidateOnExistingDon( | ||
ocr3ConfigMap[cctypes.PluginTypeCCIPExec], | ||
state.Chains[homeCS].CapabilityRegistry, | ||
state.Chains[homeCS].CCIPHome, | ||
destCS, | ||
state.Chains[tenv.HomeChainSel].CapabilityRegistry, | ||
state.Chains[tenv.HomeChainSel].CCIPHome, | ||
tenv.FeedChainSel, | ||
nodes.NonBootstraps(), | ||
) | ||
require.NoError(t, err) | ||
|
||
setExecCandidateProposal, err := ccdeploy.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ | ||
ChainIdentifier: mcms.ChainIdentifier(homeCS), | ||
ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), | ||
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 := commonchangeset.SignProposal(t, e, setExecCandidateProposal) | ||
commonchangeset.ExecuteProposal(t, 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[homeCS].CapabilityRegistry.GetDON(nil, donID) | ||
donInfo, err = state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) | ||
require.NoError(t, err) | ||
require.Equal(t, 4, len(donInfo.NodeP2PIds)) | ||
require.Equal(t, uint32(6), donInfo.ConfigCount) | ||
// [ACTIVE, CANDIDATE] done setup | ||
|
||
// [ACTIVE, CANDIDATE] make sure we can still send successful transaction without updating job specs | ||
err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, homeCS, destCS, 3) | ||
err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 3) | ||
require.NoError(t, err) | ||
// [ACTIVE, CANDIDATE] done send successful transaction on active | ||
|
||
// [NEW ACTIVE, NO CANDIDATE] promote to active | ||
// confirm by getting old candidate digest and making sure new active matches | ||
oldCandidateDigest, err := state.Chains[homeCS].CCIPHome.GetCandidateDigest(nil, donID, uint8(cctypes.PluginTypeCCIPExec)) | ||
oldCandidateDigest, err := state.Chains[tenv.HomeChainSel].CCIPHome.GetCandidateDigest(nil, donID, uint8(cctypes.PluginTypeCCIPExec)) | ||
require.NoError(t, err) | ||
|
||
promoteOps, err := ccdeploy.PromoteAllCandidatesForChainOps(state.Chains[homeCS].CapabilityRegistry, state.Chains[homeCS].CCIPHome, destCS, nodes.NonBootstraps()) | ||
promoteOps, err := ccdeploy.PromoteAllCandidatesForChainOps(state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome, tenv.FeedChainSel, nodes.NonBootstraps()) | ||
require.NoError(t, err) | ||
promoteProposal, err := ccdeploy.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ | ||
ChainIdentifier: mcms.ChainIdentifier(homeCS), | ||
ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), | ||
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 := commonchangeset.SignProposal(t, e, promoteProposal) | ||
commonchangeset.ExecuteProposal(t, e, promoteSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) | ||
// [NEW ACTIVE, NO CANDIDATE] done promoting | ||
|
||
// [NEW ACTIVE, NO CANDIDATE] check onchain state | ||
newActiveDigest, err := state.Chains[homeCS].CCIPHome.GetActiveDigest(nil, donID, uint8(cctypes.PluginTypeCCIPExec)) | ||
newActiveDigest, err := state.Chains[tenv.HomeChainSel].CCIPHome.GetActiveDigest(nil, donID, uint8(cctypes.PluginTypeCCIPExec)) | ||
require.NoError(t, err) | ||
require.Equal(t, oldCandidateDigest, newActiveDigest) | ||
|
||
newCandidateDigest, err := state.Chains[homeCS].CCIPHome.GetCandidateDigest(nil, donID, uint8(cctypes.PluginTypeCCIPCommit)) | ||
newCandidateDigest, err := state.Chains[tenv.HomeChainSel].CCIPHome.GetCandidateDigest(nil, donID, uint8(cctypes.PluginTypeCCIPCommit)) | ||
require.NoError(t, err) | ||
require.Equal(t, newCandidateDigest, [32]byte{}) | ||
// [NEW ACTIVE, NO CANDIDATE] done checking on chain state | ||
|
||
// [NEW ACTIVE, NO CANDIDATE] send successful request on new active | ||
donInfo, err = state.Chains[homeCS].CapabilityRegistry.GetDON(nil, donID) | ||
donInfo, err = state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) | ||
require.NoError(t, err) | ||
require.Equal(t, uint32(8), donInfo.ConfigCount) | ||
|
||
err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, homeCS, destCS, 4) | ||
err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 4) | ||
require.NoError(t, err) | ||
// [NEW ACTIVE, NO CANDIDATE] done sending successful request | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
package changeset | ||
|
||
import ( | ||
"math/big" | ||
"testing" | ||
"time" | ||
|
||
ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" | ||
|
||
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" | ||
commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" | ||
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
|
@@ -41,14 +43,27 @@ func TestAddChainInbound(t *testing.T) { | |
require.NoError(t, err) | ||
require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) | ||
|
||
tokenConfig := ccipdeployment.NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) | ||
cfg := commontypes.MCMSWithTimelockConfig{ | ||
Canceller: commonchangeset.SingleGroupMCMS(t), | ||
Bypasser: commonchangeset.SingleGroupMCMS(t), | ||
Proposer: commonchangeset.SingleGroupMCMS(t), | ||
TimelockExecutors: e.Env.AllDeployerKeys(), | ||
TimelockMinDelay: big.NewInt(0), | ||
} | ||
out, err := commonchangeset.DeployMCMSWithTimelock(e.Env, map[uint64]commontypes.MCMSWithTimelockConfig{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thats the internal impl |
||
initialDeploy[0]: cfg, | ||
initialDeploy[1]: cfg, | ||
initialDeploy[2]: cfg, | ||
}) | ||
require.NoError(t, err) | ||
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{ | ||
HomeChainSel: e.HomeChainSel, | ||
FeedChainSel: e.FeedChainSel, | ||
ChainsToDeploy: initialDeploy, | ||
TokenConfig: tokenConfig, | ||
MCMSConfig: ccipdeployment.NewTestMCMSConfig(t, e.Env), | ||
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), | ||
}) | ||
require.NoError(t, err) | ||
|
@@ -72,14 +87,19 @@ func TestAddChainInbound(t *testing.T) { | |
require.NoError(t, err) | ||
|
||
// Deploy contracts to new chain | ||
out, err = commonchangeset.DeployMCMSWithTimelock(e.Env, map[uint64]commontypes.MCMSWithTimelockConfig{ | ||
newChain: cfg, | ||
}) | ||
require.NoError(t, err) | ||
require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) | ||
|
||
newAddresses = deployment.NewMemoryAddressBook() | ||
err = ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, []uint64{newChain}) | ||
require.NoError(t, err) | ||
require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) | ||
newAddresses = deployment.NewMemoryAddressBook() | ||
err = ccipdeployment.DeployChainContracts(e.Env, | ||
e.Env.Chains[newChain], newAddresses, | ||
ccipdeployment.NewTestMCMSConfig(t, e.Env), rmnHome) | ||
e.Env.Chains[newChain], newAddresses, rmnHome) | ||
require.NoError(t, err) | ||
require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) | ||
state, err = ccipdeployment.LoadOnchainState(e.Env) | ||
|
@@ -117,10 +137,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 := commonchangeset.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) | ||
commonchangeset.ExecuteProposal(t, e.Env, acceptOwnershipExec, state.Chains[sel].Timelock, sel) | ||
} | ||
for _, chain := range initialDeploy { | ||
owner, err2 := state.Chains[chain].OnRamp.Owner(nil) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,16 @@ | ||
package changeset | ||
|
||
import ( | ||
"math/big" | ||
"testing" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
|
||
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" | ||
|
||
"github.com/smartcontractkit/chainlink/deployment" | ||
ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" | ||
|
||
|
@@ -32,12 +36,25 @@ func TestInitialDeploy(t *testing.T) { | |
require.NoError(t, err) | ||
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook)) | ||
|
||
cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's the reason for not using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in this case we want to actually test the last step in NewMemoryEnvironmentWithJobsAndContracts |
||
for _, chain := range e.AllChainSelectors() { | ||
cfg[chain] = commontypes.MCMSWithTimelockConfig{ | ||
Canceller: commonchangeset.SingleGroupMCMS(t), | ||
Bypasser: commonchangeset.SingleGroupMCMS(t), | ||
Proposer: commonchangeset.SingleGroupMCMS(t), | ||
TimelockExecutors: e.AllDeployerKeys(), | ||
TimelockMinDelay: big.NewInt(0), | ||
} | ||
} | ||
output, err = commonchangeset.DeployMCMSWithTimelock(e, cfg) | ||
require.NoError(t, err) | ||
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) | ||
|
||
output, err = InitialDeploy(tenv.Env, ccdeploy.DeployCCIPContractConfig{ | ||
HomeChainSel: tenv.HomeChainSel, | ||
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) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As there is now 3 changesets (prereqs, mcms + ccip contracts) you need to get a full system I just created a helper