Skip to content

Commit

Permalink
Add ccip/changeset/internal (#15334)
Browse files Browse the repository at this point in the history
* Move files

* Move more files

* Move the rest

* Move some files to internal

* Get building

* Move a bunch of home chain stuff to internal

* Update README

* Fix integration tests

* More merge conflicts

* More merge conflicts
  • Loading branch information
connorwstein authored Nov 20, 2024
1 parent 1f44f3c commit 789d021
Show file tree
Hide file tree
Showing 39 changed files with 825 additions and 826 deletions.
8 changes: 5 additions & 3 deletions deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ TODO: Add various examples in deployment/example.
contracts (like MCMS, LinkToken etc) which can be shared
by products.

/deployment/<product>
- package name `<product>deployment`
/deployment/<product>/internal
- Internal building blocks for changesets
- TODO: can we make this `internal`?

/deployment/<product>/view
- Hold readonly mappings Go bindings to json marshallable objects.
- Used to generate a view of the system.

/deployment/<product>/changeset
- Think of this as the public API for deployment and configuration
Expand Down
19 changes: 10 additions & 9 deletions deployment/ccip/changeset/active_candidate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ package changeset

import (
"fmt"

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

"github.com/smartcontractkit/chainlink/deployment"
ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip"
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal"
cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"
)

// PromoteAllCandidatesChangeset generates a proposal to call promoteCandidate on the CCIPHome through CapReg.
// This needs to be called after SetCandidateProposal is executed.
func PromoteAllCandidatesChangeset(
state ccdeploy.CCIPOnChainState,
state CCIPOnChainState,
homeChainSel, newChainSel uint64,
nodes deployment.Nodes,
) (deployment.ChangesetOutput, error) {
promoteCandidateOps, err := ccdeploy.PromoteAllCandidatesForChainOps(
promoteCandidateOps, err := PromoteAllCandidatesForChainOps(
state.Chains[homeChainSel].CapabilityRegistry,
state.Chains[homeChainSel].CCIPHome,
newChainSel,
Expand All @@ -27,7 +28,7 @@ func PromoteAllCandidatesChangeset(
return deployment.ChangesetOutput{}, err
}

prop, err := ccdeploy.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
prop, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
ChainIdentifier: mcms.ChainIdentifier(homeChainSel),
Batch: promoteCandidateOps,
}}, "promoteCandidate for commit and execution", 0)
Expand All @@ -43,15 +44,15 @@ func PromoteAllCandidatesChangeset(

// SetCandidateExecPluginProposal calls setCandidate on the CCIPHome for setting up OCR3 exec Plugin config for the new chain.
func SetCandidatePluginChangeset(
state ccdeploy.CCIPOnChainState,
state CCIPOnChainState,
e deployment.Environment,
nodes deployment.Nodes,
ocrSecrets deployment.OCRSecrets,
homeChainSel, feedChainSel, newChainSel uint64,
tokenConfig ccdeploy.TokenConfig,
tokenConfig TokenConfig,
pluginType cctypes.PluginType,
) (deployment.ChangesetOutput, error) {
newDONArgs, err := ccdeploy.BuildOCR3ConfigForCCIPHome(
newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome(
ocrSecrets,
state.Chains[newChainSel].OffRamp,
e.Chains[newChainSel],
Expand All @@ -70,7 +71,7 @@ func SetCandidatePluginChangeset(
return deployment.ChangesetOutput{}, fmt.Errorf("missing exec plugin in ocr3Configs")
}

setCandidateMCMSOps, err := ccdeploy.SetCandidateOnExistingDon(
setCandidateMCMSOps, err := SetCandidateOnExistingDon(
execConfig,
state.Chains[homeChainSel].CapabilityRegistry,
state.Chains[homeChainSel].CCIPHome,
Expand All @@ -81,7 +82,7 @@ func SetCandidatePluginChangeset(
return deployment.ChangesetOutput{}, err
}

prop, err := ccdeploy.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
prop, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
ChainIdentifier: mcms.ChainIdentifier(homeChainSel),
Batch: setCandidateMCMSOps,
}}, "SetCandidate for execution", 0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package ccipdeployment
package changeset

import (
"fmt"
"math/big"

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

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal"
cctypes "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"
"math/big"
)

// SetCandidateExecPluginOps calls setCandidate on CCIPHome contract through the UpdateDON call on CapReg contract
Expand All @@ -20,12 +23,12 @@ func SetCandidateOnExistingDon(
nodes deployment.Nodes,
) ([]mcms.Operation, error) {
// fetch DON ID for the chain
donID, err := DonIDForChain(capReg, ccipHome, chainSelector)
donID, err := internal.DonIDForChain(capReg, ccipHome, chainSelector)
if err != nil {
return nil, fmt.Errorf("fetch don id for chain: %w", err)
}
fmt.Printf("donID: %d", donID)
encodedSetCandidateCall, err := CCIPHomeABI.Pack(
encodedSetCandidateCall, err := internal.CCIPHomeABI.Pack(
"setCandidate",
donID,
pluginConfig.PluginType,
Expand All @@ -43,7 +46,7 @@ func SetCandidateOnExistingDon(
nodes.PeerIDs(),
[]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{
{
CapabilityId: CCIPCapabilityID,
CapabilityId: internal.CCIPCapabilityID,
Config: encodedSetCandidateCall,
},
},
Expand Down Expand Up @@ -75,7 +78,7 @@ func PromoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg
}
fmt.Printf("commit candidate digest after setCandidate: %x\n", allConfigs.CandidateConfig.ConfigDigest)

encodedPromotionCall, err := CCIPHomeABI.Pack(
encodedPromotionCall, err := internal.CCIPHomeABI.Pack(
"promoteCandidateAndRevokeActive",
donID,
pluginType,
Expand All @@ -92,7 +95,7 @@ func PromoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg
nodes.PeerIDs(),
[]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{
{
CapabilityId: CCIPCapabilityID,
CapabilityId: internal.CCIPCapabilityID,
Config: encodedPromotionCall,
},
},
Expand All @@ -117,7 +120,7 @@ func PromoteAllCandidatesForChainOps(
nodes deployment.Nodes,
) ([]mcms.Operation, error) {
// fetch DON ID for the chain
donID, err := DonIDForChain(capReg, ccipHome, chainSelector)
donID, err := internal.DonIDForChain(capReg, ccipHome, chainSelector)
if err != nil {
return nil, fmt.Errorf("fetch don id for chain: %w", err)
}
Expand Down
51 changes: 25 additions & 26 deletions deployment/ccip/changeset/active_candidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ import (
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock"

"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext"

"github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal"
cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router"

"github.com/smartcontractkit/chainlink/deployment"

"github.com/stretchr/testify/require"

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

"github.com/smartcontractkit/chainlink/v2/core/logger"
Expand All @@ -26,17 +25,17 @@ func TestActiveCandidate(t *testing.T) {
t.Skipf("to be enabled after latest cl-ccip is compatible")

lggr := logger.TestLogger(t)
tenv := ccdeploy.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5)
tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5)
e := tenv.Env
state, err := ccdeploy.LoadOnchainState(tenv.Env)
state, err := LoadOnchainState(tenv.Env)
require.NoError(t, err)

// Add all lanes
require.NoError(t, ccdeploy.AddLanesForAll(e, state))
require.NoError(t, AddLanesForAll(e, state))
// Need to keep track of the block number for each chain so that event subscription can be done from that block.
startBlocks := make(map[uint64]*uint64)
// Send a message from each chain to every other chain.
expectedSeqNum := make(map[ccdeploy.SourceDestPair]uint64)
expectedSeqNum := make(map[SourceDestPair]uint64)
for src := range e.Chains {
for dest, destChain := range e.Chains {
if src == dest {
Expand All @@ -46,58 +45,58 @@ func TestActiveCandidate(t *testing.T) {
require.NoError(t, err)
block := latesthdr.Number.Uint64()
startBlocks[dest] = &block
msgSentEvent := ccdeploy.TestSendRequest(t, e, state, src, dest, false, router.ClientEVM2AnyMessage{
msgSentEvent := TestSendRequest(t, e, state, src, dest, false, router.ClientEVM2AnyMessage{
Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32),
Data: []byte("hello world"),
TokenAmounts: nil,
FeeToken: common.HexToAddress("0x0"),
ExtraArgs: nil,
})
expectedSeqNum[ccdeploy.SourceDestPair{
expectedSeqNum[SourceDestPair{
SourceChainSelector: src,
DestChainSelector: dest,
}] = msgSentEvent.SequenceNumber
}
}

// Wait for all commit reports to land.
ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks)
ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks)

//After commit is reported on all chains, token prices should be updated in FeeQuoter.
for dest := range e.Chains {
linkAddress := state.Chains[dest].LinkToken.Address()
feeQuoter := state.Chains[dest].FeeQuoter
timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress)
require.NoError(t, err)
require.Equal(t, ccdeploy.MockLinkPrice, timestampedPrice.Value)
require.Equal(t, MockLinkPrice, timestampedPrice.Value)
}

//Wait for all exec reports to land
ccdeploy.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks)
ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks)

// transfer ownership
ccdeploy.TransferAllOwnership(t, state, tenv.HomeChainSel, e)
acceptOwnershipProposal, err := ccdeploy.GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors())
TransferAllOwnership(t, state, tenv.HomeChainSel, e)
acceptOwnershipProposal, err := GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors())
require.NoError(t, err)
acceptOwnershipExec := commonchangeset.SignProposal(t, e, acceptOwnershipProposal)
for _, sel := range e.AllChainSelectors() {
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, tenv.HomeChainSel, tenv.FeedChainSel, 2)
err = 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[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome
donID, err := ccdeploy.DonIDForChain(capReg, ccipHome, tenv.FeedChainSel)
donID, err := internal.DonIDForChain(capReg, ccipHome, tenv.FeedChainSel)
require.NoError(t, err)
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)

state, err = ccdeploy.LoadOnchainState(e)
state, err = LoadOnchainState(e)
require.NoError(t, err)

// delete a non-bootstrap node
Expand All @@ -117,8 +116,8 @@ func TestActiveCandidate(t *testing.T) {
// this will construct ocr3 configurations for the
// commit and exec plugin we will be using
rmnHomeAddress := state.Chains[tenv.HomeChainSel].RMNHome.Address()
tokenConfig := ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds)
ocr3ConfigMap, err := ccdeploy.BuildOCR3ConfigForCCIPHome(
tokenConfig := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds)
ocr3ConfigMap, err := internal.BuildOCR3ConfigForCCIPHome(
deployment.XXXGenerateTestOCRSecrets(),
state.Chains[tenv.FeedChainSel].OffRamp,
e.Chains[tenv.FeedChainSel],
Expand All @@ -130,15 +129,15 @@ func TestActiveCandidate(t *testing.T) {
)
require.NoError(t, err)

setCommitCandidateOp, err := ccdeploy.SetCandidateOnExistingDon(
setCommitCandidateOp, err := SetCandidateOnExistingDon(
ocr3ConfigMap[cctypes.PluginTypeCCIPCommit],
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{{
setCommitCandidateProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel),
Batch: setCommitCandidateOp,
}}, "set new candidates on commit plugin", 0)
Expand All @@ -147,7 +146,7 @@ func TestActiveCandidate(t *testing.T) {
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(
setExecCandidateOp, err := SetCandidateOnExistingDon(
ocr3ConfigMap[cctypes.PluginTypeCCIPExec],
state.Chains[tenv.HomeChainSel].CapabilityRegistry,
state.Chains[tenv.HomeChainSel].CCIPHome,
Expand All @@ -156,7 +155,7 @@ func TestActiveCandidate(t *testing.T) {
)
require.NoError(t, err)

setExecCandidateProposal, err := ccdeploy.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
setExecCandidateProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel),
Batch: setExecCandidateOp,
}}, "set new candidates on commit and exec plugins", 0)
Expand All @@ -172,7 +171,7 @@ func TestActiveCandidate(t *testing.T) {
// [ACTIVE, CANDIDATE] done setup

// [ACTIVE, CANDIDATE] make sure we can still send successful transaction without updating job specs
err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 3)
err = ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 3)
require.NoError(t, err)
// [ACTIVE, CANDIDATE] done send successful transaction on active

Expand All @@ -181,9 +180,9 @@ func TestActiveCandidate(t *testing.T) {
oldCandidateDigest, err := state.Chains[tenv.HomeChainSel].CCIPHome.GetCandidateDigest(nil, donID, uint8(cctypes.PluginTypeCCIPExec))
require.NoError(t, err)

promoteOps, err := ccdeploy.PromoteAllCandidatesForChainOps(state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome, tenv.FeedChainSel, nodes.NonBootstraps())
promoteOps, err := 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{{
promoteProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{
ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel),
Batch: promoteOps,
}}, "promote candidates and revoke actives", 0)
Expand All @@ -207,7 +206,7 @@ func TestActiveCandidate(t *testing.T) {
require.NoError(t, err)
require.Equal(t, uint32(8), donInfo.ConfigCount)

err = ccdeploy.ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 4)
err = ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 4)
require.NoError(t, err)
// [NEW ACTIVE, NO CANDIDATE] done sending successful request
}
Loading

0 comments on commit 789d021

Please sign in to comment.