Skip to content

Commit

Permalink
Enable TestAddChainInbound (#14815)
Browse files Browse the repository at this point in the history
* add mcms batch accumulator for running integ tests

* add functions for proposing and promoting candidates in MCMS

* add some more execution for mcms, breaking at timelock reverting on underlying transaction

* format calls

* more fixes

* fixes

* clean up

* fix lint

* review comments

* review comments

* fix lint

* review comments

* fix tests

* more review comments

* add sens requests

* review comments

* send a dummy req

* fix test

* fix build

---------

Co-authored-by: 0xAustinWang <[email protected]>
  • Loading branch information
AnieeG and 0xAustinWang authored Oct 20, 2024
1 parent 505e43d commit e725f05
Show file tree
Hide file tree
Showing 8 changed files with 531 additions and 127 deletions.
116 changes: 64 additions & 52 deletions integration-tests/deployment/ccip/add_chain.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ccipdeployment

import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -15,7 +16,7 @@ import (
"github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"

"github.com/smartcontractkit/chainlink/integration-tests/deployment"

"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/ccip/generated/fee_quoter"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp"
Expand All @@ -25,19 +26,14 @@ import (
// to connect the new chain to the existing chains.
func NewChainInboundProposal(
e deployment.Environment,
ocrSecrets deployment.OCRSecrets,
state CCIPOnChainState,
homeChainSel uint64,
feedChainSel uint64,
newChainSel uint64,
sources []uint64,
tokenConfig TokenConfig,
rmnHomeAddress []byte,
) (*timelock.MCMSWithTimelockProposal, error) {
// Generate proposal which enables new destination (from test router) on all source chains.
var batches []timelock.BatchChainOperation
metaDataPerChain := make(map[mcms.ChainIdentifier]mcms.ChainMetadata)
timelockAddresses := make(map[mcms.ChainIdentifier]common.Address)
var chains []uint64
for _, source := range sources {
chain, _ := chainsel.ChainBySelector(source)
enableOnRampDest, err := state.Chains[source].OnRamp.ApplyDestChainConfigUpdates(deployment.SimTransactOpts(), []onramp.OnRampDestChainConfigArgs{
Expand Down Expand Up @@ -96,19 +92,10 @@ func NewChainInboundProposal(
},
},
})
opCount, err := state.Chains[source].ProposerMcm.GetOpCount(nil)
if err != nil {
return nil, err
}
metaDataPerChain[mcms.ChainIdentifier(chain.Selector)] = mcms.ChainMetadata{
StartingOpCount: opCount.Uint64(),
MCMAddress: state.Chains[source].ProposerMcm.Address(),
}
timelockAddresses[mcms.ChainIdentifier(chain.Selector)] = state.Chains[source].Timelock.Address()
chains = append(chains, source)
}

// Home chain new don.
// - Add new DONs for destination to home chain
homeChain, _ := chainsel.ChainBySelector(homeChainSel)
nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain)
if err != nil {
return nil, err
Expand All @@ -131,7 +118,47 @@ func NewChainInboundProposal(
return nil, err
}

newDONArgs, err := BuildAddDONArgs(
timelockAddresses, metaDataPerChain, err := BuildProposalMetadata(state, append(chains, homeChainSel))
if err != nil {
return nil, err
}
batches = append(batches, timelock.BatchChainOperation{
ChainIdentifier: mcms.ChainIdentifier(homeChain.Selector),
Batch: []mcms.Operation{
{
// Add the chain first, don needs it to be there.
To: state.Chains[homeChainSel].CCIPHome.Address(),
Data: addChain.Data(),
Value: big.NewInt(0),
},
},
})
return timelock.NewMCMSWithTimelockProposal(
"1",
2004259681, // TODO: should be parameterized and based on current block timestamp.
[]mcms.Signature{},
false,
metaDataPerChain,
timelockAddresses,
"blah", // TODO
batches,
timelock.Schedule,
"0s", // TODO: Should be parameterized.
)
}

// AddDonAndSetCandidateForCommitProposal adds new DON for destination to home chain
// and sets the commit plugin config as candidateConfig for the don.
func AddDonAndSetCandidateForCommitProposal(
state CCIPOnChainState,
e deployment.Environment,
nodes deployment.Nodes,
ocrSecrets deployment.OCRSecrets,
homeChainSel, feedChainSel, newChainSel uint64,
tokenConfig TokenConfig,
rmnHomeAddress common.Address,
) (*timelock.MCMSWithTimelockProposal, error) {
newDONArgs, err := BuildOCR3ConfigForCCIPHome(
e.Logger,
ocrSecrets,
state.Chains[newChainSel].OffRamp,
Expand All @@ -144,54 +171,39 @@ func NewChainInboundProposal(
if err != nil {
return nil, err
}
mcmsOps, err := CreateDON(
e.Logger,
latestDon, err := LatestCCIPDON(state.Chains[homeChainSel].CapabilityRegistry)
if err != nil {
return nil, err
}
commitConfig, ok := newDONArgs[types.PluginTypeCCIPCommit]
if !ok {
return nil, fmt.Errorf("missing commit plugin in ocr3Configs")
}
donID := latestDon.Id + 1
addDonOp, err := SetCandidateCommitPluginWithAddDonOps(
donID, commitConfig,
state.Chains[homeChainSel].CapabilityRegistry,
state.Chains[homeChainSel].CCIPHome,
newDONArgs,
e.Chains[homeChainSel],
nodes,
nodes.NonBootstraps(),
)
//addDON, err := state.Chains[homeChainSel].CapabilityRegistry.AddDON(SimTransactOpts(),
// nodes.NonBootstraps().PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{
// {
// CapabilityId: CCIPCapabilityID,
// Config: newDONArgs,
// },
// }, false, false, nodes.NonBootstraps().DefaultF())
if err != nil {
return nil, err
}
homeChain, _ := chainsel.ChainBySelector(homeChainSel)
opCount, err := state.Chains[homeChainSel].ProposerMcm.GetOpCount(nil)
timelockAddresses, metaDataPerChain, err := BuildProposalMetadata(state, []uint64{homeChainSel})
if err != nil {
return nil, err
}
metaDataPerChain[mcms.ChainIdentifier(homeChain.Selector)] = mcms.ChainMetadata{
StartingOpCount: opCount.Uint64(),
MCMAddress: state.Chains[homeChainSel].ProposerMcm.Address(),
}
timelockAddresses[mcms.ChainIdentifier(homeChain.Selector)] = state.Chains[homeChainSel].Timelock.Address()
batches = append(batches, timelock.BatchChainOperation{
ChainIdentifier: mcms.ChainIdentifier(homeChain.Selector),
Batch: append([]mcms.Operation{
{
// Add the chain first, don needs it to be there.
To: state.Chains[homeChainSel].CCIPHome.Address(),
Data: addChain.Data(),
Value: big.NewInt(0),
},
}, mcmsOps...),
})
return timelock.NewMCMSWithTimelockProposal(
"1",
2004259681, // TODO: should be parameterized and based on current block timestamp.
[]mcms.Signature{},
false,
metaDataPerChain,
timelockAddresses,
"blah", // TODO
batches,
"SetCandidate for commit And AddDon for new chain",
[]timelock.BatchChainOperation{{
ChainIdentifier: mcms.ChainIdentifier(homeChainSel),
Batch: []mcms.Operation{addDonOp},
}},
timelock.Schedule,
"0s", // TODO: Should be parameterized.
)
Expand Down
42 changes: 37 additions & 5 deletions integration-tests/deployment/ccip/add_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ import (
)

func TestAddChainInbound(t *testing.T) {
// TODO: fix
t.Skip("Not currently working, need to fix the addChain proposal")

// 4 chains where the 4th is added after initial deployment.
e := NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), 4)
state, err := LoadOnchainState(e.Env, e.Ab)
Expand Down Expand Up @@ -129,15 +126,45 @@ func TestAddChainInbound(t *testing.T) {
require.Equal(t, state.Chains[e.HomeChainSel].Timelock.Address(), cfgOwner)
require.Equal(t, state.Chains[e.HomeChainSel].Timelock.Address(), crOwner)

nodes, err := deployment.NodeInfo(e.Env.NodeIDs, e.Env.Offchain)
require.NoError(t, err)

// Generate and sign inbound proposal to new 4th chain.
rmnHomeAddressBytes := common.HexToAddress(rmnHomeAddress).Bytes()
chainInboundProposal, err := NewChainInboundProposal(e.Env, deployment.XXXGenerateTestOCRSecrets(), state, e.HomeChainSel, e.FeedChainSel, newChain, initialDeploy, tokenConfig, rmnHomeAddressBytes)
chainInboundProposal, err := NewChainInboundProposal(e.Env, state, e.HomeChainSel, newChain, initialDeploy)
require.NoError(t, err)
chainInboundExec := SignProposal(t, e.Env, chainInboundProposal)
for _, sel := range initialDeploy {
ExecuteProposal(t, e.Env, chainInboundExec, state, sel)
}
// 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
//SendRequest(t, e.Env, state, initialDeploy[0], newChain, true)

t.Logf("Executing add don and set candidate proposal for commit plugin on chain %d", newChain)
addDonProp, err := AddDonAndSetCandidateForCommitProposal(state, e.Env, nodes, deployment.XXXGenerateTestOCRSecrets(), e.HomeChainSel, e.FeedChainSel, newChain, tokenConfig, common.HexToAddress(rmnHomeAddress))
require.NoError(t, err)

addDonExec := SignProposal(t, e.Env, addDonProp)
ExecuteProposal(t, e.Env, addDonExec, state, e.HomeChainSel)

t.Logf("Executing promote candidate proposal for exec plugin on chain %d", newChain)
setCandidateForExecProposal, err := SetCandidateExecPluginProposal(state, e.Env, nodes, deployment.XXXGenerateTestOCRSecrets(), e.HomeChainSel, e.FeedChainSel, newChain, tokenConfig, common.HexToAddress(rmnHomeAddress))
require.NoError(t, err)
setCandidateForExecExec := SignProposal(t, e.Env, setCandidateForExecProposal)
ExecuteProposal(t, e.Env, setCandidateForExecExec, state, e.HomeChainSel)

t.Logf("Executing promote candidate proposal for both commit and exec plugins on chain %d", newChain)
donPromoteProposal, err := PromoteCandidateProposal(state, e.HomeChainSel, newChain, nodes)
require.NoError(t, err)
donPromoteExec := SignProposal(t, e.Env, donPromoteProposal)
ExecuteProposal(t, e.Env, donPromoteExec, state, e.HomeChainSel)

// verify if the configs are updated
require.NoError(t, ValidateCCIPHomeConfigSetUp(
state.Chains[e.HomeChainSel].CapabilityRegistry,
state.Chains[e.HomeChainSel].CCIPHome,
newChain,
))
replayBlocks, err := LatestBlocksByChain(testcontext.Get(t), e.Env.Chains)
require.NoError(t, err)

Expand Down Expand Up @@ -189,6 +216,11 @@ func TestAddChainInbound(t *testing.T) {
require.NoError(t, err)
startBlock := latesthdr.Number.Uint64()
seqNr := SendRequest(t, e.Env, state, initialDeploy[0], newChain, true)
require.NoError(t,
ConfirmCommitWithExpectedSeqNumRange(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, cciptypes.SeqNumRange{
cciptypes.SeqNum(1),
cciptypes.SeqNum(seqNr),
}))
require.NoError(t,
ConfirmExecWithSeqNr(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, seqNr))

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/deployment/ccip/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func DeployCCIPContracts(e deployment.Environment, ab deployment.AddressBook, c
c.OCRSecrets,
capReg,
ccipHome,
common.HexToAddress(rmnHomeAddress).Bytes(),
common.HexToAddress(rmnHomeAddress),
chainState.OffRamp,
c.FeedChainSel,
tokenInfo,
Expand Down
Loading

0 comments on commit e725f05

Please sign in to comment.