From e6653a31c149de805b6ed6ff811475f74bff038d Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 09:39:21 -0500 Subject: [PATCH 01/27] Move files --- deployment/ccip/changeset/active_candidate.go | 9 +-- .../active_candidate_helpers.go} | 6 +- .../ccip/changeset/active_candidate_test.go | 30 +++++----- deployment/ccip/changeset/add_chain.go | 13 ++-- deployment/ccip/changeset/add_chain_test.go | 32 +++++----- deployment/ccip/{ => changeset}/add_lane.go | 7 ++- .../ccip/{ => changeset}/add_lane_test.go | 6 +- deployment/ccip/{ => changeset}/consts.go | 2 +- .../ccip/changeset/deploy_chain_test.go | 6 +- .../ccip/{ => changeset}/deploy_home_chain.go | 17 +++--- deployment/ccip/changeset/home_chain.go | 3 +- deployment/ccip/changeset/home_chain_test.go | 6 +- .../ccip/changeset/initial_deploy_test.go | 21 ++++--- deployment/ccip/changeset/prerequisites.go | 4 +- .../ccip/{ => changeset}/test_assertions.go | 11 ++-- .../ccip/{ => changeset}/test_helpers.go | 60 ++++++++----------- .../ccip/{ => changeset}/test_params.go | 2 +- .../ccip/{ => changeset}/test_usdc_helpers.go | 21 ++++--- deployment/ccip/{ => changeset}/token_info.go | 3 +- deployment/ccip/deploy.go | 17 +++--- deployment/ccip/deploy_test.go | 3 +- deployment/ccip/jobs.go | 9 +-- deployment/ccip/state.go | 14 +++-- .../ccip-tests/testsetups/test_helpers.go | 30 +++++----- .../smoke/ccip_messaging_test.go | 36 +++++------ integration-tests/smoke/ccip_rmn_test.go | 11 ++-- integration-tests/smoke/ccip_test.go | 25 ++++---- integration-tests/smoke/ccip_usdc_test.go | 17 +++--- integration-tests/smoke/fee_boosting_test.go | 26 ++++---- 29 files changed, 227 insertions(+), 220 deletions(-) rename deployment/ccip/{active_candidate.go => changeset/active_candidate_helpers.go} (99%) rename deployment/ccip/{ => changeset}/add_lane.go (93%) rename deployment/ccip/{ => changeset}/add_lane_test.go (97%) rename deployment/ccip/{ => changeset}/consts.go (89%) rename deployment/ccip/{ => changeset}/deploy_home_chain.go (98%) rename deployment/ccip/{ => changeset}/test_assertions.go (98%) rename deployment/ccip/{ => changeset}/test_helpers.go (94%) rename deployment/ccip/{ => changeset}/test_params.go (97%) rename deployment/ccip/{ => changeset}/test_usdc_helpers.go (93%) rename deployment/ccip/{ => changeset}/token_info.go (99%) diff --git a/deployment/ccip/changeset/active_candidate.go b/deployment/ccip/changeset/active_candidate.go index 9f46b8d20f1..83315b22de9 100644 --- a/deployment/ccip/changeset/active_candidate.go +++ b/deployment/ccip/changeset/active_candidate.go @@ -2,6 +2,7 @@ package changeset import ( "fmt" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" @@ -17,7 +18,7 @@ func PromoteAllCandidatesChangeset( 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, @@ -48,10 +49,10 @@ func SetCandidatePluginChangeset( 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 := BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], @@ -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, diff --git a/deployment/ccip/active_candidate.go b/deployment/ccip/changeset/active_candidate_helpers.go similarity index 99% rename from deployment/ccip/active_candidate.go rename to deployment/ccip/changeset/active_candidate_helpers.go index c65dac04103..914f8fc0c17 100644 --- a/deployment/ccip/active_candidate.go +++ b/deployment/ccip/changeset/active_candidate_helpers.go @@ -1,13 +1,15 @@ -package ccipdeployment +package changeset import ( "fmt" + "math/big" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/chainlink/deployment" 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 diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index 50115389a28..4929518a9c0 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -26,13 +26,13 @@ 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) 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. @@ -46,7 +46,7 @@ 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, @@ -58,7 +58,7 @@ func TestActiveCandidate(t *testing.T) { } // 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 { @@ -66,11 +66,11 @@ func TestActiveCandidate(t *testing.T) { 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) @@ -82,12 +82,12 @@ func TestActiveCandidate(t *testing.T) { } // 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 := DonIDForChain(capReg, ccipHome, tenv.FeedChainSel) require.NoError(t, err) donInfo, err := state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) require.NoError(t, err) @@ -114,8 +114,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 := BuildOCR3ConfigForCCIPHome( deployment.XXXGenerateTestOCRSecrets(), state.Chains[tenv.FeedChainSel].OffRamp, e.Chains[tenv.FeedChainSel], @@ -127,7 +127,7 @@ 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, @@ -144,7 +144,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, @@ -169,7 +169,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 @@ -178,7 +178,7 @@ 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{{ ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), @@ -204,7 +204,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 } diff --git a/deployment/ccip/changeset/add_chain.go b/deployment/ccip/changeset/add_chain.go index 3ce6d17d24e..1039f87dcc6 100644 --- a/deployment/ccip/changeset/add_chain.go +++ b/deployment/ccip/changeset/add_chain.go @@ -5,7 +5,6 @@ import ( "math/big" ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" @@ -42,7 +41,7 @@ func NewChainInboundChangeset( []fee_quoter.FeeQuoterDestChainConfigArgs{ { DestChainSelector: newChainSel, - DestChainConfig: ccipdeployment.DefaultFeeQuoterDestChainConfig(), + DestChainConfig: DefaultFeeQuoterDestChainConfig(), }, }) if err != nil { @@ -66,7 +65,7 @@ func NewChainInboundChangeset( }) } - addChainOp, err := ccipdeployment.ApplyChainConfigUpdatesOp(e, state, homeChainSel, []uint64{newChainSel}) + addChainOp, err := ApplyChainConfigUpdatesOp(e, state, homeChainSel, []uint64{newChainSel}) if err != nil { return deployment.ChangesetOutput{}, err } @@ -96,10 +95,10 @@ func AddDonAndSetCandidateChangeset( nodes deployment.Nodes, ocrSecrets deployment.OCRSecrets, homeChainSel, feedChainSel, newChainSel uint64, - tokenConfig ccipdeployment.TokenConfig, + tokenConfig TokenConfig, pluginType types.PluginType, ) (deployment.ChangesetOutput, error) { - newDONArgs, err := ccipdeployment.BuildOCR3ConfigForCCIPHome( + newDONArgs, err := BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], @@ -112,7 +111,7 @@ func AddDonAndSetCandidateChangeset( if err != nil { return deployment.ChangesetOutput{}, err } - latestDon, err := ccipdeployment.LatestCCIPDON(state.Chains[homeChainSel].CapabilityRegistry) + latestDon, err := LatestCCIPDON(state.Chains[homeChainSel].CapabilityRegistry) if err != nil { return deployment.ChangesetOutput{}, err } @@ -121,7 +120,7 @@ func AddDonAndSetCandidateChangeset( return deployment.ChangesetOutput{}, fmt.Errorf("missing commit plugin in ocr3Configs") } donID := latestDon.Id + 1 - addDonOp, err := ccipdeployment.NewDonWithCandidateOp( + addDonOp, err := NewDonWithCandidateOp( donID, commitConfig, state.Chains[homeChainSel].CapabilityRegistry, nodes.NonBootstraps(), diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 76104871784..abf4447af49 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -31,7 +31,7 @@ import ( func TestAddChainInbound(t *testing.T) { // 4 chains where the 4th is added after initial deployment. - e := ccipdeployment.NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), 4, 4) + e := NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), 4, 4) state, err := ccipdeployment.LoadOnchainState(e.Env) require.NoError(t, err) // Take first non-home chain as the new chain. @@ -58,7 +58,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) newAddresses = deployment.NewMemoryAddressBook() - tokenConfig := ccipdeployment.NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) err = ccipdeployment.DeployCCIPContracts(e.Env, newAddresses, ccipdeployment.DeployCCIPContractConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, @@ -75,7 +75,7 @@ func TestAddChainInbound(t *testing.T) { for _, source := range initialDeploy { for _, dest := range initialDeploy { if source != dest { - require.NoError(t, ccipdeployment.AddLaneWithDefaultPrices(e.Env, state, source, dest)) + require.NoError(t, AddLaneWithDefaultPrices(e.Env, state, source, dest)) } } } @@ -160,7 +160,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) + ProcessChangeset(t, 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 @@ -169,25 +169,25 @@ 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) + ProcessChangeset(t, 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) + ProcessChangeset(t, 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) + ProcessChangeset(t, e.Env, donPromoteChangeset) // verify if the configs are updated - require.NoError(t, ccipdeployment.ValidateCCIPHomeConfigSetUp( + require.NoError(t, ValidateCCIPHomeConfigSetUp( state.Chains[e.HomeChainSel].CapabilityRegistry, state.Chains[e.HomeChainSel].CCIPHome, newChain, )) - replayBlocks, err := ccipdeployment.LatestBlocksByChain(testcontext.Get(t), e.Env.Chains) + replayBlocks, err := LatestBlocksByChain(testcontext.Get(t), e.Env.Chains) require.NoError(t, err) // Now configure the new chain using deployer key (not transferred to timelock yet). @@ -205,9 +205,9 @@ func TestAddChainInbound(t *testing.T) { _, err = deployment.ConfirmIfNoError(e.Env.Chains[newChain], tx, err) require.NoError(t, err) // Set the OCR3 config on new 4th chain to enable the plugin. - latestDON, err := ccipdeployment.LatestCCIPDON(state.Chains[e.HomeChainSel].CapabilityRegistry) + latestDON, err := LatestCCIPDON(state.Chains[e.HomeChainSel].CapabilityRegistry) require.NoError(t, err) - ocrConfigs, err := ccipdeployment.BuildSetOCR3ConfigArgs(latestDON.Id, state.Chains[e.HomeChainSel].CCIPHome, newChain) + ocrConfigs, err := BuildSetOCR3ConfigArgs(latestDON.Id, state.Chains[e.HomeChainSel].CCIPHome, newChain) require.NoError(t, err) tx, err = state.Chains[newChain].OffRamp.SetOCR3Configs(e.Env.Chains[newChain].DeployerKey, ocrConfigs) require.NoError(t, err) @@ -230,14 +230,14 @@ func TestAddChainInbound(t *testing.T) { } // Ensure job related logs are up to date. time.Sleep(30 * time.Second) - ccipdeployment.ReplayLogs(t, e.Env.Offchain, replayBlocks) + ReplayLogs(t, e.Env.Offchain, replayBlocks) // TODO: Send via all inbound lanes and use parallel helper // Now that the proposal has been executed we expect to be able to send traffic to this new 4th chain. latesthdr, err := e.Env.Chains[newChain].Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) startBlock := latesthdr.Number.Uint64() - msgSentEvent := ccipdeployment.TestSendRequest(t, e.Env, state, initialDeploy[0], newChain, true, router.ClientEVM2AnyMessage{ + msgSentEvent := TestSendRequest(t, e.Env, state, initialDeploy[0], newChain, true, router.ClientEVM2AnyMessage{ Receiver: common.LeftPadBytes(state.Chains[newChain].Receiver.Address().Bytes(), 32), Data: []byte("hello world"), TokenAmounts: nil, @@ -245,16 +245,16 @@ func TestAddChainInbound(t *testing.T) { ExtraArgs: nil, }) require.NoError(t, - ccipdeployment.ConfirmCommitWithExpectedSeqNumRange(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, cciptypes.SeqNumRange{ + ConfirmCommitWithExpectedSeqNumRange(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, cciptypes.SeqNumRange{ cciptypes.SeqNum(1), cciptypes.SeqNum(msgSentEvent.SequenceNumber), })) require.NoError(t, - commonutils.JustError(ccipdeployment.ConfirmExecWithSeqNr(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, msgSentEvent.SequenceNumber))) + commonutils.JustError(ConfirmExecWithSeqNr(t, e.Env.Chains[initialDeploy[0]], e.Env.Chains[newChain], state.Chains[newChain].OffRamp, &startBlock, msgSentEvent.SequenceNumber))) linkAddress := state.Chains[newChain].LinkToken.Address() feeQuoter := state.Chains[newChain].FeeQuoter timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress) require.NoError(t, err) - require.Equal(t, ccipdeployment.MockLinkPrice, timestampedPrice.Value) + require.Equal(t, MockLinkPrice, timestampedPrice.Value) } diff --git a/deployment/ccip/add_lane.go b/deployment/ccip/changeset/add_lane.go similarity index 93% rename from deployment/ccip/add_lane.go rename to deployment/ccip/changeset/add_lane.go index 8af96277fc2..9eed05a81cd 100644 --- a/deployment/ccip/add_lane.go +++ b/deployment/ccip/changeset/add_lane.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "encoding/hex" @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" @@ -27,11 +28,11 @@ var DefaultInitialPrices = InitialPrices{ GasPrice: ToPackedFee(big.NewInt(8e14), big.NewInt(0)), } -func AddLaneWithDefaultPrices(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { +func AddLaneWithDefaultPrices(e deployment.Environment, state ccipdeployment.CCIPOnChainState, from, to uint64) error { return AddLane(e, state, from, to, DefaultInitialPrices) } -func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, initialPrices InitialPrices) error { +func AddLane(e deployment.Environment, state ccipdeployment.CCIPOnChainState, from, to uint64, initialPrices InitialPrices) error { // TODO: Batch tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ { diff --git a/deployment/ccip/add_lane_test.go b/deployment/ccip/changeset/add_lane_test.go similarity index 97% rename from deployment/ccip/add_lane_test.go rename to deployment/ccip/changeset/add_lane_test.go index 5c87a089a1b..2d27925b536 100644 --- a/deployment/ccip/add_lane_test.go +++ b/deployment/ccip/changeset/add_lane_test.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "testing" @@ -9,8 +9,8 @@ import ( commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -23,7 +23,7 @@ func TestAddLane(t *testing.T) { // We add more chains to the chainlink nodes than the number of chains where CCIP is deployed. e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4) // Here we have CR + nodes set up, but no CCIP contracts deployed. - state, err := LoadOnchainState(e.Env) + state, err := ccipdeployment.LoadOnchainState(e.Env) require.NoError(t, err) selectors := e.Env.AllChainSelectors() diff --git a/deployment/ccip/consts.go b/deployment/ccip/changeset/consts.go similarity index 89% rename from deployment/ccip/consts.go rename to deployment/ccip/changeset/consts.go index 48466bcef46..8d5e64ccde7 100644 --- a/deployment/ccip/consts.go +++ b/deployment/ccip/changeset/consts.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset type TokenSymbol string diff --git a/deployment/ccip/changeset/deploy_chain_test.go b/deployment/ccip/changeset/deploy_chain_test.go index 0e5b7a8d270..181287815c5 100644 --- a/deployment/ccip/changeset/deploy_chain_test.go +++ b/deployment/ccip/changeset/deploy_chain_test.go @@ -30,9 +30,9 @@ func TestDeployChainContractsChangeset(t *testing.T) { // deploy home chain homeChainCfg := DeployHomeChainConfig{ HomeChainSel: homeChainSel, - RMNStaticConfig: ccdeploy.NewTestRMNStaticConfig(), - RMNDynamicConfig: ccdeploy.NewTestRMNDynamicConfig(), - NodeOperators: ccdeploy.NewTestNodeOperator(e.Chains[homeChainSel].DeployerKey.From), + RMNStaticConfig: NewTestRMNStaticConfig(), + RMNDynamicConfig: NewTestRMNDynamicConfig(), + NodeOperators: NewTestNodeOperator(e.Chains[homeChainSel].DeployerKey.From), NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ "NodeOperator": p2pIds, }, diff --git a/deployment/ccip/deploy_home_chain.go b/deployment/ccip/changeset/deploy_home_chain.go similarity index 98% rename from deployment/ccip/deploy_home_chain.go rename to deployment/ccip/changeset/deploy_home_chain.go index 9c7c65bc9dc..b07e844be04 100644 --- a/deployment/ccip/deploy_home_chain.go +++ b/deployment/ccip/changeset/deploy_home_chain.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "bytes" @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + "github.com/smartcontractkit/chainlink/deployment/ccip" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" @@ -90,7 +91,7 @@ func MustABIEncode(abiString string, args ...interface{}) []byte { // and returns a deployment.ContractDeploy struct with the address and contract instance. func DeployCapReg( lggr logger.Logger, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, ab deployment.AddressBook, chain deployment.Chain, ) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { @@ -100,7 +101,7 @@ func DeployCapReg( if cr != nil { lggr.Infow("Found CapabilitiesRegistry in chain state", "address", cr.Address().String()) return &deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ - Address: cr.Address(), Contract: cr, Tv: deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0), + Address: cr.Address(), Contract: cr, Tv: deployment.NewTypeAndVersion(ccipdeployment.CapabilitiesRegistry, deployment.Version1_0_0), }, nil } } @@ -111,7 +112,7 @@ func DeployCapReg( chain.Client, ) return deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ - Address: crAddr, Contract: cr, Tv: deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0), Tx: tx, Err: err2, + Address: crAddr, Contract: cr, Tv: deployment.NewTypeAndVersion(ccipdeployment.CapabilitiesRegistry, deployment.Version1_0_0), Tx: tx, Err: err2, } }) if err != nil { @@ -132,7 +133,7 @@ func DeployHomeChain( nodeP2PIDsPerNodeOpAdmin map[string][][32]byte, ) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { // load existing state - state, err := LoadOnchainState(e) + state, err := ccipdeployment.LoadOnchainState(e) if err != nil { return nil, fmt.Errorf("failed to load onchain state: %w", err) } @@ -152,7 +153,7 @@ func DeployHomeChain( capReg.Address, ) return deployment.ContractDeploy[*ccip_home.CCIPHome]{ - Address: ccAddr, Tv: deployment.NewTypeAndVersion(CCIPHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: cc, + Address: ccAddr, Tv: deployment.NewTypeAndVersion(ccipdeployment.CCIPHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: cc, } }) if err != nil { @@ -169,7 +170,7 @@ func DeployHomeChain( chain.Client, ) return deployment.ContractDeploy[*rmn_home.RMNHome]{ - Address: rmnAddr, Tv: deployment.NewTypeAndVersion(RMNHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: rmn, + Address: rmnAddr, Tv: deployment.NewTypeAndVersion(ccipdeployment.RMNHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: rmn, } }, ) @@ -1046,7 +1047,7 @@ func AddDON( func ApplyChainConfigUpdatesOp( e deployment.Environment, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, homeChainSel uint64, chains []uint64, ) (mcms.Operation, error) { diff --git a/deployment/ccip/changeset/home_chain.go b/deployment/ccip/changeset/home_chain.go index 92b5b09c695..51c2a1ed77f 100644 --- a/deployment/ccip/changeset/home_chain.go +++ b/deployment/ccip/changeset/home_chain.go @@ -8,7 +8,6 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) @@ -23,7 +22,7 @@ func DeployHomeChain(env deployment.Environment, cfg DeployHomeChainConfig) (dep } ab := deployment.NewMemoryAddressBook() // Note we also deploy the cap reg. - _, err = ccipdeployment.DeployHomeChain(env.Logger, env, ab, env.Chains[cfg.HomeChainSel], cfg.RMNStaticConfig, cfg.RMNDynamicConfig, cfg.NodeOperators, cfg.NodeP2PIDsPerNodeOpAdmin) + _, err = DeployHomeChain(env.Logger, env, ab, env.Chains[cfg.HomeChainSel], cfg.RMNStaticConfig, cfg.RMNDynamicConfig, cfg.NodeOperators, cfg.NodeP2PIDsPerNodeOpAdmin) if err != nil { env.Logger.Errorw("Failed to deploy cap reg", "err", err, "addresses", env.ExistingAddresses) return deployment.ChangesetOutput{ diff --git a/deployment/ccip/changeset/home_chain_test.go b/deployment/ccip/changeset/home_chain_test.go index f0abdc64437..1b3fad73924 100644 --- a/deployment/ccip/changeset/home_chain_test.go +++ b/deployment/ccip/changeset/home_chain_test.go @@ -27,9 +27,9 @@ func TestDeployHomeChain(t *testing.T) { p2pIds := nodes.NonBootstraps().PeerIDs() homeChainCfg := DeployHomeChainConfig{ HomeChainSel: homeChainSel, - RMNStaticConfig: ccdeploy.NewTestRMNStaticConfig(), - RMNDynamicConfig: ccdeploy.NewTestRMNDynamicConfig(), - NodeOperators: ccdeploy.NewTestNodeOperator(e.Chains[homeChainSel].DeployerKey.From), + RMNStaticConfig: NewTestRMNStaticConfig(), + RMNDynamicConfig: NewTestRMNDynamicConfig(), + NodeOperators: NewTestNodeOperator(e.Chains[homeChainSel].DeployerKey.From), NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ "NodeOperator": p2pIds, }, diff --git a/deployment/ccip/changeset/initial_deploy_test.go b/deployment/ccip/changeset/initial_deploy_test.go index a299dd4971f..53eb7c0dc1d 100644 --- a/deployment/ccip/changeset/initial_deploy_test.go +++ b/deployment/ccip/changeset/initial_deploy_test.go @@ -7,7 +7,6 @@ import ( "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" @@ -24,8 +23,8 @@ import ( func TestInitialDeploy(t *testing.T) { lggr := logger.TestLogger(t) - ctx := ccdeploy.Context(t) - tenv := ccdeploy.NewMemoryEnvironment(t, lggr, 3, 4, ccdeploy.MockLinkPrice, ccdeploy.MockWethPrice) + ctx := Context(t) + tenv := NewMemoryEnvironment(t, lggr, 3, 4, MockLinkPrice, MockWethPrice) e := tenv.Env state, err := ccdeploy.LoadOnchainState(tenv.Env) @@ -54,7 +53,7 @@ func TestInitialDeploy(t *testing.T) { HomeChainSel: tenv.HomeChainSel, FeedChainSel: tenv.FeedChainSel, ChainsToDeploy: tenv.Env.AllChainSelectors(), - TokenConfig: ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds), + TokenConfig: NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds), OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), }) require.NoError(t, err) @@ -64,7 +63,7 @@ func TestInitialDeploy(t *testing.T) { 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) + ReplayLogs(t, e.Offchain, tenv.ReplayBlocks) // Apply the jobs. for nodeID, jobs := range output.JobSpecs { @@ -80,7 +79,7 @@ func TestInitialDeploy(t *testing.T) { } // 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. @@ -95,7 +94,7 @@ func TestInitialDeploy(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"), TokenAmounts: nil, @@ -107,14 +106,14 @@ func TestInitialDeploy(t *testing.T) { } // Wait for all commit reports to land. - ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) + ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) // Confirm token and gas prices are updated - ccdeploy.ConfirmTokenPriceUpdatedForAll(t, e, state, startBlocks, - ccdeploy.DefaultInitialPrices.LinkPrice, ccdeploy.DefaultInitialPrices.WethPrice) + ConfirmTokenPriceUpdatedForAll(t, e, state, startBlocks, + DefaultInitialPrices.LinkPrice, DefaultInitialPrices.WethPrice) // TODO: Fix gas prices? //ccdeploy.ConfirmGasPriceUpdatedForAll(t, e, state, startBlocks) // //// Wait for all exec reports to land - ccdeploy.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) + ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) } diff --git a/deployment/ccip/changeset/prerequisites.go b/deployment/ccip/changeset/prerequisites.go index 20ff7f5a935..7332f97fc18 100644 --- a/deployment/ccip/changeset/prerequisites.go +++ b/deployment/ccip/changeset/prerequisites.go @@ -40,8 +40,8 @@ func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfi type DeployPrerequisiteConfig struct { ChainSelectors []uint64 // TODO handle tokens and feeds in prerequisite config - Tokens map[ccipdeployment.TokenSymbol]common.Address - Feeds map[ccipdeployment.TokenSymbol]common.Address + Tokens map[TokenSymbol]common.Address + Feeds map[TokenSymbol]common.Address } func (c DeployPrerequisiteConfig) Validate() error { diff --git a/deployment/ccip/test_assertions.go b/deployment/ccip/changeset/test_assertions.go similarity index 98% rename from deployment/ccip/test_assertions.go rename to deployment/ccip/changeset/test_assertions.go index 0c15c8b95ed..f311e670664 100644 --- a/deployment/ccip/test_assertions.go +++ b/deployment/ccip/changeset/test_assertions.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "context" @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment" @@ -25,7 +26,7 @@ import ( func ConfirmGasPriceUpdatedForAll( t *testing.T, e deployment.Environment, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, startBlocks map[uint64]*uint64, gasPrice *big.Int, ) { @@ -78,7 +79,7 @@ func ConfirmGasPriceUpdated( func ConfirmTokenPriceUpdatedForAll( t *testing.T, e deployment.Environment, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, startBlocks map[uint64]*uint64, linkPrice *big.Int, wethPrice *big.Int, @@ -154,7 +155,7 @@ func ConfirmTokenPriceUpdated( func ConfirmCommitForAllWithExpectedSeqNums( t *testing.T, e deployment.Environment, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, expectedSeqNums map[uint64]uint64, startBlocks map[uint64]*uint64, ) { @@ -306,7 +307,7 @@ func ConfirmCommitWithExpectedSeqNumRange( func ConfirmExecWithSeqNrForAll( t *testing.T, e deployment.Environment, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, expectedSeqNums map[uint64]uint64, startBlocks map[uint64]*uint64, ) (executionStates map[uint64]int) { diff --git a/deployment/ccip/test_helpers.go b/deployment/ccip/changeset/test_helpers.go similarity index 94% rename from deployment/ccip/test_helpers.go rename to deployment/ccip/changeset/test_helpers.go index f858164e720..38490e9f9eb 100644 --- a/deployment/ccip/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "context" @@ -17,6 +17,8 @@ import ( "github.com/pkg/errors" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/deployment/ccip" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -85,7 +87,7 @@ type DeployedEnv struct { func (e *DeployedEnv) SetupJobs(t *testing.T) { ctx := testcontext.Get(t) - jbs, err := NewCCIPJobSpecs(e.Env.NodeIDs, e.Env.Offchain) + jbs, err := ccipdeployment.NewCCIPJobSpecs(e.Env.NodeIDs, e.Env.Offchain) require.NoError(t, err) for nodeID, jobs := range jbs { for _, job := range jobs { @@ -126,8 +128,8 @@ func DeployTestContracts(t *testing.T, ) deployment.CapabilityRegistryConfig { capReg, err := DeployCapReg(lggr, // deploying cap reg for the first time on a blank chain state - CCIPOnChainState{ - Chains: make(map[uint64]CCIPChainState), + ccipdeployment.CCIPOnChainState{ + Chains: make(map[uint64]ccipdeployment.CCIPChainState), }, ab, chains[homeChainSel]) require.NoError(t, err) _, err = DeployFeeds(lggr, ab, chains[feedChainSel], linkPrice, wethPrice) @@ -247,7 +249,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, e.SetupJobs(t) // Take first non-home chain as the new chain. newAddresses := deployment.NewMemoryAddressBook() - err := DeployPrerequisiteChainContracts(e.Env, newAddresses, e.Env.AllChainSelectors()) + err := ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, e.Env.AllChainSelectors()) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) @@ -265,7 +267,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, out, err := commonchangeset.DeployMCMSWithTimelock(e.Env, mcmsCfg) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) - state, err := LoadOnchainState(e.Env) + state, err := ccipdeployment.LoadOnchainState(e.Env) require.NoError(t, err) newAddresses = deployment.NewMemoryAddressBook() @@ -273,15 +275,15 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, server := mockAttestationResponse() defer server.Close() endpoint := server.URL - err = DeployCCIPContracts(e.Env, newAddresses, DeployCCIPContractConfig{ + err = ccipdeployment.DeployCCIPContracts(e.Env, newAddresses, ccipdeployment.DeployCCIPContractConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: e.Env.AllChainSelectors(), TokenConfig: tokenConfig, OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - USDCConfig: USDCConfig{ + USDCConfig: ccipdeployment.USDCConfig{ Enabled: true, - USDCAttestationConfig: USDCAttestationConfig{ + USDCAttestationConfig: ccipdeployment.USDCAttestationConfig{ API: endpoint, APITimeout: commonconfig.MustNewDuration(time.Second), APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), @@ -290,27 +292,15 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, }) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - state, err = LoadOnchainState(e.Env) + state, err = ccipdeployment.LoadOnchainState(e.Env) require.NoError(t, err) return e } -func NewMemoryEnvironmentWithJobsAndPrices( - t *testing.T, - lggr logger.Logger, - numChains int, - numNodes int, - linkPrice *big.Int, - wethPrice *big.Int) DeployedEnv { - e := NewMemoryEnvironment(t, lggr, numChains, numNodes, linkPrice, wethPrice) - e.SetupJobs(t) - return e -} - func CCIPSendRequest( e deployment.Environment, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, src, dest uint64, testRouter bool, evm2AnyMessage router.ClientEVM2AnyMessage, @@ -352,7 +342,7 @@ func CCIPSendRequest( func TestSendRequest( t *testing.T, e deployment.Environment, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, src, dest uint64, testRouter bool, evm2AnyMessage router.ClientEVM2AnyMessage, @@ -413,11 +403,11 @@ func MakeEVMExtraArgsV2(gasLimit uint64, allowOOO bool) []byte { // AddLanesForAll adds densely connected lanes for all chains in the environment so that each chain // is connected to every other chain except itself. -func AddLanesForAll(e deployment.Environment, state CCIPOnChainState) error { +func AddLanesForAll(e deployment.Environment, state ccipdeployment.CCIPOnChainState) error { for source := range e.Chains { for dest := range e.Chains { if source != dest { - err := AddLaneWithDefaultPrices(e, state, source, dest) + err := internal.AddLaneWithDefaultPrices(e, state, source, dest) if err != nil { return err } @@ -468,7 +458,7 @@ func DeployFeeds( linkPrice *big.Int, wethPrice *big.Int, ) (map[string]common.Address, error) { - linkTV := deployment.NewTypeAndVersion(PriceFeed, deployment.Version1_0_0) + linkTV := deployment.NewTypeAndVersion(ccipdeployment.PriceFeed, deployment.Version1_0_0) mockLinkFeed := func(chain deployment.Chain) deployment.ContractDeploy[*aggregator_v3_interface.AggregatorV3Interface] { linkFeed, tx, _, err1 := mock_v3_aggregator_contract.DeployMockV3Aggregator( chain.DeployerKey, @@ -544,7 +534,7 @@ func deploySingleFeed( return mockTokenFeed.Address, desc, nil } -func ConfirmRequestOnSourceAndDest(t *testing.T, env deployment.Environment, state CCIPOnChainState, sourceCS, destCS, expectedSeqNr uint64) error { +func ConfirmRequestOnSourceAndDest(t *testing.T, env deployment.Environment, state ccipdeployment.CCIPOnChainState, sourceCS, destCS, expectedSeqNr uint64) error { latesthdr, err := env.Chains[destCS].Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) startBlock := latesthdr.Number.Uint64() @@ -589,7 +579,7 @@ func ProcessChangeset(t *testing.T, e deployment.Environment, c deployment.Chang // sign and execute all proposals provided if len(c.Proposals) != 0 { - state, err := LoadOnchainState(e) + state, err := ccipdeployment.LoadOnchainState(e) require.NoError(t, err) for _, prop := range c.Proposals { chains := mapset.NewSet[uint64]() @@ -615,7 +605,7 @@ func DeployTransferableToken( lggr logger.Logger, chains map[uint64]deployment.Chain, src, dst uint64, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, addresses deployment.AddressBook, token string, ) (*burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, *burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, error) { @@ -770,7 +760,7 @@ func setTokenPoolCounterPart( func attachTokenToTheRegistry( chain deployment.Chain, - state CCIPChainState, + state ccipdeployment.CCIPChainState, owner *bind.TransactOpts, token common.Address, tokenPool common.Address, @@ -816,10 +806,10 @@ func deployTransferTokenOneEnd( return nil, nil, err } for address, v := range chainAddresses { - if deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0) == v { + if deployment.NewTypeAndVersion(ccipdeployment.ARMProxy, deployment.Version1_0_0) == v { rmnAddress = address } - if deployment.NewTypeAndVersion(Router, deployment.Version1_2_0) == v { + if deployment.NewTypeAndVersion(ccipdeployment.Router, deployment.Version1_2_0) == v { routerAddress = address } if rmnAddress != "" && routerAddress != "" { @@ -838,7 +828,7 @@ func deployTransferTokenOneEnd( big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), ) return deployment.ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ - USDCTokenAddr, token, tx, deployment.NewTypeAndVersion(BurnMintToken, deployment.Version1_0_0), err2, + USDCTokenAddr, token, tx, deployment.NewTypeAndVersion(ccipdeployment.BurnMintToken, deployment.Version1_0_0), err2, } }) if err != nil { @@ -866,7 +856,7 @@ func deployTransferTokenOneEnd( common.HexToAddress(routerAddress), ) return deployment.ContractDeploy[*burn_mint_token_pool.BurnMintTokenPool]{ - tokenPoolAddress, tokenPoolContract, tx, deployment.NewTypeAndVersion(BurnMintTokenPool, deployment.Version1_0_0), err2, + tokenPoolAddress, tokenPoolContract, tx, deployment.NewTypeAndVersion(ccipdeployment.BurnMintTokenPool, deployment.Version1_0_0), err2, } }) if err != nil { diff --git a/deployment/ccip/test_params.go b/deployment/ccip/changeset/test_params.go similarity index 97% rename from deployment/ccip/test_params.go rename to deployment/ccip/changeset/test_params.go index 531c48532f1..eea0f8eb183 100644 --- a/deployment/ccip/test_params.go +++ b/deployment/ccip/changeset/test_params.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "github.com/ethereum/go-ethereum/common" diff --git a/deployment/ccip/test_usdc_helpers.go b/deployment/ccip/changeset/test_usdc_helpers.go similarity index 93% rename from deployment/ccip/test_usdc_helpers.go rename to deployment/ccip/changeset/test_usdc_helpers.go index 787ca328a8e..f114cbef8b4 100644 --- a/deployment/ccip/test_usdc_helpers.go +++ b/deployment/ccip/changeset/test_usdc_helpers.go @@ -1,23 +1,26 @@ -package ccipdeployment +package changeset import ( + "math/big" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-ccip/pkg/reader" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_messenger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" - "math/big" ) func ConfigureUSDCTokenPools( lggr logger.Logger, chains map[uint64]deployment.Chain, src, dst uint64, - state CCIPOnChainState, + state ccipdeployment.CCIPOnChainState, ) (*burn_mint_erc677.BurnMintERC677, *burn_mint_erc677.BurnMintERC677, error) { srcToken := state.Chains[src].BurnMintTokens677[USDCSymbol] dstToken := state.Chains[dst].BurnMintTokens677[USDCSymbol] @@ -76,7 +79,7 @@ func ConfigureUSDCTokenPools( func UpdateFeeQuoterForUSDC( lggr logger.Logger, chain deployment.Chain, - state CCIPChainState, + state ccipdeployment.CCIPChainState, dstChain uint64, usdcToken *burn_mint_erc677.BurnMintERC677, ) error { @@ -117,7 +120,7 @@ func DeployUSDC( lggr logger.Logger, chain deployment.Chain, addresses deployment.AddressBook, - state CCIPChainState, + state ccipdeployment.CCIPChainState, ) ( *burn_mint_erc677.BurnMintERC677, *usdc_token_pool.USDCTokenPool, @@ -139,7 +142,7 @@ func DeployUSDC( Address: tokenAddress, Contract: tokenContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(USDCToken, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCToken, deployment.Version1_0_0), Err: err2, } }) @@ -171,7 +174,7 @@ func DeployUSDC( Address: transmitterAddress, Contract: transmitterContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(USDCMockTransmitter, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCMockTransmitter, deployment.Version1_0_0), Err: err2, } }) @@ -194,7 +197,7 @@ func DeployUSDC( Address: messengerAddress, Contract: messengerContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(USDCTokenMessenger, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCTokenMessenger, deployment.Version1_0_0), Err: err2, } }) @@ -219,7 +222,7 @@ func DeployUSDC( Address: tokenPoolAddress, Contract: tokenPoolContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(USDCTokenPool, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCTokenPool, deployment.Version1_0_0), Err: err2, } }) diff --git a/deployment/ccip/token_info.go b/deployment/ccip/changeset/token_info.go similarity index 99% rename from deployment/ccip/token_info.go rename to deployment/ccip/changeset/token_info.go index 559c961e3d4..c658ffa2b2f 100644 --- a/deployment/ccip/token_info.go +++ b/deployment/ccip/changeset/token_info.go @@ -1,9 +1,8 @@ -package ccipdeployment +package changeset import ( "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" diff --git a/deployment/ccip/deploy.go b/deployment/ccip/deploy.go index 0dea0a8b1f8..ea69a426f67 100644 --- a/deployment/ccip/deploy.go +++ b/deployment/ccip/deploy.go @@ -12,6 +12,7 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" @@ -282,7 +283,7 @@ type DeployCCIPContractConfig struct { HomeChainSel uint64 FeedChainSel uint64 ChainsToDeploy []uint64 - TokenConfig TokenConfig + TokenConfig changeset.TokenConfig USDCConfig USDCConfig // For setting OCR configuration OCRSecrets deployment.OCRSecrets @@ -337,7 +338,7 @@ func DeployCCIPContracts( return fmt.Errorf("chain %d not found", chainSel) } if c.USDCConfig.Enabled { - token, pool, messenger, transmitter, err1 := DeployUSDC(e.Logger, chain, ab, existingState.Chains[chainSel]) + token, pool, messenger, transmitter, err1 := changeset.DeployUSDC(e.Logger, chain, ab, existingState.Chains[chainSel]) if err1 != nil { return err1 } @@ -376,7 +377,7 @@ func DeployCCIPContracts( tokenInfo := c.TokenConfig.GetTokenInfo(e.Logger, existingState.Chains[chainSel].LinkToken, existingState.Chains[chainSel].Weth9) // TODO: Do we want to extract this? // Add chain config for each chain. - _, err = AddChainConfig( + _, err = changeset.AddChainConfig( e.Logger, e.Chains[c.HomeChainSel], ccipHome, @@ -399,7 +400,7 @@ func DeployCCIPContracts( }} } // For each chain, we create a DON on the home chain (2 OCR instances) - if err := AddDON( + if err := changeset.AddDON( e.Logger, c.OCRSecrets, capReg, @@ -438,15 +439,15 @@ func DeployChainContractsForChains( return fmt.Errorf("capability registry not found") } cr, err := capReg.GetHashedCapabilityId( - &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) + &bind.CallOpts{}, changeset.CapabilityLabelledName, changeset.CapabilityVersion) if err != nil { e.Logger.Errorw("Failed to get hashed capability id", "err", err) return err } - if cr != CCIPCapabilityID { - return fmt.Errorf("capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(CCIPCapabilityID[:])) + if cr != changeset.CCIPCapabilityID { + return fmt.Errorf("capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(changeset.CCIPCapabilityID[:])) } - capability, err := capReg.GetCapability(nil, CCIPCapabilityID) + capability, err := capReg.GetCapability(nil, changeset.CCIPCapabilityID) if err != nil { e.Logger.Errorw("Failed to get capability", "err", err) return err diff --git a/deployment/ccip/deploy_test.go b/deployment/ccip/deploy_test.go index c2b71e093de..d5f5cb41e90 100644 --- a/deployment/ccip/deploy_test.go +++ b/deployment/ccip/deploy_test.go @@ -7,12 +7,13 @@ import ( "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestDeployCCIPContracts(t *testing.T) { lggr := logger.TestLogger(t) - e := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, + e := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, ) diff --git a/deployment/ccip/jobs.go b/deployment/ccip/jobs.go index b7ffed45cac..4cd3a619153 100644 --- a/deployment/ccip/jobs.go +++ b/deployment/ccip/jobs.go @@ -2,6 +2,7 @@ package ccipdeployment import ( "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) @@ -26,8 +27,8 @@ func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string if !node.IsBootstrap { spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ P2PV2Bootstrappers: nodes.BootstrapLocators(), - CapabilityVersion: CapabilityVersion, - CapabilityLabelledName: CapabilityLabelledName, + CapabilityVersion: changeset.CapabilityVersion, + CapabilityLabelledName: changeset.CapabilityLabelledName, OCRKeyBundleIDs: map[string]string{ // TODO: Validate that that all EVM chains are using the same keybundle. relay.NetworkEVM: node.FirstOCRKeybundle().KeyBundleID, @@ -39,8 +40,8 @@ func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string } else { spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ P2PV2Bootstrappers: []string{}, // Intentionally empty for bootstraps. - CapabilityVersion: CapabilityVersion, - CapabilityLabelledName: CapabilityLabelledName, + CapabilityVersion: changeset.CapabilityVersion, + CapabilityLabelledName: changeset.CapabilityLabelledName, OCRKeyBundleIDs: map[string]string{}, // TODO: validate that all EVM chains are using the same keybundle P2PKeyID: node.PeerID.String(), diff --git a/deployment/ccip/state.go b/deployment/ccip/state.go index f7fad230cc4..8ad308e6698 100644 --- a/deployment/ccip/state.go +++ b/deployment/ccip/state.go @@ -2,6 +2,8 @@ package ccipdeployment import ( "fmt" + + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_messenger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool" @@ -66,10 +68,10 @@ type CCIPChainState struct { // and the respective token contract // This is more of an illustration of how we'll have tokens, and it might need some work later to work properly. // Not all tokens will be burn and mint tokens. - BurnMintTokens677 map[TokenSymbol]*burn_mint_erc677.BurnMintERC677 + BurnMintTokens677 map[changeset.TokenSymbol]*burn_mint_erc677.BurnMintERC677 // Map between token Symbol (e.g. LinkSymbol, WethSymbol) // and the respective aggregator USD feed contract - USDFeeds map[TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface + USDFeeds map[changeset.TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface // Note we only expect one of these (on the home chain) CapabilityRegistry *capabilities_registry.CapabilitiesRegistry @@ -365,8 +367,8 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type if err != nil { return state, err } - state.BurnMintTokens677 = map[TokenSymbol]*burn_mint_erc677.BurnMintERC677{ - USDCSymbol: ut, + state.BurnMintTokens677 = map[changeset.TokenSymbol]*burn_mint_erc677.BurnMintERC677{ + changeset.USDCSymbol: ut, } case deployment.NewTypeAndVersion(USDCTokenPool, deployment.Version1_0_0).String(): utp, err := usdc_token_pool.NewUSDCTokenPool(common.HexToAddress(address), chain.Client) @@ -411,13 +413,13 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } if state.USDFeeds == nil { - state.USDFeeds = make(map[TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface) + state.USDFeeds = make(map[changeset.TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface) } desc, err := feed.Description(&bind.CallOpts{}) if err != nil { return state, err } - key, ok := MockDescriptionToTokenSymbol[desc] + key, ok := changeset.MockDescriptionToTokenSymbol[desc] if !ok { return state, fmt.Errorf("unknown feed description %s", desc) } diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index c65ea5ede9b..61dbf5ff6cc 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -52,7 +52,7 @@ import ( // DeployedLocalDevEnvironment is a helper struct for setting up a local dev environment with docker type DeployedLocalDevEnvironment struct { - ccipdeployment.DeployedEnv + changeset.DeployedEnv testEnv *test_env.CLClusterTestEnv DON *devenv.DON } @@ -78,14 +78,14 @@ func (d DeployedLocalDevEnvironment) RestartChainlinkNodes(t *testing.T) error { func NewLocalDevEnvironmentWithDefaultPrice( t *testing.T, - lggr logger.Logger) (ccipdeployment.DeployedEnv, *test_env.CLClusterTestEnv, testconfig.TestConfig) { - return NewLocalDevEnvironment(t, lggr, ccipdeployment.MockLinkPrice, ccipdeployment.MockWethPrice) + lggr logger.Logger) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, testconfig.TestConfig) { + return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice) } func NewLocalDevEnvironment( t *testing.T, lggr logger.Logger, - linkPrice, wethPrice *big.Int) (ccipdeployment.DeployedEnv, *test_env.CLClusterTestEnv, testconfig.TestConfig) { + linkPrice, wethPrice *big.Int) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, testconfig.TestConfig) { ctx := testcontext.Get(t) // create a local docker environment with simulated chains and job-distributor // we cannot create the chainlink nodes yet as we need to deploy the capability registry first @@ -100,11 +100,11 @@ func NewLocalDevEnvironment( require.NotEmpty(t, homeChainSel, "homeChainSel should not be empty") feedSel := envConfig.FeedChainSelector require.NotEmpty(t, feedSel, "feedSel should not be empty") - replayBlocks, err := ccipdeployment.LatestBlocksByChain(ctx, chains) + replayBlocks, err := changeset.LatestBlocksByChain(ctx, chains) require.NoError(t, err) ab := deployment.NewMemoryAddressBook() - crConfig := ccipdeployment.DeployTestContracts(t, lggr, ab, homeChainSel, feedSel, chains, linkPrice, wethPrice) + crConfig := changeset.DeployTestContracts(t, lggr, ab, homeChainSel, feedSel, chains, linkPrice, wethPrice) // start the chainlink nodes with the CR address err = StartChainlinkNodes(t, envConfig, @@ -120,10 +120,10 @@ func NewLocalDevEnvironment( envNodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) require.NoError(t, err) - _, err = ccipdeployment.DeployHomeChain(lggr, *e, e.ExistingAddresses, chains[homeChainSel], - ccipdeployment.NewTestRMNStaticConfig(), - ccipdeployment.NewTestRMNDynamicConfig(), - ccipdeployment.NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), + _, err = changeset.DeployHomeChain(lggr, *e, e.ExistingAddresses, chains[homeChainSel], + changeset.NewTestRMNStaticConfig(), + changeset.NewTestRMNDynamicConfig(), + changeset.NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), map[string][][32]byte{ "NodeOperator": envNodes.NonBootstraps().PeerIDs(), }, @@ -160,7 +160,7 @@ func NewLocalDevEnvironment( require.NoError(t, err) endpoint = e.MockAdapter.InternalEndpoint - tokenConfig := ccipdeployment.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) + tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) // Apply migration output, err = changeset.InitialDeploy(*e, ccipdeployment.DeployCCIPContractConfig{ HomeChainSel: homeChainSel, @@ -181,7 +181,7 @@ func NewLocalDevEnvironment( require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) // Ensure capreg logs are up to date. - ccipdeployment.ReplayLogs(t, e.Offchain, replayBlocks) + changeset.ReplayLogs(t, e.Offchain, replayBlocks) // Apply the jobs. for nodeID, jobs := range output.JobSpecs { @@ -196,7 +196,7 @@ func NewLocalDevEnvironment( } } - return ccipdeployment.DeployedEnv{ + return changeset.DeployedEnv{ Env: *e, HomeChainSel: homeChainSel, FeedChainSel: feedSel, @@ -208,7 +208,7 @@ func NewLocalDevEnvironmentWithRMN( t *testing.T, lggr logger.Logger, numRmnNodes int, -) (ccipdeployment.DeployedEnv, devenv.RMNCluster) { +) (changeset.DeployedEnv, devenv.RMNCluster) { tenv, dockerenv, testCfg := NewLocalDevEnvironmentWithDefaultPrice(t, lggr) l := logging.GetTestLogger(t) config := GenerateTestRMNConfig(t, numRmnNodes, tenv, MustNetworksToRPCMap(dockerenv.EVMNetworks)) @@ -255,7 +255,7 @@ func MustCCIPNameToRMNName(a string) string { return v } -func GenerateTestRMNConfig(t *testing.T, nRMNNodes int, tenv ccipdeployment.DeployedEnv, rpcMap map[uint64]string) map[string]devenv.RMNConfig { +func GenerateTestRMNConfig(t *testing.T, nRMNNodes int, tenv changeset.DeployedEnv, rpcMap map[uint64]string) map[string]devenv.RMNConfig { // Find the bootstrappers. nodes, err := deployment.NodeInfo(tenv.Env.NodeIDs, tenv.Env.Offchain) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip_messaging_test.go b/integration-tests/smoke/ccip_messaging_test.go index 6bb34658e22..ae3ff87e94f 100644 --- a/integration-tests/smoke/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip_messaging_test.go @@ -17,6 +17,8 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/deployment" ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" @@ -27,7 +29,7 @@ import ( type testCaseSetup struct { t *testing.T sender []byte - deployedEnv ccdeploy.DeployedEnv + deployedEnv changeset.DeployedEnv onchainState ccdeploy.CCIPOnChainState sourceChain, destChain uint64 } @@ -47,7 +49,7 @@ type messagingTestCaseOutput struct { func Test_CCIPMessaging(t *testing.T) { // Setup 2 chains and a single lane. lggr := logger.TestLogger(t) - ctx := ccdeploy.Context(t) + ctx := changeset.Context(t) e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) state, err := ccdeploy.LoadOnchainState(e.Env) @@ -64,7 +66,7 @@ func Test_CCIPMessaging(t *testing.T) { ", dest chain selector:", destChain, ) // connect a single lane, source to dest - require.NoError(t, ccdeploy.AddLaneWithDefaultPrices(e.Env, state, sourceChain, destChain)) + require.NoError(t, internal.AddLaneWithDefaultPrices(e.Env, state, sourceChain, destChain)) var ( replayed bool @@ -89,8 +91,8 @@ func Test_CCIPMessaging(t *testing.T) { }, common.HexToAddress("0xdead"), []byte("hello eoa"), - nil, // default extraArgs - ccdeploy.EXECUTION_STATE_SUCCESS, // success because offRamp won't call an EOA + nil, // default extraArgs + changeset.EXECUTION_STATE_SUCCESS, // success because offRamp won't call an EOA ) }) @@ -103,8 +105,8 @@ func Test_CCIPMessaging(t *testing.T) { }, state.Chains[destChain].FeeQuoter.Address(), []byte("hello FeeQuoter"), - nil, // default extraArgs - ccdeploy.EXECUTION_STATE_SUCCESS, // success because offRamp won't call a contract not implementing CCIPReceiver + nil, // default extraArgs + changeset.EXECUTION_STATE_SUCCESS, // success because offRamp won't call a contract not implementing CCIPReceiver ) }) @@ -120,7 +122,7 @@ func Test_CCIPMessaging(t *testing.T) { state.Chains[destChain].Receiver.Address(), []byte("hello CCIPReceiver"), nil, // default extraArgs - ccdeploy.EXECUTION_STATE_SUCCESS, + changeset.EXECUTION_STATE_SUCCESS, func(t *testing.T) { iter, err := state.Chains[destChain].Receiver.FilterMessageReceived(&bind.FilterOpts{ Context: ctx, @@ -144,8 +146,8 @@ func Test_CCIPMessaging(t *testing.T) { }, state.Chains[destChain].Receiver.Address(), []byte("hello CCIPReceiver with low exec gas"), - ccdeploy.MakeEVMExtraArgsV2(1, false), // 1 gas is too low. - ccdeploy.EXECUTION_STATE_FAILURE, // state would be failed onchain due to low gas + changeset.MakeEVMExtraArgsV2(1, false), // 1 gas is too low. + changeset.EXECUTION_STATE_FAILURE, // state would be failed onchain due to low gas ) manuallyExecute(ctx, t, latestHead.Number.Uint64(), state, destChain, out, sourceChain, e, sender) @@ -163,7 +165,7 @@ func manuallyExecute( destChain uint64, out messagingTestCaseOutput, sourceChain uint64, - e ccdeploy.DeployedEnv, + e changeset.DeployedEnv, sender []byte, ) { merkleRoot := getMerkleRoot( @@ -230,7 +232,7 @@ func manuallyExecute( newExecutionState, err := state.Chains[destChain].OffRamp.GetExecutionState(&bind.CallOpts{Context: ctx}, sourceChain, out.msgSentEvent.SequenceNumber) require.NoError(t, err) - require.Equal(t, uint8(ccdeploy.EXECUTION_STATE_SUCCESS), newExecutionState) + require.Equal(t, uint8(changeset.EXECUTION_STATE_SUCCESS), newExecutionState) } func getMerkleRoot( @@ -286,12 +288,12 @@ func getMessageHash( return iter.Event.MessageHash } -func sleepAndReplay(t *testing.T, e ccdeploy.DeployedEnv, sourceChain, destChain uint64) { +func sleepAndReplay(t *testing.T, e changeset.DeployedEnv, sourceChain, destChain uint64) { time.Sleep(30 * time.Second) replayBlocks := make(map[uint64]uint64) replayBlocks[sourceChain] = 1 replayBlocks[destChain] = 1 - ccdeploy.ReplayLogs(t, e.Env.Offchain, replayBlocks) + changeset.ReplayLogs(t, e.Env.Offchain, replayBlocks) } func runMessagingTestCase( @@ -310,7 +312,7 @@ func runMessagingTestCase( require.Equal(tc.t, tc.nonce, latestNonce) startBlocks := make(map[uint64]*uint64) - msgSentEvent := ccdeploy.TestSendRequest(tc.t, tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, false, router.ClientEVM2AnyMessage{ + msgSentEvent := changeset.TestSendRequest(tc.t, tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, false, router.ClientEVM2AnyMessage{ Receiver: common.LeftPadBytes(receiver.Bytes(), 32), Data: msgData, TokenAmounts: nil, @@ -327,8 +329,8 @@ func runMessagingTestCase( out.replayed = true } - ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) - execStates := ccdeploy.ConfirmExecWithSeqNrForAll(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) + changeset.ConfirmCommitForAllWithExpectedSeqNums(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) + execStates := changeset.ConfirmExecWithSeqNrForAll(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) require.Equalf( tc.t, diff --git a/integration-tests/smoke/ccip_rmn_test.go b/integration-tests/smoke/ccip_rmn_test.go index 4f44caccb52..54f5bcdfbf3 100644 --- a/integration-tests/smoke/ccip_rmn_test.go +++ b/integration-tests/smoke/ccip_rmn_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/deployment" ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" @@ -335,9 +336,9 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { } } - ccipdeployment.ReplayLogs(t, envWithRMN.Env.Offchain, envWithRMN.ReplayBlocks) + changeset.ReplayLogs(t, envWithRMN.Env.Offchain, envWithRMN.ReplayBlocks) // Add all lanes - require.NoError(t, ccipdeployment.AddLanesForAll(envWithRMN.Env, onChainState)) + require.NoError(t, changeset.AddLanesForAll(envWithRMN.Env, onChainState)) // 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) @@ -347,7 +348,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { toChain := chainSelectors[msg.toChainIdx] for i := 0; i < msg.count; i++ { - msgSentEvent := ccipdeployment.TestSendRequest(t, envWithRMN.Env, onChainState, fromChain, toChain, false, router.ClientEVM2AnyMessage{ + msgSentEvent := changeset.TestSendRequest(t, envWithRMN.Env, onChainState, fromChain, toChain, false, router.ClientEVM2AnyMessage{ Receiver: common.LeftPadBytes(onChainState.Chains[toChain].Receiver.Address().Bytes(), 32), Data: []byte("hello world"), TokenAmounts: nil, @@ -365,7 +366,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { commitReportReceived := make(chan struct{}) go func() { - ccipdeployment.ConfirmCommitForAllWithExpectedSeqNums(t, envWithRMN.Env, onChainState, expectedSeqNum, startBlocks) + changeset.ConfirmCommitForAllWithExpectedSeqNums(t, envWithRMN.Env, onChainState, expectedSeqNum, startBlocks) commitReportReceived <- struct{}{} }() @@ -387,7 +388,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { if tc.waitForExec { t.Logf("⌛ Waiting for exec reports...") - ccipdeployment.ConfirmExecWithSeqNrForAll(t, envWithRMN.Env, onChainState, expectedSeqNum, startBlocks) + changeset.ConfirmExecWithSeqNrForAll(t, envWithRMN.Env, onChainState, expectedSeqNum, startBlocks) t.Logf("✅ Exec report") } } diff --git a/integration-tests/smoke/ccip_test.go b/integration-tests/smoke/ccip_test.go index 36aed7d5baa..6acf31fc3f6 100644 --- a/integration-tests/smoke/ccip_test.go +++ b/integration-tests/smoke/ccip_test.go @@ -9,6 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -23,7 +24,7 @@ func TestInitialDeployOnLocal(t *testing.T) { require.NoError(t, err) // Add all lanes - require.NoError(t, ccdeploy.AddLanesForAll(e, state)) + require.NoError(t, changeset.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. @@ -37,7 +38,7 @@ func TestInitialDeployOnLocal(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 := changeset.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, @@ -49,7 +50,7 @@ func TestInitialDeployOnLocal(t *testing.T) { } // Wait for all commit reports to land. - ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) + changeset.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 { @@ -57,11 +58,11 @@ func TestInitialDeployOnLocal(t *testing.T) { 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, changeset.MockLinkPrice, timestampedPrice.Value) } // Wait for all exec reports to land - ccdeploy.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) + changeset.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) // TODO: Apply the proposal. } @@ -74,7 +75,7 @@ func TestTokenTransfer(t *testing.T) { state, err := ccdeploy.LoadOnchainState(e) require.NoError(t, err) - srcToken, _, dstToken, _, err := ccdeploy.DeployTransferableToken( + srcToken, _, dstToken, _, err := changeset.DeployTransferableToken( lggr, tenv.Env.Chains, tenv.HomeChainSel, @@ -86,7 +87,7 @@ func TestTokenTransfer(t *testing.T) { require.NoError(t, err) // Add all lanes - require.NoError(t, ccdeploy.AddLanesForAll(e, state)) + require.NoError(t, changeset.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. @@ -147,7 +148,7 @@ func TestTokenTransfer(t *testing.T) { feeToken = common.HexToAddress("0x0") ) if src == tenv.HomeChainSel && dest == tenv.FeedChainSel { - msgSentEvent := ccdeploy.TestSendRequest(t, e, state, src, dest, false, router.ClientEVM2AnyMessage{ + msgSentEvent := changeset.TestSendRequest(t, e, state, src, dest, false, router.ClientEVM2AnyMessage{ Receiver: receiver, Data: data, TokenAmounts: tokens[src], @@ -156,7 +157,7 @@ func TestTokenTransfer(t *testing.T) { }) expectedSeqNum[dest] = msgSentEvent.SequenceNumber } else { - msgSentEvent := ccdeploy.TestSendRequest(t, e, state, src, dest, false, router.ClientEVM2AnyMessage{ + msgSentEvent := changeset.TestSendRequest(t, e, state, src, dest, false, router.ClientEVM2AnyMessage{ Receiver: receiver, Data: data, TokenAmounts: nil, @@ -169,7 +170,7 @@ func TestTokenTransfer(t *testing.T) { } // Wait for all commit reports to land. - ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) + changeset.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 { @@ -177,11 +178,11 @@ func TestTokenTransfer(t *testing.T) { 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, changeset.MockLinkPrice, timestampedPrice.Value) } // Wait for all exec reports to land - ccdeploy.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) + changeset.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) balance, err := dstToken.BalanceOf(nil, state.Chains[tenv.FeedChainSel].Receiver.Address()) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip_usdc_test.go b/integration-tests/smoke/ccip_usdc_test.go index a183808f2f8..dd63bd59a99 100644 --- a/integration-tests/smoke/ccip_usdc_test.go +++ b/integration-tests/smoke/ccip_usdc_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment" ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" @@ -35,10 +36,10 @@ func TestUSDCTokenTransfer(t *testing.T) { sourceChain := allChainSelectors[0] destChain := allChainSelectors[1] - srcUSDC, dstUSDC, err := ccdeploy.ConfigureUSDCTokenPools(lggr, e.Chains, sourceChain, destChain, state) + srcUSDC, dstUSDC, err := changeset.ConfigureUSDCTokenPools(lggr, e.Chains, sourceChain, destChain, state) require.NoError(t, err) - srcToken, _, dstToken, _, err := ccdeploy.DeployTransferableToken( + srcToken, _, dstToken, _, err := changeset.DeployTransferableToken( lggr, tenv.Env.Chains, sourceChain, @@ -50,17 +51,17 @@ func TestUSDCTokenTransfer(t *testing.T) { require.NoError(t, err) // Add all lanes - require.NoError(t, ccdeploy.AddLanesForAll(e, state)) + require.NoError(t, changeset.AddLanesForAll(e, state)) mintAndAllow(t, e, state, map[uint64][]*burn_mint_erc677.BurnMintERC677{ sourceChain: {srcUSDC, srcToken}, destChain: {dstUSDC, dstToken}, }) - err = ccdeploy.UpdateFeeQuoterForUSDC(lggr, e.Chains[sourceChain], state.Chains[sourceChain], destChain, srcUSDC) + err = changeset.UpdateFeeQuoterForUSDC(lggr, e.Chains[sourceChain], state.Chains[sourceChain], destChain, srcUSDC) require.NoError(t, err) - err = ccdeploy.UpdateFeeQuoterForUSDC(lggr, e.Chains[destChain], state.Chains[destChain], sourceChain, dstUSDC) + err = changeset.UpdateFeeQuoterForUSDC(lggr, e.Chains[destChain], state.Chains[destChain], sourceChain, dstUSDC) require.NoError(t, err) // MockE2EUSDCTransmitter always mint 1, see MockE2EUSDCTransmitter.sol for more details @@ -220,7 +221,7 @@ func transferAndWaitForSuccess( block := latesthdr.Number.Uint64() startBlocks[destChain] = &block - msgSentEvent := ccdeploy.TestSendRequest(t, env, state, sourceChain, destChain, false, router.ClientEVM2AnyMessage{ + msgSentEvent := changeset.TestSendRequest(t, env, state, sourceChain, destChain, false, router.ClientEVM2AnyMessage{ Receiver: common.LeftPadBytes(receiver.Bytes(), 32), Data: data, TokenAmounts: tokens, @@ -230,10 +231,10 @@ func transferAndWaitForSuccess( expectedSeqNum[destChain] = msgSentEvent.SequenceNumber // Wait for all commit reports to land. - ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(t, env, state, expectedSeqNum, startBlocks) + changeset.ConfirmCommitForAllWithExpectedSeqNums(t, env, state, expectedSeqNum, startBlocks) // Wait for all exec reports to land - ccdeploy.ConfirmExecWithSeqNrForAll(t, env, state, expectedSeqNum, startBlocks) + changeset.ConfirmExecWithSeqNrForAll(t, env, state, expectedSeqNum, startBlocks) } func waitForTheTokenBalance( diff --git a/integration-tests/smoke/fee_boosting_test.go b/integration-tests/smoke/fee_boosting_test.go index 0e0fb094016..6bf8359d3c7 100644 --- a/integration-tests/smoke/fee_boosting_test.go +++ b/integration-tests/smoke/fee_boosting_test.go @@ -11,6 +11,8 @@ import ( "github.com/smartcontractkit/chainlink/deployment" ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -19,9 +21,9 @@ import ( type feeboostTestCase struct { t *testing.T sender []byte - deployedEnv ccdeploy.DeployedEnv + deployedEnv changeset.DeployedEnv onchainState ccdeploy.CCIPOnChainState - initialPrices ccdeploy.InitialPrices + initialPrices internal.InitialPrices priceFeedPrices priceFeedPrices sourceChain, destChain uint64 } @@ -33,7 +35,7 @@ type priceFeedPrices struct { // TODO: find a way to reuse the same test setup for all tests func Test_CCIPFeeBoosting(t *testing.T) { - setupTestEnv := func(t *testing.T, numChains int) (ccdeploy.DeployedEnv, ccdeploy.CCIPOnChainState, []uint64) { + setupTestEnv := func(t *testing.T, numChains int) (changeset.DeployedEnv, ccdeploy.CCIPOnChainState, []uint64) { e, _, _ := testsetups.NewLocalDevEnvironment( t, logger.TestLogger(t), deployment.E18Mult(5), @@ -54,10 +56,10 @@ func Test_CCIPFeeBoosting(t *testing.T) { sender: common.LeftPadBytes(e.Env.Chains[chains[0]].DeployerKey.From.Bytes(), 32), deployedEnv: e, onchainState: state, - initialPrices: ccdeploy.InitialPrices{ + initialPrices: internal.InitialPrices{ LinkPrice: deployment.E18Mult(5), WethPrice: deployment.E18Mult(9), - GasPrice: ccdeploy.ToPackedFee(big.NewInt(1.8e11), big.NewInt(0)), + GasPrice: changeset.ToPackedFee(big.NewInt(1.8e11), big.NewInt(0)), }, priceFeedPrices: priceFeedPrices{ linkPrice: deployment.E18Mult(5), @@ -75,10 +77,10 @@ func Test_CCIPFeeBoosting(t *testing.T) { sender: common.LeftPadBytes(e.Env.Chains[chains[0]].DeployerKey.From.Bytes(), 32), deployedEnv: e, onchainState: state, - initialPrices: ccdeploy.InitialPrices{ + initialPrices: internal.InitialPrices{ LinkPrice: deployment.E18Mult(5), WethPrice: deployment.E18Mult(9), - GasPrice: ccdeploy.ToPackedFee(big.NewInt(1.8e11), big.NewInt(0)), + GasPrice: changeset.ToPackedFee(big.NewInt(1.8e11), big.NewInt(0)), }, priceFeedPrices: priceFeedPrices{ linkPrice: big.NewInt(4.5e18), // decrease from 5e18 to 4.5e18 @@ -91,11 +93,11 @@ func Test_CCIPFeeBoosting(t *testing.T) { } func runFeeboostTestCase(tc feeboostTestCase) { - require.NoError(tc.t, ccdeploy.AddLane(tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, tc.initialPrices)) + require.NoError(tc.t, internal.AddLane(tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, tc.initialPrices)) startBlocks := make(map[uint64]*uint64) expectedSeqNum := make(map[uint64]uint64) - msgSentEvent := ccdeploy.TestSendRequest(tc.t, tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, false, router.ClientEVM2AnyMessage{ + msgSentEvent := changeset.TestSendRequest(tc.t, tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, false, router.ClientEVM2AnyMessage{ Receiver: common.LeftPadBytes(tc.onchainState.Chains[tc.destChain].Receiver.Address().Bytes(), 32), Data: []byte("message that needs fee boosting"), TokenAmounts: nil, @@ -109,8 +111,8 @@ func runFeeboostTestCase(tc feeboostTestCase) { replayBlocks := make(map[uint64]uint64) replayBlocks[tc.sourceChain] = 1 replayBlocks[tc.destChain] = 1 - ccdeploy.ReplayLogs(tc.t, tc.deployedEnv.Env.Offchain, replayBlocks) + changeset.ReplayLogs(tc.t, tc.deployedEnv.Env.Offchain, replayBlocks) - ccdeploy.ConfirmCommitForAllWithExpectedSeqNums(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) - ccdeploy.ConfirmExecWithSeqNrForAll(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) + changeset.ConfirmCommitForAllWithExpectedSeqNums(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) + changeset.ConfirmExecWithSeqNrForAll(tc.t, tc.deployedEnv.Env, tc.onchainState, expectedSeqNum, startBlocks) } From 95fd35a483f51e6e62e9a429b29706bb94b2564e Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 09:45:11 -0500 Subject: [PATCH 02/27] Move more files --- deployment/ccip/{ => changeset}/deploy.go | 0 deployment/ccip/{ => changeset}/deploy_test.go | 0 deployment/ccip/changeset/initial_deploy.go | 2 +- deployment/ccip/{ => changeset}/jobs.go | 11 +++++------ deployment/ccip/changeset/jobspec.go | 3 +-- deployment/ccip/changeset/test_helpers.go | 2 +- 6 files changed, 8 insertions(+), 10 deletions(-) rename deployment/ccip/{ => changeset}/deploy.go (100%) rename deployment/ccip/{ => changeset}/deploy_test.go (100%) rename deployment/ccip/{ => changeset}/jobs.go (85%) diff --git a/deployment/ccip/deploy.go b/deployment/ccip/changeset/deploy.go similarity index 100% rename from deployment/ccip/deploy.go rename to deployment/ccip/changeset/deploy.go diff --git a/deployment/ccip/deploy_test.go b/deployment/ccip/changeset/deploy_test.go similarity index 100% rename from deployment/ccip/deploy_test.go rename to deployment/ccip/changeset/deploy_test.go diff --git a/deployment/ccip/changeset/initial_deploy.go b/deployment/ccip/changeset/initial_deploy.go index de17834e8bd..5d9a9d0b91c 100644 --- a/deployment/ccip/changeset/initial_deploy.go +++ b/deployment/ccip/changeset/initial_deploy.go @@ -17,7 +17,7 @@ func InitialDeploy(env deployment.Environment, c ccipdeployment.DeployCCIPContra env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "newAddresses", newAddresses) return deployment.ChangesetOutput{AddressBook: newAddresses}, deployment.MaybeDataErr(err) } - js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain) + js, err := NewCCIPJobSpecs(env.NodeIDs, env.Offchain) if err != nil { return deployment.ChangesetOutput{AddressBook: newAddresses}, err } diff --git a/deployment/ccip/jobs.go b/deployment/ccip/changeset/jobs.go similarity index 85% rename from deployment/ccip/jobs.go rename to deployment/ccip/changeset/jobs.go index 4cd3a619153..5cfe112ff53 100644 --- a/deployment/ccip/jobs.go +++ b/deployment/ccip/changeset/jobs.go @@ -1,8 +1,7 @@ -package ccipdeployment +package changeset import ( "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) @@ -27,8 +26,8 @@ func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string if !node.IsBootstrap { spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ P2PV2Bootstrappers: nodes.BootstrapLocators(), - CapabilityVersion: changeset.CapabilityVersion, - CapabilityLabelledName: changeset.CapabilityLabelledName, + CapabilityVersion: CapabilityVersion, + CapabilityLabelledName: CapabilityLabelledName, OCRKeyBundleIDs: map[string]string{ // TODO: Validate that that all EVM chains are using the same keybundle. relay.NetworkEVM: node.FirstOCRKeybundle().KeyBundleID, @@ -40,8 +39,8 @@ func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string } else { spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ P2PV2Bootstrappers: []string{}, // Intentionally empty for bootstraps. - CapabilityVersion: changeset.CapabilityVersion, - CapabilityLabelledName: changeset.CapabilityLabelledName, + CapabilityVersion: CapabilityVersion, + CapabilityLabelledName: CapabilityLabelledName, OCRKeyBundleIDs: map[string]string{}, // TODO: validate that all EVM chains are using the same keybundle P2PKeyID: node.PeerID.String(), diff --git a/deployment/ccip/changeset/jobspec.go b/deployment/ccip/changeset/jobspec.go index 76352ff364f..bd968c97e1e 100644 --- a/deployment/ccip/changeset/jobspec.go +++ b/deployment/ccip/changeset/jobspec.go @@ -5,11 +5,10 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" ) func Jobspec(env deployment.Environment, _ any) (deployment.ChangesetOutput, error) { - js, err := ccipdeployment.NewCCIPJobSpecs(env.NodeIDs, env.Offchain) + js, err := NewCCIPJobSpecs(env.NodeIDs, env.Offchain) if err != nil { return deployment.ChangesetOutput{}, errors.Wrapf(err, "failed to create job specs") } diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 38490e9f9eb..a73075d7bf2 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -87,7 +87,7 @@ type DeployedEnv struct { func (e *DeployedEnv) SetupJobs(t *testing.T) { ctx := testcontext.Get(t) - jbs, err := ccipdeployment.NewCCIPJobSpecs(e.Env.NodeIDs, e.Env.Offchain) + jbs, err := NewCCIPJobSpecs(e.Env.NodeIDs, e.Env.Offchain) require.NoError(t, err) for nodeID, jobs := range jbs { for _, job := range jobs { From 654f3268d84d9fcb9506332ff28caf217df5fa0f Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 09:56:26 -0500 Subject: [PATCH 03/27] Move the rest --- deployment/ccip/changeset/active_candidate.go | 9 ++++---- .../ccip/changeset/active_candidate_test.go | 15 ++++++------ deployment/ccip/changeset/add_chain_test.go | 21 ++++++++--------- deployment/ccip/changeset/add_lane_test.go | 3 +-- deployment/ccip/changeset/deploy.go | 23 +++++++++---------- .../ccip/changeset/deploy_chain_test.go | 3 +-- deployment/ccip/changeset/deploy_test.go | 5 ++-- deployment/ccip/changeset/home_chain_test.go | 3 +-- .../ccip/changeset/initial_deploy_test.go | 10 ++++---- deployment/ccip/{ => changeset}/ownership.go | 2 +- .../ccip/changeset/prerequisites_test.go | 3 +-- deployment/ccip/{ => changeset}/propose.go | 2 +- .../ccip/changeset/save_existing_test.go | 13 +++++------ deployment/ccip/{ => changeset}/state.go | 15 ++++++------ .../smoke/ccip_messaging_test.go | 10 ++++---- integration-tests/smoke/ccip_rmn_test.go | 3 +-- integration-tests/smoke/ccip_test.go | 5 ++-- integration-tests/smoke/ccip_usdc_test.go | 7 +++--- integration-tests/smoke/fee_boosting_test.go | 16 ++++++------- 19 files changed, 74 insertions(+), 94 deletions(-) rename deployment/ccip/{ => changeset}/ownership.go (98%) rename deployment/ccip/{ => changeset}/propose.go (99%) rename deployment/ccip/{ => changeset}/state.go (96%) diff --git a/deployment/ccip/changeset/active_candidate.go b/deployment/ccip/changeset/active_candidate.go index 83315b22de9..f75d0e5e942 100644 --- a/deployment/ccip/changeset/active_candidate.go +++ b/deployment/ccip/changeset/active_candidate.go @@ -7,14 +7,13 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" 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) { @@ -28,7 +27,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) @@ -44,7 +43,7 @@ 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, @@ -82,7 +81,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) diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index 4929518a9c0..2734248da5a 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -16,7 +16,6 @@ import ( "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" @@ -28,7 +27,7 @@ func TestActiveCandidate(t *testing.T) { lggr := logger.TestLogger(t) 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 @@ -73,8 +72,8 @@ func TestActiveCandidate(t *testing.T) { 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() { @@ -94,7 +93,7 @@ func TestActiveCandidate(t *testing.T) { 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 @@ -135,7 +134,7 @@ func TestActiveCandidate(t *testing.T) { 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) @@ -153,7 +152,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) @@ -180,7 +179,7 @@ func TestActiveCandidate(t *testing.T) { 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) diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index abf4447af49..3dc18f5161c 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -5,7 +5,6 @@ import ( "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" @@ -32,14 +31,14 @@ import ( func TestAddChainInbound(t *testing.T) { // 4 chains where the 4th is added after initial deployment. e := NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), 4, 4) - state, err := ccipdeployment.LoadOnchainState(e.Env) + state, err := LoadOnchainState(e.Env) require.NoError(t, err) // Take first non-home chain as the new chain. newChain := e.Env.AllChainSelectorsExcluding([]uint64{e.HomeChainSel})[0] // We deploy to the rest. initialDeploy := e.Env.AllChainSelectorsExcluding([]uint64{newChain}) newAddresses := deployment.NewMemoryAddressBook() - err = ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy) + err = DeployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) @@ -59,7 +58,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) newAddresses = deployment.NewMemoryAddressBook() tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - err = ccipdeployment.DeployCCIPContracts(e.Env, newAddresses, ccipdeployment.DeployCCIPContractConfig{ + err = DeployCCIPContracts(e.Env, newAddresses, DeployCCIPContractConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: initialDeploy, @@ -68,7 +67,7 @@ func TestAddChainInbound(t *testing.T) { }) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - state, err = ccipdeployment.LoadOnchainState(e.Env) + state, err = LoadOnchainState(e.Env) require.NoError(t, err) // Connect all the existing lanes. @@ -80,7 +79,7 @@ func TestAddChainInbound(t *testing.T) { } } - rmnHomeAddress, err := deployment.SearchAddressBook(e.Env.ExistingAddresses, e.HomeChainSel, ccipdeployment.RMNHome) + rmnHomeAddress, err := deployment.SearchAddressBook(e.Env.ExistingAddresses, e.HomeChainSel, RMNHome) require.NoError(t, err) require.True(t, common.IsHexAddress(rmnHomeAddress)) rmnHome, err := rmn_home.NewRMNHome(common.HexToAddress(rmnHomeAddress), e.Env.Chains[e.HomeChainSel].Client) @@ -94,15 +93,15 @@ 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 = 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, + err = deployChainContracts(e.Env, e.Env.Chains[newChain], newAddresses, rmnHome) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - state, err = ccipdeployment.LoadOnchainState(e.Env) + state, err = LoadOnchainState(e.Env) require.NoError(t, err) // Transfer onramp/fq ownership to timelock. @@ -135,7 +134,7 @@ func TestAddChainInbound(t *testing.T) { _, err = deployment.ConfirmIfNoError(e.Env.Chains[e.HomeChainSel], tx, err) require.NoError(t, err) - acceptOwnershipProposal, err := ccipdeployment.GenerateAcceptOwnershipProposal(state, e.HomeChainSel, initialDeploy) + acceptOwnershipProposal, err := GenerateAcceptOwnershipProposal(state, e.HomeChainSel, initialDeploy) require.NoError(t, err) acceptOwnershipExec := commonchangeset.SignProposal(t, e.Env, acceptOwnershipProposal) // Apply the accept ownership proposal to all the chains. @@ -215,7 +214,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, err) // Assert the inbound lanes to the new chain are wired correctly. - state, err = ccipdeployment.LoadOnchainState(e.Env) + state, err = LoadOnchainState(e.Env) require.NoError(t, err) for _, chain := range initialDeploy { cfg, err2 := state.Chains[chain].OnRamp.GetDestChainConfig(nil, newChain) diff --git a/deployment/ccip/changeset/add_lane_test.go b/deployment/ccip/changeset/add_lane_test.go index 2d27925b536..4ad6f992bbd 100644 --- a/deployment/ccip/changeset/add_lane_test.go +++ b/deployment/ccip/changeset/add_lane_test.go @@ -10,7 +10,6 @@ import ( commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -23,7 +22,7 @@ func TestAddLane(t *testing.T) { // We add more chains to the chainlink nodes than the number of chains where CCIP is deployed. e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4) // Here we have CR + nodes set up, but no CCIP contracts deployed. - state, err := ccipdeployment.LoadOnchainState(e.Env) + state, err := LoadOnchainState(e.Env) require.NoError(t, err) selectors := e.Env.AllChainSelectors() diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index ea69a426f67..264127c9030 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "fmt" @@ -12,7 +12,6 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" @@ -283,7 +282,7 @@ type DeployCCIPContractConfig struct { HomeChainSel uint64 FeedChainSel uint64 ChainsToDeploy []uint64 - TokenConfig changeset.TokenConfig + TokenConfig TokenConfig USDCConfig USDCConfig // For setting OCR configuration OCRSecrets deployment.OCRSecrets @@ -338,7 +337,7 @@ func DeployCCIPContracts( return fmt.Errorf("chain %d not found", chainSel) } if c.USDCConfig.Enabled { - token, pool, messenger, transmitter, err1 := changeset.DeployUSDC(e.Logger, chain, ab, existingState.Chains[chainSel]) + token, pool, messenger, transmitter, err1 := DeployUSDC(e.Logger, chain, ab, existingState.Chains[chainSel]) if err1 != nil { return err1 } @@ -377,7 +376,7 @@ func DeployCCIPContracts( tokenInfo := c.TokenConfig.GetTokenInfo(e.Logger, existingState.Chains[chainSel].LinkToken, existingState.Chains[chainSel].Weth9) // TODO: Do we want to extract this? // Add chain config for each chain. - _, err = changeset.AddChainConfig( + _, err = AddChainConfig( e.Logger, e.Chains[c.HomeChainSel], ccipHome, @@ -400,7 +399,7 @@ func DeployCCIPContracts( }} } // For each chain, we create a DON on the home chain (2 OCR instances) - if err := changeset.AddDON( + if err := AddDON( e.Logger, c.OCRSecrets, capReg, @@ -439,15 +438,15 @@ func DeployChainContractsForChains( return fmt.Errorf("capability registry not found") } cr, err := capReg.GetHashedCapabilityId( - &bind.CallOpts{}, changeset.CapabilityLabelledName, changeset.CapabilityVersion) + &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) if err != nil { e.Logger.Errorw("Failed to get hashed capability id", "err", err) return err } - if cr != changeset.CCIPCapabilityID { - return fmt.Errorf("capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(changeset.CCIPCapabilityID[:])) + if cr != CCIPCapabilityID { + return fmt.Errorf("capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(CCIPCapabilityID[:])) } - capability, err := capReg.GetCapability(nil, changeset.CCIPCapabilityID) + capability, err := capReg.GetCapability(nil, CCIPCapabilityID) if err != nil { e.Logger.Errorw("Failed to get capability", "err", err) return err @@ -473,7 +472,7 @@ func DeployChainContractsForChains( if existingState.Chains[chainSel].LinkToken == nil || existingState.Chains[chainSel].Weth9 == nil { return fmt.Errorf("fee tokens not found for chain %d", chainSel) } - err := DeployChainContracts(e, chain, ab, rmnHome) + err := deployChainContracts(e, chain, ab, rmnHome) if err != nil { e.Logger.Errorw("Failed to deploy chain contracts", "chain", chainSel, "err", err) return fmt.Errorf("failed to deploy chain contracts for chain %d: %w", chainSel, err) @@ -482,7 +481,7 @@ func DeployChainContractsForChains( return nil } -func DeployChainContracts( +func deployChainContracts( e deployment.Environment, chain deployment.Chain, ab deployment.AddressBook, diff --git a/deployment/ccip/changeset/deploy_chain_test.go b/deployment/ccip/changeset/deploy_chain_test.go index 181287815c5..acab6fde6cb 100644 --- a/deployment/ccip/changeset/deploy_chain_test.go +++ b/deployment/ccip/changeset/deploy_chain_test.go @@ -8,7 +8,6 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink/deployment" - ccdeploy "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/deployment/environment/memory" @@ -71,7 +70,7 @@ func TestDeployChainContractsChangeset(t *testing.T) { require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) // load onchain state - state, err := ccdeploy.LoadOnchainState(e) + state, err := LoadOnchainState(e) require.NoError(t, err) // verify all contracts populated diff --git a/deployment/ccip/changeset/deploy_test.go b/deployment/ccip/changeset/deploy_test.go index d5f5cb41e90..5054ac2dba5 100644 --- a/deployment/ccip/changeset/deploy_test.go +++ b/deployment/ccip/changeset/deploy_test.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "encoding/json" @@ -7,13 +7,12 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestDeployCCIPContracts(t *testing.T) { lggr := logger.TestLogger(t) - e := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, + e := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, ) diff --git a/deployment/ccip/changeset/home_chain_test.go b/deployment/ccip/changeset/home_chain_test.go index 1b3fad73924..55bc7466837 100644 --- a/deployment/ccip/changeset/home_chain_test.go +++ b/deployment/ccip/changeset/home_chain_test.go @@ -8,7 +8,6 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink/deployment" - ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -37,7 +36,7 @@ func TestDeployHomeChain(t *testing.T) { output, err := DeployHomeChain(e, homeChainCfg) require.NoError(t, err) require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) - state, err := ccdeploy.LoadOnchainState(e) + state, err := LoadOnchainState(e) require.NoError(t, err) require.NotNil(t, state.Chains[homeChainSel].CapabilityRegistry) require.NotNil(t, state.Chains[homeChainSel].CCIPHome) diff --git a/deployment/ccip/changeset/initial_deploy_test.go b/deployment/ccip/changeset/initial_deploy_test.go index 53eb7c0dc1d..14958f68d9c 100644 --- a/deployment/ccip/changeset/initial_deploy_test.go +++ b/deployment/ccip/changeset/initial_deploy_test.go @@ -10,10 +10,8 @@ import ( 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" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -27,7 +25,7 @@ func TestInitialDeploy(t *testing.T) { tenv := NewMemoryEnvironment(t, lggr, 3, 4, MockLinkPrice, MockWethPrice) e := tenv.Env - state, err := ccdeploy.LoadOnchainState(tenv.Env) + state, err := LoadOnchainState(tenv.Env) require.NoError(t, err) output, err := DeployPrerequisites(e, DeployPrerequisiteConfig{ ChainSelectors: tenv.Env.AllChainSelectors(), @@ -49,7 +47,7 @@ func TestInitialDeploy(t *testing.T) { require.NoError(t, err) require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) - output, err = InitialDeploy(tenv.Env, ccdeploy.DeployCCIPContractConfig{ + output, err = InitialDeploy(tenv.Env, DeployCCIPContractConfig{ HomeChainSel: tenv.HomeChainSel, FeedChainSel: tenv.FeedChainSel, ChainsToDeploy: tenv.Env.AllChainSelectors(), @@ -59,7 +57,7 @@ func TestInitialDeploy(t *testing.T) { require.NoError(t, err) // Get new state after migration. require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook)) - state, err = ccdeploy.LoadOnchainState(e) + state, err = LoadOnchainState(e) require.NoError(t, err) require.NotNil(t, state.Chains[tenv.HomeChainSel].LinkToken) // Ensure capreg logs are up to date. diff --git a/deployment/ccip/ownership.go b/deployment/ccip/changeset/ownership.go similarity index 98% rename from deployment/ccip/ownership.go rename to deployment/ccip/changeset/ownership.go index ebc3ed60d09..4287363b8a6 100644 --- a/deployment/ccip/ownership.go +++ b/deployment/ccip/changeset/ownership.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "testing" diff --git a/deployment/ccip/changeset/prerequisites_test.go b/deployment/ccip/changeset/prerequisites_test.go index 94d5c8d0581..1a167b2816c 100644 --- a/deployment/ccip/changeset/prerequisites_test.go +++ b/deployment/ccip/changeset/prerequisites_test.go @@ -6,7 +6,6 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -27,7 +26,7 @@ func TestDeployPrerequisites(t *testing.T) { require.NoError(t, err) err = e.ExistingAddresses.Merge(output.AddressBook) require.NoError(t, err) - state, err := ccipdeployment.LoadOnchainState(e) + state, err := LoadOnchainState(e) require.NoError(t, err) require.NotNil(t, state.Chains[newChain].LinkToken) require.NotNil(t, state.Chains[newChain].Weth9) diff --git a/deployment/ccip/propose.go b/deployment/ccip/changeset/propose.go similarity index 99% rename from deployment/ccip/propose.go rename to deployment/ccip/changeset/propose.go index d7baf9ab542..1b7d928f414 100644 --- a/deployment/ccip/propose.go +++ b/deployment/ccip/changeset/propose.go @@ -1,4 +1,4 @@ -package ccipdeployment +package changeset import ( "fmt" diff --git a/deployment/ccip/changeset/save_existing_test.go b/deployment/ccip/changeset/save_existing_test.go index 5f09c13b272..c3f25870d2e 100644 --- a/deployment/ccip/changeset/save_existing_test.go +++ b/deployment/ccip/changeset/save_existing_test.go @@ -9,7 +9,6 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -29,27 +28,27 @@ func TestSaveExisting(t *testing.T) { ExistingContracts: []Contract{ { Address: common.BigToAddress(big.NewInt(1)), - TypeAndVersion: deployment.NewTypeAndVersion(ccipdeployment.LinkToken, deployment.Version1_0_0), + TypeAndVersion: deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0), ChainSelector: chain1, }, { Address: common.BigToAddress(big.NewInt(2)), - TypeAndVersion: deployment.NewTypeAndVersion(ccipdeployment.WETH9, deployment.Version1_0_0), + TypeAndVersion: deployment.NewTypeAndVersion(WETH9, deployment.Version1_0_0), ChainSelector: chain1, }, { Address: common.BigToAddress(big.NewInt(3)), - TypeAndVersion: deployment.NewTypeAndVersion(ccipdeployment.TokenAdminRegistry, deployment.Version1_5_0), + TypeAndVersion: deployment.NewTypeAndVersion(TokenAdminRegistry, deployment.Version1_5_0), ChainSelector: chain1, }, { Address: common.BigToAddress(big.NewInt(4)), - TypeAndVersion: deployment.NewTypeAndVersion(ccipdeployment.RegistryModule, deployment.Version1_5_0), + TypeAndVersion: deployment.NewTypeAndVersion(RegistryModule, deployment.Version1_5_0), ChainSelector: chain2, }, { Address: common.BigToAddress(big.NewInt(5)), - TypeAndVersion: deployment.NewTypeAndVersion(ccipdeployment.Router, deployment.Version1_2_0), + TypeAndVersion: deployment.NewTypeAndVersion(Router, deployment.Version1_2_0), ChainSelector: chain2, }, }, @@ -59,7 +58,7 @@ func TestSaveExisting(t *testing.T) { require.NoError(t, err) err = e.ExistingAddresses.Merge(output.AddressBook) require.NoError(t, err) - state, err := ccipdeployment.LoadOnchainState(e) + state, err := LoadOnchainState(e) require.NoError(t, err) require.Equal(t, state.Chains[chain1].LinkToken.Address(), common.BigToAddress(big.NewInt(1))) require.Equal(t, state.Chains[chain1].Weth9.Address(), common.BigToAddress(big.NewInt(2))) diff --git a/deployment/ccip/state.go b/deployment/ccip/changeset/state.go similarity index 96% rename from deployment/ccip/state.go rename to deployment/ccip/changeset/state.go index 8ad308e6698..a8b3fb04c96 100644 --- a/deployment/ccip/state.go +++ b/deployment/ccip/changeset/state.go @@ -1,9 +1,8 @@ -package ccipdeployment +package changeset import ( "fmt" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_messenger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/usdc_token_pool" @@ -68,10 +67,10 @@ type CCIPChainState struct { // and the respective token contract // This is more of an illustration of how we'll have tokens, and it might need some work later to work properly. // Not all tokens will be burn and mint tokens. - BurnMintTokens677 map[changeset.TokenSymbol]*burn_mint_erc677.BurnMintERC677 + BurnMintTokens677 map[TokenSymbol]*burn_mint_erc677.BurnMintERC677 // Map between token Symbol (e.g. LinkSymbol, WethSymbol) // and the respective aggregator USD feed contract - USDFeeds map[changeset.TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface + USDFeeds map[TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface // Note we only expect one of these (on the home chain) CapabilityRegistry *capabilities_registry.CapabilitiesRegistry @@ -367,8 +366,8 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type if err != nil { return state, err } - state.BurnMintTokens677 = map[changeset.TokenSymbol]*burn_mint_erc677.BurnMintERC677{ - changeset.USDCSymbol: ut, + state.BurnMintTokens677 = map[TokenSymbol]*burn_mint_erc677.BurnMintERC677{ + USDCSymbol: ut, } case deployment.NewTypeAndVersion(USDCTokenPool, deployment.Version1_0_0).String(): utp, err := usdc_token_pool.NewUSDCTokenPool(common.HexToAddress(address), chain.Client) @@ -413,13 +412,13 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } if state.USDFeeds == nil { - state.USDFeeds = make(map[changeset.TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface) + state.USDFeeds = make(map[TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface) } desc, err := feed.Description(&bind.CallOpts{}) if err != nil { return state, err } - key, ok := changeset.MockDescriptionToTokenSymbol[desc] + key, ok := MockDescriptionToTokenSymbol[desc] if !ok { return state, fmt.Errorf("unknown feed description %s", desc) } diff --git a/integration-tests/smoke/ccip_messaging_test.go b/integration-tests/smoke/ccip_messaging_test.go index ae3ff87e94f..25e8949cb79 100644 --- a/integration-tests/smoke/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip_messaging_test.go @@ -16,9 +16,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/deployment" - ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" @@ -30,7 +28,7 @@ type testCaseSetup struct { t *testing.T sender []byte deployedEnv changeset.DeployedEnv - onchainState ccdeploy.CCIPOnChainState + onchainState changeset.CCIPOnChainState sourceChain, destChain uint64 } @@ -52,7 +50,7 @@ func Test_CCIPMessaging(t *testing.T) { ctx := changeset.Context(t) e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) - state, err := ccdeploy.LoadOnchainState(e.Env) + state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) allChainSelectors := maps.Keys(e.Env.Chains) @@ -66,7 +64,7 @@ func Test_CCIPMessaging(t *testing.T) { ", dest chain selector:", destChain, ) // connect a single lane, source to dest - require.NoError(t, internal.AddLaneWithDefaultPrices(e.Env, state, sourceChain, destChain)) + require.NoError(t, changeset.AddLaneWithDefaultPrices(e.Env, state, sourceChain, destChain)) var ( replayed bool @@ -161,7 +159,7 @@ func manuallyExecute( ctx context.Context, t *testing.T, startBlock uint64, - state ccdeploy.CCIPOnChainState, + state changeset.CCIPOnChainState, destChain uint64, out messagingTestCaseOutput, sourceChain uint64, diff --git a/integration-tests/smoke/ccip_rmn_test.go b/integration-tests/smoke/ccip_rmn_test.go index 54f5bcdfbf3..f19c7fe1d24 100644 --- a/integration-tests/smoke/ccip_rmn_test.go +++ b/integration-tests/smoke/ccip_rmn_test.go @@ -18,7 +18,6 @@ import ( "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -232,7 +231,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { }) } - onChainState, err := ccipdeployment.LoadOnchainState(envWithRMN.Env) + onChainState, err := changeset.LoadOnchainState(envWithRMN.Env) require.NoError(t, err) t.Logf("onChainState: %#v", onChainState) diff --git a/integration-tests/smoke/ccip_test.go b/integration-tests/smoke/ccip_test.go index 6acf31fc3f6..04ec25188ef 100644 --- a/integration-tests/smoke/ccip_test.go +++ b/integration-tests/smoke/ccip_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -20,7 +19,7 @@ func TestInitialDeployOnLocal(t *testing.T) { lggr := logger.TestLogger(t) tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) e := tenv.Env - state, err := ccdeploy.LoadOnchainState(e) + state, err := changeset.LoadOnchainState(e) require.NoError(t, err) // Add all lanes @@ -72,7 +71,7 @@ func TestTokenTransfer(t *testing.T) { lggr := logger.TestLogger(t) tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) e := tenv.Env - state, err := ccdeploy.LoadOnchainState(e) + state, err := changeset.LoadOnchainState(e) require.NoError(t, err) srcToken, _, dstToken, _, err := changeset.DeployTransferableToken( diff --git a/integration-tests/smoke/ccip_usdc_test.go b/integration-tests/smoke/ccip_usdc_test.go index dd63bd59a99..51cf42e6562 100644 --- a/integration-tests/smoke/ccip_usdc_test.go +++ b/integration-tests/smoke/ccip_usdc_test.go @@ -14,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment" - ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" @@ -29,7 +28,7 @@ func TestUSDCTokenTransfer(t *testing.T) { tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) e := tenv.Env - state, err := ccdeploy.LoadOnchainState(e) + state, err := changeset.LoadOnchainState(e) require.NoError(t, err) allChainSelectors := maps.Keys(e.Chains) @@ -179,7 +178,7 @@ func TestUSDCTokenTransfer(t *testing.T) { func mintAndAllow( t *testing.T, e deployment.Environment, - state ccdeploy.CCIPOnChainState, + state changeset.CCIPOnChainState, tkMap map[uint64][]*burn_mint_erc677.BurnMintERC677, ) { for chain, tokens := range tkMap { @@ -207,7 +206,7 @@ func mintAndAllow( func transferAndWaitForSuccess( t *testing.T, env deployment.Environment, - state ccdeploy.CCIPOnChainState, + state changeset.CCIPOnChainState, sourceChain, destChain uint64, tokens []router.ClientEVMTokenAmount, receiver common.Address, diff --git a/integration-tests/smoke/fee_boosting_test.go b/integration-tests/smoke/fee_boosting_test.go index 6bf8359d3c7..bf2f69e7402 100644 --- a/integration-tests/smoke/fee_boosting_test.go +++ b/integration-tests/smoke/fee_boosting_test.go @@ -10,9 +10,7 @@ import ( "golang.org/x/exp/maps" "github.com/smartcontractkit/chainlink/deployment" - ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -22,8 +20,8 @@ type feeboostTestCase struct { t *testing.T sender []byte deployedEnv changeset.DeployedEnv - onchainState ccdeploy.CCIPOnChainState - initialPrices internal.InitialPrices + onchainState changeset.CCIPOnChainState + initialPrices changeset.InitialPrices priceFeedPrices priceFeedPrices sourceChain, destChain uint64 } @@ -35,13 +33,13 @@ type priceFeedPrices struct { // TODO: find a way to reuse the same test setup for all tests func Test_CCIPFeeBoosting(t *testing.T) { - setupTestEnv := func(t *testing.T, numChains int) (changeset.DeployedEnv, ccdeploy.CCIPOnChainState, []uint64) { + setupTestEnv := func(t *testing.T, numChains int) (changeset.DeployedEnv, changeset.CCIPOnChainState, []uint64) { e, _, _ := testsetups.NewLocalDevEnvironment( t, logger.TestLogger(t), deployment.E18Mult(5), big.NewInt(9e8)) - state, err := ccdeploy.LoadOnchainState(e.Env) + state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) allChainSelectors := maps.Keys(e.Env.Chains) @@ -56,7 +54,7 @@ func Test_CCIPFeeBoosting(t *testing.T) { sender: common.LeftPadBytes(e.Env.Chains[chains[0]].DeployerKey.From.Bytes(), 32), deployedEnv: e, onchainState: state, - initialPrices: internal.InitialPrices{ + initialPrices: changeset.InitialPrices{ LinkPrice: deployment.E18Mult(5), WethPrice: deployment.E18Mult(9), GasPrice: changeset.ToPackedFee(big.NewInt(1.8e11), big.NewInt(0)), @@ -77,7 +75,7 @@ func Test_CCIPFeeBoosting(t *testing.T) { sender: common.LeftPadBytes(e.Env.Chains[chains[0]].DeployerKey.From.Bytes(), 32), deployedEnv: e, onchainState: state, - initialPrices: internal.InitialPrices{ + initialPrices: changeset.InitialPrices{ LinkPrice: deployment.E18Mult(5), WethPrice: deployment.E18Mult(9), GasPrice: changeset.ToPackedFee(big.NewInt(1.8e11), big.NewInt(0)), @@ -93,7 +91,7 @@ func Test_CCIPFeeBoosting(t *testing.T) { } func runFeeboostTestCase(tc feeboostTestCase) { - require.NoError(tc.t, internal.AddLane(tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, tc.initialPrices)) + require.NoError(tc.t, changeset.AddLane(tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, tc.initialPrices)) startBlocks := make(map[uint64]*uint64) expectedSeqNum := make(map[uint64]uint64) From d8fc0dcdc999ea90f41a1391249bfa8fe214e08f Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 10:04:39 -0500 Subject: [PATCH 04/27] Move some files to internal --- deployment/ccip/changeset/add_chain.go | 9 ++--- deployment/ccip/changeset/add_chain_test.go | 5 ++- .../{ => internal}/active_candidate.go | 15 +++---- .../active_candidate_helpers.go | 15 +++---- .../{ => internal}/active_candidate_test.go | 39 ++++++++++--------- .../changeset/{ => internal}/ownership.go | 2 +- .../ccip-tests/testsetups/test_helpers.go | 31 ++++++++------- 7 files changed, 60 insertions(+), 56 deletions(-) rename deployment/ccip/changeset/{ => internal}/active_candidate.go (86%) rename deployment/ccip/changeset/{ => internal}/active_candidate_helpers.go (90%) rename deployment/ccip/changeset/{ => internal}/active_candidate_test.go (82%) rename deployment/ccip/changeset/{ => internal}/ownership.go (98%) diff --git a/deployment/ccip/changeset/add_chain.go b/deployment/ccip/changeset/add_chain.go index 1039f87dcc6..f58da7b4e5d 100644 --- a/deployment/ccip/changeset/add_chain.go +++ b/deployment/ccip/changeset/add_chain.go @@ -4,7 +4,6 @@ import ( "fmt" "math/big" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" @@ -19,7 +18,7 @@ import ( // to connect the new chain to the existing chains. func NewChainInboundChangeset( e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, homeChainSel uint64, newChainSel uint64, sources []uint64, @@ -77,7 +76,7 @@ func NewChainInboundChangeset( }, }) - prop, err := ccipdeployment.BuildProposalFromBatches(state, batches, "proposal to set new chains", 0) + prop, err := BuildProposalFromBatches(state, batches, "proposal to set new chains", 0) if err != nil { return deployment.ChangesetOutput{}, err } @@ -90,7 +89,7 @@ func NewChainInboundChangeset( // AddDonAndSetCandidateChangeset adds new DON for destination to home chain // and sets the commit plugin config as candidateConfig for the don. func AddDonAndSetCandidateChangeset( - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, e deployment.Environment, nodes deployment.Nodes, ocrSecrets deployment.OCRSecrets, @@ -129,7 +128,7 @@ func AddDonAndSetCandidateChangeset( return deployment.ChangesetOutput{}, err } - prop, err := ccipdeployment.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + prop, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(homeChainSel), Batch: []mcms.Operation{addDonOp}, }}, "setCandidate for commit and AddDon on new Chain", 0) diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 3dc18f5161c..20f89bffb14 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" 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" @@ -171,12 +172,12 @@ func TestAddChainInbound(t *testing.T) { ProcessChangeset(t, 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) + setCandidateForExecChangeset, err := internal.SetCandidatePluginChangeset(state, e.Env, nodes, deployment.XXXGenerateTestOCRSecrets(), e.HomeChainSel, e.FeedChainSel, newChain, tokenConfig, types.PluginTypeCCIPExec) require.NoError(t, err) ProcessChangeset(t, 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) + donPromoteChangeset, err := internal.PromoteAllCandidatesChangeset(state, e.HomeChainSel, newChain, nodes) require.NoError(t, err) ProcessChangeset(t, e.Env, donPromoteChangeset) diff --git a/deployment/ccip/changeset/active_candidate.go b/deployment/ccip/changeset/internal/active_candidate.go similarity index 86% rename from deployment/ccip/changeset/active_candidate.go rename to deployment/ccip/changeset/internal/active_candidate.go index f75d0e5e942..8a1b934fc4d 100644 --- a/deployment/ccip/changeset/active_candidate.go +++ b/deployment/ccip/changeset/internal/active_candidate.go @@ -1,4 +1,4 @@ -package changeset +package internal import ( "fmt" @@ -7,13 +7,14 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" 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 CCIPOnChainState, + state changeset.CCIPOnChainState, homeChainSel, newChainSel uint64, nodes deployment.Nodes, ) (deployment.ChangesetOutput, error) { @@ -27,7 +28,7 @@ func PromoteAllCandidatesChangeset( return deployment.ChangesetOutput{}, err } - prop, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + prop, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(homeChainSel), Batch: promoteCandidateOps, }}, "promoteCandidate for commit and execution", 0) @@ -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 CCIPOnChainState, + state changeset.CCIPOnChainState, e deployment.Environment, nodes deployment.Nodes, ocrSecrets deployment.OCRSecrets, homeChainSel, feedChainSel, newChainSel uint64, - tokenConfig TokenConfig, + tokenConfig changeset.TokenConfig, pluginType cctypes.PluginType, ) (deployment.ChangesetOutput, error) { - newDONArgs, err := BuildOCR3ConfigForCCIPHome( + newDONArgs, err := changeset.BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], @@ -81,7 +82,7 @@ func SetCandidatePluginChangeset( return deployment.ChangesetOutput{}, err } - prop, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + prop, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(homeChainSel), Batch: setCandidateMCMSOps, }}, "SetCandidate for execution", 0) diff --git a/deployment/ccip/changeset/active_candidate_helpers.go b/deployment/ccip/changeset/internal/active_candidate_helpers.go similarity index 90% rename from deployment/ccip/changeset/active_candidate_helpers.go rename to deployment/ccip/changeset/internal/active_candidate_helpers.go index 914f8fc0c17..26d552ccb77 100644 --- a/deployment/ccip/changeset/active_candidate_helpers.go +++ b/deployment/ccip/changeset/internal/active_candidate_helpers.go @@ -1,4 +1,4 @@ -package changeset +package internal import ( "fmt" @@ -7,6 +7,7 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" 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" @@ -22,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 := changeset.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 := changeset.CCIPHomeABI.Pack( "setCandidate", donID, pluginConfig.PluginType, @@ -45,7 +46,7 @@ func SetCandidateOnExistingDon( nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ { - CapabilityId: CCIPCapabilityID, + CapabilityId: changeset.CCIPCapabilityID, Config: encodedSetCandidateCall, }, }, @@ -77,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 := changeset.CCIPHomeABI.Pack( "promoteCandidateAndRevokeActive", donID, pluginType, @@ -94,7 +95,7 @@ func PromoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ { - CapabilityId: CCIPCapabilityID, + CapabilityId: changeset.CCIPCapabilityID, Config: encodedPromotionCall, }, }, @@ -119,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 := changeset.DonIDForChain(capReg, ccipHome, chainSelector) if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/internal/active_candidate_test.go similarity index 82% rename from deployment/ccip/changeset/active_candidate_test.go rename to deployment/ccip/changeset/internal/active_candidate_test.go index 2734248da5a..96f120db58d 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/internal/active_candidate_test.go @@ -1,4 +1,4 @@ -package changeset +package internal import ( "testing" @@ -8,6 +8,7 @@ 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" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -25,13 +26,13 @@ func TestActiveCandidate(t *testing.T) { t.Skipf("to be enabled after latest cl-ccip is compatible") lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5) + tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5) e := tenv.Env - state, err := LoadOnchainState(tenv.Env) + state, err := changeset.LoadOnchainState(tenv.Env) require.NoError(t, err) // Add all lanes - require.NoError(t, AddLanesForAll(e, state)) + require.NoError(t, changeset.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. @@ -45,7 +46,7 @@ func TestActiveCandidate(t *testing.T) { require.NoError(t, err) block := latesthdr.Number.Uint64() startBlocks[dest] = &block - msgSentEvent := TestSendRequest(t, e, state, src, dest, false, router.ClientEVM2AnyMessage{ + msgSentEvent := changeset.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, @@ -57,7 +58,7 @@ func TestActiveCandidate(t *testing.T) { } // Wait for all commit reports to land. - ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) + changeset.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 { @@ -65,15 +66,15 @@ func TestActiveCandidate(t *testing.T) { feeQuoter := state.Chains[dest].FeeQuoter timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress) require.NoError(t, err) - require.Equal(t, MockLinkPrice, timestampedPrice.Value) + require.Equal(t, changeset.MockLinkPrice, timestampedPrice.Value) } //Wait for all exec reports to land - ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) + changeset.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) // transfer ownership TransferAllOwnership(t, state, tenv.HomeChainSel, e) - acceptOwnershipProposal, err := GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors()) + acceptOwnershipProposal, err := changeset.GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors()) require.NoError(t, err) acceptOwnershipExec := commonchangeset.SignProposal(t, e, acceptOwnershipProposal) for _, sel := range e.AllChainSelectors() { @@ -81,19 +82,19 @@ func TestActiveCandidate(t *testing.T) { } // Apply the accept ownership proposal to all the chains. - err = ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 2) + err = changeset.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 := DonIDForChain(capReg, ccipHome, tenv.FeedChainSel) + donID, err := changeset.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 = LoadOnchainState(e) + state, err = changeset.LoadOnchainState(e) require.NoError(t, err) // delete a non-bootstrap node @@ -113,8 +114,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 := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) - ocr3ConfigMap, err := BuildOCR3ConfigForCCIPHome( + tokenConfig := changeset.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) + ocr3ConfigMap, err := changeset.BuildOCR3ConfigForCCIPHome( deployment.XXXGenerateTestOCRSecrets(), state.Chains[tenv.FeedChainSel].OffRamp, e.Chains[tenv.FeedChainSel], @@ -134,7 +135,7 @@ func TestActiveCandidate(t *testing.T) { nodes.NonBootstraps(), ) require.NoError(t, err) - setCommitCandidateProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + setCommitCandidateProposal, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), Batch: setCommitCandidateOp, }}, "set new candidates on commit plugin", 0) @@ -152,7 +153,7 @@ func TestActiveCandidate(t *testing.T) { ) require.NoError(t, err) - setExecCandidateProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + setExecCandidateProposal, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), Batch: setExecCandidateOp, }}, "set new candidates on commit and exec plugins", 0) @@ -168,7 +169,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 = ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 3) + err = changeset.ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 3) require.NoError(t, err) // [ACTIVE, CANDIDATE] done send successful transaction on active @@ -179,7 +180,7 @@ func TestActiveCandidate(t *testing.T) { promoteOps, err := PromoteAllCandidatesForChainOps(state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome, tenv.FeedChainSel, nodes.NonBootstraps()) require.NoError(t, err) - promoteProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + promoteProposal, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), Batch: promoteOps, }}, "promote candidates and revoke actives", 0) @@ -203,7 +204,7 @@ func TestActiveCandidate(t *testing.T) { require.NoError(t, err) require.Equal(t, uint32(8), donInfo.ConfigCount) - err = ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 4) + err = changeset.ConfirmRequestOnSourceAndDest(t, e, state, tenv.HomeChainSel, tenv.FeedChainSel, 4) require.NoError(t, err) // [NEW ACTIVE, NO CANDIDATE] done sending successful request } diff --git a/deployment/ccip/changeset/ownership.go b/deployment/ccip/changeset/internal/ownership.go similarity index 98% rename from deployment/ccip/changeset/ownership.go rename to deployment/ccip/changeset/internal/ownership.go index 4287363b8a6..50eb8e12b48 100644 --- a/deployment/ccip/changeset/ownership.go +++ b/deployment/ccip/changeset/internal/ownership.go @@ -1,4 +1,4 @@ -package changeset +package internal import ( "testing" diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index 61dbf5ff6cc..042a768a96c 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -21,12 +21,10 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink-testing-framework/seth" - commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" - commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" - "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/environment/devenv" clclient "github.com/smartcontractkit/chainlink/deployment/environment/nodeclient" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -120,12 +118,15 @@ func NewLocalDevEnvironment( envNodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) require.NoError(t, err) - _, err = changeset.DeployHomeChain(lggr, *e, e.ExistingAddresses, chains[homeChainSel], - changeset.NewTestRMNStaticConfig(), - changeset.NewTestRMNDynamicConfig(), - changeset.NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), - map[string][][32]byte{ - "NodeOperator": envNodes.NonBootstraps().PeerIDs(), + _, err = changeset.DeployHomeChain(*e, + changeset.DeployHomeChainConfig{ + HomeChainSel: homeChainSel, + RMNStaticConfig: changeset.NewTestRMNStaticConfig(), + RMNDynamicConfig: changeset.NewTestRMNDynamicConfig(), + NodeOperators: changeset.NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), + NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ + "NodeOperator": envNodes.NonBootstraps().PeerIDs(), + }, }, ) require.NoError(t, err) @@ -152,7 +153,7 @@ func NewLocalDevEnvironment( require.NoError(t, err) require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) - state, err := ccipdeployment.LoadOnchainState(*e) + state, err := changeset.LoadOnchainState(*e) require.NoError(t, err) var endpoint string @@ -162,15 +163,15 @@ func NewLocalDevEnvironment( tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) // Apply migration - output, err = changeset.InitialDeploy(*e, ccipdeployment.DeployCCIPContractConfig{ + output, err = changeset.InitialDeploy(*e, changeset.DeployCCIPContractConfig{ HomeChainSel: homeChainSel, FeedChainSel: feedSel, ChainsToDeploy: e.AllChainSelectors(), TokenConfig: tokenConfig, OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - USDCConfig: ccipdeployment.USDCConfig{ + USDCConfig: changeset.USDCConfig{ Enabled: true, - USDCAttestationConfig: ccipdeployment.USDCAttestationConfig{ + USDCAttestationConfig: changeset.USDCAttestationConfig{ API: endpoint, APITimeout: commonconfig.MustNewDuration(time.Second), APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), @@ -262,7 +263,7 @@ func GenerateTestRMNConfig(t *testing.T, nRMNNodes int, tenv changeset.DeployedE bootstrappers := nodes.BootstrapLocators() // Just set all RMN nodes to support all chains. - state, err := ccipdeployment.LoadOnchainState(tenv.Env) + state, err := changeset.LoadOnchainState(tenv.Env) require.NoError(t, err) var chainParams []devenv.ChainParam var remoteChains []devenv.RemoteChains From edb4eb9dc76701bf2bbd44c84bdbfdf7fc2d8677 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 10:34:41 -0500 Subject: [PATCH 05/27] Get building --- .../{internal => }/active_candidate.go | 15 +++--- .../active_candidate_helpers.go | 15 +++--- .../{internal => }/active_candidate_test.go | 40 ++++++++-------- deployment/ccip/changeset/add_chain_test.go | 5 +- deployment/ccip/changeset/add_lane.go | 5 +- deployment/ccip/changeset/deploy_chain.go | 3 +- .../ccip/changeset/deploy_home_chain.go | 18 ++++---- deployment/ccip/changeset/home_chain.go | 2 +- deployment/ccip/changeset/initial_deploy.go | 8 ++-- .../changeset/internal/deploy_home_chain.go | 1 + .../changeset/{internal => }/ownership.go | 2 +- deployment/ccip/changeset/prerequisites.go | 3 +- deployment/ccip/changeset/test_assertions.go | 9 ++-- deployment/ccip/changeset/test_helpers.go | 46 +++++++++---------- .../ccip/changeset/test_usdc_helpers.go | 15 +++--- deployment/ccip/changeset/view.go | 3 +- 16 files changed, 87 insertions(+), 103 deletions(-) rename deployment/ccip/changeset/{internal => }/active_candidate.go (86%) rename deployment/ccip/changeset/{internal => }/active_candidate_helpers.go (90%) rename deployment/ccip/changeset/{internal => }/active_candidate_test.go (82%) create mode 100644 deployment/ccip/changeset/internal/deploy_home_chain.go rename deployment/ccip/changeset/{internal => }/ownership.go (98%) diff --git a/deployment/ccip/changeset/internal/active_candidate.go b/deployment/ccip/changeset/active_candidate.go similarity index 86% rename from deployment/ccip/changeset/internal/active_candidate.go rename to deployment/ccip/changeset/active_candidate.go index 8a1b934fc4d..f75d0e5e942 100644 --- a/deployment/ccip/changeset/internal/active_candidate.go +++ b/deployment/ccip/changeset/active_candidate.go @@ -1,4 +1,4 @@ -package internal +package changeset import ( "fmt" @@ -7,14 +7,13 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" 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 changeset.CCIPOnChainState, + state CCIPOnChainState, homeChainSel, newChainSel uint64, nodes deployment.Nodes, ) (deployment.ChangesetOutput, error) { @@ -28,7 +27,7 @@ func PromoteAllCandidatesChangeset( return deployment.ChangesetOutput{}, err } - prop, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + prop, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(homeChainSel), Batch: promoteCandidateOps, }}, "promoteCandidate for commit and execution", 0) @@ -44,15 +43,15 @@ func PromoteAllCandidatesChangeset( // SetCandidateExecPluginProposal calls setCandidate on the CCIPHome for setting up OCR3 exec Plugin config for the new chain. func SetCandidatePluginChangeset( - state changeset.CCIPOnChainState, + state CCIPOnChainState, e deployment.Environment, nodes deployment.Nodes, ocrSecrets deployment.OCRSecrets, homeChainSel, feedChainSel, newChainSel uint64, - tokenConfig changeset.TokenConfig, + tokenConfig TokenConfig, pluginType cctypes.PluginType, ) (deployment.ChangesetOutput, error) { - newDONArgs, err := changeset.BuildOCR3ConfigForCCIPHome( + newDONArgs, err := BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], @@ -82,7 +81,7 @@ func SetCandidatePluginChangeset( return deployment.ChangesetOutput{}, err } - prop, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + prop, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(homeChainSel), Batch: setCandidateMCMSOps, }}, "SetCandidate for execution", 0) diff --git a/deployment/ccip/changeset/internal/active_candidate_helpers.go b/deployment/ccip/changeset/active_candidate_helpers.go similarity index 90% rename from deployment/ccip/changeset/internal/active_candidate_helpers.go rename to deployment/ccip/changeset/active_candidate_helpers.go index 26d552ccb77..914f8fc0c17 100644 --- a/deployment/ccip/changeset/internal/active_candidate_helpers.go +++ b/deployment/ccip/changeset/active_candidate_helpers.go @@ -1,4 +1,4 @@ -package internal +package changeset import ( "fmt" @@ -7,7 +7,6 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" 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" @@ -23,12 +22,12 @@ func SetCandidateOnExistingDon( nodes deployment.Nodes, ) ([]mcms.Operation, error) { // fetch DON ID for the chain - donID, err := changeset.DonIDForChain(capReg, ccipHome, chainSelector) + donID, err := 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 := changeset.CCIPHomeABI.Pack( + encodedSetCandidateCall, err := CCIPHomeABI.Pack( "setCandidate", donID, pluginConfig.PluginType, @@ -46,7 +45,7 @@ func SetCandidateOnExistingDon( nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ { - CapabilityId: changeset.CCIPCapabilityID, + CapabilityId: CCIPCapabilityID, Config: encodedSetCandidateCall, }, }, @@ -78,7 +77,7 @@ func PromoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg } fmt.Printf("commit candidate digest after setCandidate: %x\n", allConfigs.CandidateConfig.ConfigDigest) - encodedPromotionCall, err := changeset.CCIPHomeABI.Pack( + encodedPromotionCall, err := CCIPHomeABI.Pack( "promoteCandidateAndRevokeActive", donID, pluginType, @@ -95,7 +94,7 @@ func PromoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ { - CapabilityId: changeset.CCIPCapabilityID, + CapabilityId: CCIPCapabilityID, Config: encodedPromotionCall, }, }, @@ -120,7 +119,7 @@ func PromoteAllCandidatesForChainOps( nodes deployment.Nodes, ) ([]mcms.Operation, error) { // fetch DON ID for the chain - donID, err := changeset.DonIDForChain(capReg, ccipHome, chainSelector) + donID, err := DonIDForChain(capReg, ccipHome, chainSelector) if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } diff --git a/deployment/ccip/changeset/internal/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go similarity index 82% rename from deployment/ccip/changeset/internal/active_candidate_test.go rename to deployment/ccip/changeset/active_candidate_test.go index 96f120db58d..0a85b7ef51d 100644 --- a/deployment/ccip/changeset/internal/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -1,4 +1,4 @@ -package internal +package changeset import ( "testing" @@ -8,8 +8,6 @@ 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" - cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -26,13 +24,13 @@ func TestActiveCandidate(t *testing.T) { t.Skipf("to be enabled after latest cl-ccip is compatible") lggr := logger.TestLogger(t) - tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5) + tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5) e := tenv.Env - state, err := changeset.LoadOnchainState(tenv.Env) + state, err := LoadOnchainState(tenv.Env) require.NoError(t, err) // Add all lanes - require.NoError(t, changeset.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. @@ -46,7 +44,7 @@ func TestActiveCandidate(t *testing.T) { require.NoError(t, err) block := latesthdr.Number.Uint64() startBlocks[dest] = &block - msgSentEvent := changeset.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, @@ -58,7 +56,7 @@ func TestActiveCandidate(t *testing.T) { } // Wait for all commit reports to land. - changeset.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 { @@ -66,15 +64,15 @@ func TestActiveCandidate(t *testing.T) { feeQuoter := state.Chains[dest].FeeQuoter timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress) require.NoError(t, err) - require.Equal(t, changeset.MockLinkPrice, timestampedPrice.Value) + require.Equal(t, MockLinkPrice, timestampedPrice.Value) } //Wait for all exec reports to land - changeset.ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) + ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) // transfer ownership TransferAllOwnership(t, state, tenv.HomeChainSel, e) - acceptOwnershipProposal, err := changeset.GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors()) + acceptOwnershipProposal, err := GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors()) require.NoError(t, err) acceptOwnershipExec := commonchangeset.SignProposal(t, e, acceptOwnershipProposal) for _, sel := range e.AllChainSelectors() { @@ -82,19 +80,19 @@ func TestActiveCandidate(t *testing.T) { } // Apply the accept ownership proposal to all the chains. - err = changeset.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 := changeset.DonIDForChain(capReg, ccipHome, tenv.FeedChainSel) + donID, err := 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 = changeset.LoadOnchainState(e) + state, err = LoadOnchainState(e) require.NoError(t, err) // delete a non-bootstrap node @@ -114,8 +112,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 := changeset.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) - ocr3ConfigMap, err := changeset.BuildOCR3ConfigForCCIPHome( + tokenConfig := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) + ocr3ConfigMap, err := BuildOCR3ConfigForCCIPHome( deployment.XXXGenerateTestOCRSecrets(), state.Chains[tenv.FeedChainSel].OffRamp, e.Chains[tenv.FeedChainSel], @@ -135,7 +133,7 @@ func TestActiveCandidate(t *testing.T) { nodes.NonBootstraps(), ) require.NoError(t, err) - setCommitCandidateProposal, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + setCommitCandidateProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), Batch: setCommitCandidateOp, }}, "set new candidates on commit plugin", 0) @@ -153,7 +151,7 @@ func TestActiveCandidate(t *testing.T) { ) require.NoError(t, err) - setExecCandidateProposal, err := changeset.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) @@ -169,7 +167,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 = changeset.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 @@ -180,7 +178,7 @@ func TestActiveCandidate(t *testing.T) { promoteOps, err := PromoteAllCandidatesForChainOps(state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome, tenv.FeedChainSel, nodes.NonBootstraps()) require.NoError(t, err) - promoteProposal, err := changeset.BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ + promoteProposal, err := BuildProposalFromBatches(state, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), Batch: promoteOps, }}, "promote candidates and revoke actives", 0) @@ -204,7 +202,7 @@ func TestActiveCandidate(t *testing.T) { require.NoError(t, err) require.Equal(t, uint32(8), donInfo.ConfigCount) - err = changeset.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 } diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 20f89bffb14..3dc18f5161c 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" 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" @@ -172,12 +171,12 @@ func TestAddChainInbound(t *testing.T) { ProcessChangeset(t, e.Env, addDonChangeset) t.Logf("Executing promote candidate proposal for exec plugin on chain %d", newChain) - setCandidateForExecChangeset, err := internal.SetCandidatePluginChangeset(state, e.Env, nodes, deployment.XXXGenerateTestOCRSecrets(), e.HomeChainSel, e.FeedChainSel, newChain, tokenConfig, types.PluginTypeCCIPExec) + setCandidateForExecChangeset, err := SetCandidatePluginChangeset(state, e.Env, nodes, deployment.XXXGenerateTestOCRSecrets(), e.HomeChainSel, e.FeedChainSel, newChain, tokenConfig, types.PluginTypeCCIPExec) require.NoError(t, err) ProcessChangeset(t, e.Env, setCandidateForExecChangeset) t.Logf("Executing promote candidate proposal for both commit and exec plugins on chain %d", newChain) - donPromoteChangeset, err := internal.PromoteAllCandidatesChangeset(state, e.HomeChainSel, newChain, nodes) + donPromoteChangeset, err := PromoteAllCandidatesChangeset(state, e.HomeChainSel, newChain, nodes) require.NoError(t, err) ProcessChangeset(t, e.Env, donPromoteChangeset) diff --git a/deployment/ccip/changeset/add_lane.go b/deployment/ccip/changeset/add_lane.go index 9eed05a81cd..82cf60b77f6 100644 --- a/deployment/ccip/changeset/add_lane.go +++ b/deployment/ccip/changeset/add_lane.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" @@ -28,11 +27,11 @@ var DefaultInitialPrices = InitialPrices{ GasPrice: ToPackedFee(big.NewInt(8e14), big.NewInt(0)), } -func AddLaneWithDefaultPrices(e deployment.Environment, state ccipdeployment.CCIPOnChainState, from, to uint64) error { +func AddLaneWithDefaultPrices(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { return AddLane(e, state, from, to, DefaultInitialPrices) } -func AddLane(e deployment.Environment, state ccipdeployment.CCIPOnChainState, from, to uint64, initialPrices InitialPrices) error { +func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, initialPrices InitialPrices) error { // TODO: Batch tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ { diff --git a/deployment/ccip/changeset/deploy_chain.go b/deployment/ccip/changeset/deploy_chain.go index 633d01bbf4c..cb60f1ddabd 100644 --- a/deployment/ccip/changeset/deploy_chain.go +++ b/deployment/ccip/changeset/deploy_chain.go @@ -6,14 +6,13 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" ) var _ deployment.ChangeSet[DeployChainContractsConfig] = DeployChainContracts func DeployChainContracts(env deployment.Environment, c DeployChainContractsConfig) (deployment.ChangesetOutput, error) { newAddresses := deployment.NewMemoryAddressBook() - err := ccipdeployment.DeployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors) + err := DeployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors) if err != nil { env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "newAddresses", newAddresses) return deployment.ChangesetOutput{AddressBook: newAddresses}, deployment.MaybeDataErr(err) diff --git a/deployment/ccip/changeset/deploy_home_chain.go b/deployment/ccip/changeset/deploy_home_chain.go index b07e844be04..47dd5f590e6 100644 --- a/deployment/ccip/changeset/deploy_home_chain.go +++ b/deployment/ccip/changeset/deploy_home_chain.go @@ -20,8 +20,6 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - "github.com/smartcontractkit/chainlink/deployment/ccip" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" @@ -91,7 +89,7 @@ func MustABIEncode(abiString string, args ...interface{}) []byte { // and returns a deployment.ContractDeploy struct with the address and contract instance. func DeployCapReg( lggr logger.Logger, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, ab deployment.AddressBook, chain deployment.Chain, ) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { @@ -101,7 +99,7 @@ func DeployCapReg( if cr != nil { lggr.Infow("Found CapabilitiesRegistry in chain state", "address", cr.Address().String()) return &deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ - Address: cr.Address(), Contract: cr, Tv: deployment.NewTypeAndVersion(ccipdeployment.CapabilitiesRegistry, deployment.Version1_0_0), + Address: cr.Address(), Contract: cr, Tv: deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0), }, nil } } @@ -112,7 +110,7 @@ func DeployCapReg( chain.Client, ) return deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry]{ - Address: crAddr, Contract: cr, Tv: deployment.NewTypeAndVersion(ccipdeployment.CapabilitiesRegistry, deployment.Version1_0_0), Tx: tx, Err: err2, + Address: crAddr, Contract: cr, Tv: deployment.NewTypeAndVersion(CapabilitiesRegistry, deployment.Version1_0_0), Tx: tx, Err: err2, } }) if err != nil { @@ -122,7 +120,7 @@ func DeployCapReg( return capReg, nil } -func DeployHomeChain( +func deployHomeChain( lggr logger.Logger, e deployment.Environment, ab deployment.AddressBook, @@ -133,7 +131,7 @@ func DeployHomeChain( nodeP2PIDsPerNodeOpAdmin map[string][][32]byte, ) (*deployment.ContractDeploy[*capabilities_registry.CapabilitiesRegistry], error) { // load existing state - state, err := ccipdeployment.LoadOnchainState(e) + state, err := LoadOnchainState(e) if err != nil { return nil, fmt.Errorf("failed to load onchain state: %w", err) } @@ -153,7 +151,7 @@ func DeployHomeChain( capReg.Address, ) return deployment.ContractDeploy[*ccip_home.CCIPHome]{ - Address: ccAddr, Tv: deployment.NewTypeAndVersion(ccipdeployment.CCIPHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: cc, + Address: ccAddr, Tv: deployment.NewTypeAndVersion(CCIPHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: cc, } }) if err != nil { @@ -170,7 +168,7 @@ func DeployHomeChain( chain.Client, ) return deployment.ContractDeploy[*rmn_home.RMNHome]{ - Address: rmnAddr, Tv: deployment.NewTypeAndVersion(ccipdeployment.RMNHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: rmn, + Address: rmnAddr, Tv: deployment.NewTypeAndVersion(RMNHome, deployment.Version1_6_0_dev), Tx: tx, Err: err2, Contract: rmn, } }, ) @@ -1047,7 +1045,7 @@ func AddDON( func ApplyChainConfigUpdatesOp( e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, homeChainSel uint64, chains []uint64, ) (mcms.Operation, error) { diff --git a/deployment/ccip/changeset/home_chain.go b/deployment/ccip/changeset/home_chain.go index 51c2a1ed77f..e88db2bcfe0 100644 --- a/deployment/ccip/changeset/home_chain.go +++ b/deployment/ccip/changeset/home_chain.go @@ -22,7 +22,7 @@ func DeployHomeChain(env deployment.Environment, cfg DeployHomeChainConfig) (dep } ab := deployment.NewMemoryAddressBook() // Note we also deploy the cap reg. - _, err = DeployHomeChain(env.Logger, env, ab, env.Chains[cfg.HomeChainSel], cfg.RMNStaticConfig, cfg.RMNDynamicConfig, cfg.NodeOperators, cfg.NodeP2PIDsPerNodeOpAdmin) + _, err = deployHomeChain(env.Logger, env, ab, env.Chains[cfg.HomeChainSel], cfg.RMNStaticConfig, cfg.RMNDynamicConfig, cfg.NodeOperators, cfg.NodeP2PIDsPerNodeOpAdmin) if err != nil { env.Logger.Errorw("Failed to deploy cap reg", "err", err, "addresses", env.ExistingAddresses) return deployment.ChangesetOutput{ diff --git a/deployment/ccip/changeset/initial_deploy.go b/deployment/ccip/changeset/initial_deploy.go index 5d9a9d0b91c..29cfde18ec2 100644 --- a/deployment/ccip/changeset/initial_deploy.go +++ b/deployment/ccip/changeset/initial_deploy.go @@ -4,15 +4,13 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" ) -var _ deployment.ChangeSet[ccipdeployment.DeployCCIPContractConfig] = InitialDeploy +var _ deployment.ChangeSet[DeployCCIPContractConfig] = InitialDeploy -func InitialDeploy(env deployment.Environment, c ccipdeployment.DeployCCIPContractConfig) (deployment.ChangesetOutput, error) { +func InitialDeploy(env deployment.Environment, c DeployCCIPContractConfig) (deployment.ChangesetOutput, error) { newAddresses := deployment.NewMemoryAddressBook() - err := ccipdeployment.DeployCCIPContracts(env, newAddresses, c) + err := DeployCCIPContracts(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) diff --git a/deployment/ccip/changeset/internal/deploy_home_chain.go b/deployment/ccip/changeset/internal/deploy_home_chain.go new file mode 100644 index 00000000000..5bf0569ce8c --- /dev/null +++ b/deployment/ccip/changeset/internal/deploy_home_chain.go @@ -0,0 +1 @@ +package internal diff --git a/deployment/ccip/changeset/internal/ownership.go b/deployment/ccip/changeset/ownership.go similarity index 98% rename from deployment/ccip/changeset/internal/ownership.go rename to deployment/ccip/changeset/ownership.go index 50eb8e12b48..4287363b8a6 100644 --- a/deployment/ccip/changeset/internal/ownership.go +++ b/deployment/ccip/changeset/ownership.go @@ -1,4 +1,4 @@ -package internal +package changeset import ( "testing" diff --git a/deployment/ccip/changeset/prerequisites.go b/deployment/ccip/changeset/prerequisites.go index 7332f97fc18..3136c5cc35e 100644 --- a/deployment/ccip/changeset/prerequisites.go +++ b/deployment/ccip/changeset/prerequisites.go @@ -8,7 +8,6 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" ) var ( @@ -23,7 +22,7 @@ func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfi return deployment.ChangesetOutput{}, errors.Wrapf(deployment.ErrInvalidConfig, "%v", err) } ab := deployment.NewMemoryAddressBook() - err = ccipdeployment.DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors) + err = DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors) if err != nil { env.Logger.Errorw("Failed to deploy prerequisite contracts", "err", err, "addressBook", ab) return deployment.ChangesetOutput{ diff --git a/deployment/ccip/changeset/test_assertions.go b/deployment/ccip/changeset/test_assertions.go index f311e670664..8efb83c477d 100644 --- a/deployment/ccip/changeset/test_assertions.go +++ b/deployment/ccip/changeset/test_assertions.go @@ -15,7 +15,6 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment" @@ -26,7 +25,7 @@ import ( func ConfirmGasPriceUpdatedForAll( t *testing.T, e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, startBlocks map[uint64]*uint64, gasPrice *big.Int, ) { @@ -79,7 +78,7 @@ func ConfirmGasPriceUpdated( func ConfirmTokenPriceUpdatedForAll( t *testing.T, e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, startBlocks map[uint64]*uint64, linkPrice *big.Int, wethPrice *big.Int, @@ -155,7 +154,7 @@ func ConfirmTokenPriceUpdated( func ConfirmCommitForAllWithExpectedSeqNums( t *testing.T, e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, expectedSeqNums map[uint64]uint64, startBlocks map[uint64]*uint64, ) { @@ -307,7 +306,7 @@ func ConfirmCommitWithExpectedSeqNumRange( func ConfirmExecWithSeqNrForAll( t *testing.T, e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, expectedSeqNums map[uint64]uint64, startBlocks map[uint64]*uint64, ) (executionStates map[uint64]int) { diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index a73075d7bf2..ffc7e9a1a1f 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -17,8 +17,6 @@ import ( "github.com/pkg/errors" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink/deployment/ccip" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -128,8 +126,8 @@ func DeployTestContracts(t *testing.T, ) deployment.CapabilityRegistryConfig { capReg, err := DeployCapReg(lggr, // deploying cap reg for the first time on a blank chain state - ccipdeployment.CCIPOnChainState{ - Chains: make(map[uint64]ccipdeployment.CCIPChainState), + CCIPOnChainState{ + Chains: make(map[uint64]CCIPChainState), }, ab, chains[homeChainSel]) require.NoError(t, err) _, err = DeployFeeds(lggr, ab, chains[feedChainSel], linkPrice, wethPrice) @@ -199,7 +197,7 @@ func NewMemoryEnvironment( envNodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) require.NoError(t, err) e.ExistingAddresses = ab - _, err = DeployHomeChain(lggr, e, e.ExistingAddresses, chains[homeChainSel], + _, err = deployHomeChain(lggr, e, e.ExistingAddresses, chains[homeChainSel], NewTestRMNStaticConfig(), NewTestRMNDynamicConfig(), NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), @@ -249,7 +247,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, e.SetupJobs(t) // Take first non-home chain as the new chain. newAddresses := deployment.NewMemoryAddressBook() - err := ccipdeployment.DeployPrerequisiteChainContracts(e.Env, newAddresses, e.Env.AllChainSelectors()) + err := DeployPrerequisiteChainContracts(e.Env, newAddresses, e.Env.AllChainSelectors()) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) @@ -267,7 +265,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, out, err := commonchangeset.DeployMCMSWithTimelock(e.Env, mcmsCfg) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) - state, err := ccipdeployment.LoadOnchainState(e.Env) + state, err := LoadOnchainState(e.Env) require.NoError(t, err) newAddresses = deployment.NewMemoryAddressBook() @@ -275,15 +273,15 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, server := mockAttestationResponse() defer server.Close() endpoint := server.URL - err = ccipdeployment.DeployCCIPContracts(e.Env, newAddresses, ccipdeployment.DeployCCIPContractConfig{ + err = DeployCCIPContracts(e.Env, newAddresses, DeployCCIPContractConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: e.Env.AllChainSelectors(), TokenConfig: tokenConfig, OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - USDCConfig: ccipdeployment.USDCConfig{ + USDCConfig: USDCConfig{ Enabled: true, - USDCAttestationConfig: ccipdeployment.USDCAttestationConfig{ + USDCAttestationConfig: USDCAttestationConfig{ API: endpoint, APITimeout: commonconfig.MustNewDuration(time.Second), APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), @@ -292,7 +290,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, }) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - state, err = ccipdeployment.LoadOnchainState(e.Env) + state, err = LoadOnchainState(e.Env) require.NoError(t, err) return e @@ -300,7 +298,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, func CCIPSendRequest( e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, src, dest uint64, testRouter bool, evm2AnyMessage router.ClientEVM2AnyMessage, @@ -342,7 +340,7 @@ func CCIPSendRequest( func TestSendRequest( t *testing.T, e deployment.Environment, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, src, dest uint64, testRouter bool, evm2AnyMessage router.ClientEVM2AnyMessage, @@ -403,11 +401,11 @@ func MakeEVMExtraArgsV2(gasLimit uint64, allowOOO bool) []byte { // AddLanesForAll adds densely connected lanes for all chains in the environment so that each chain // is connected to every other chain except itself. -func AddLanesForAll(e deployment.Environment, state ccipdeployment.CCIPOnChainState) error { +func AddLanesForAll(e deployment.Environment, state CCIPOnChainState) error { for source := range e.Chains { for dest := range e.Chains { if source != dest { - err := internal.AddLaneWithDefaultPrices(e, state, source, dest) + err := AddLaneWithDefaultPrices(e, state, source, dest) if err != nil { return err } @@ -458,7 +456,7 @@ func DeployFeeds( linkPrice *big.Int, wethPrice *big.Int, ) (map[string]common.Address, error) { - linkTV := deployment.NewTypeAndVersion(ccipdeployment.PriceFeed, deployment.Version1_0_0) + linkTV := deployment.NewTypeAndVersion(PriceFeed, deployment.Version1_0_0) mockLinkFeed := func(chain deployment.Chain) deployment.ContractDeploy[*aggregator_v3_interface.AggregatorV3Interface] { linkFeed, tx, _, err1 := mock_v3_aggregator_contract.DeployMockV3Aggregator( chain.DeployerKey, @@ -534,7 +532,7 @@ func deploySingleFeed( return mockTokenFeed.Address, desc, nil } -func ConfirmRequestOnSourceAndDest(t *testing.T, env deployment.Environment, state ccipdeployment.CCIPOnChainState, sourceCS, destCS, expectedSeqNr uint64) error { +func ConfirmRequestOnSourceAndDest(t *testing.T, env deployment.Environment, state CCIPOnChainState, sourceCS, destCS, expectedSeqNr uint64) error { latesthdr, err := env.Chains[destCS].Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) startBlock := latesthdr.Number.Uint64() @@ -579,7 +577,7 @@ func ProcessChangeset(t *testing.T, e deployment.Environment, c deployment.Chang // sign and execute all proposals provided if len(c.Proposals) != 0 { - state, err := ccipdeployment.LoadOnchainState(e) + state, err := LoadOnchainState(e) require.NoError(t, err) for _, prop := range c.Proposals { chains := mapset.NewSet[uint64]() @@ -605,7 +603,7 @@ func DeployTransferableToken( lggr logger.Logger, chains map[uint64]deployment.Chain, src, dst uint64, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, addresses deployment.AddressBook, token string, ) (*burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, *burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, error) { @@ -760,7 +758,7 @@ func setTokenPoolCounterPart( func attachTokenToTheRegistry( chain deployment.Chain, - state ccipdeployment.CCIPChainState, + state CCIPChainState, owner *bind.TransactOpts, token common.Address, tokenPool common.Address, @@ -806,10 +804,10 @@ func deployTransferTokenOneEnd( return nil, nil, err } for address, v := range chainAddresses { - if deployment.NewTypeAndVersion(ccipdeployment.ARMProxy, deployment.Version1_0_0) == v { + if deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_0_0) == v { rmnAddress = address } - if deployment.NewTypeAndVersion(ccipdeployment.Router, deployment.Version1_2_0) == v { + if deployment.NewTypeAndVersion(Router, deployment.Version1_2_0) == v { routerAddress = address } if rmnAddress != "" && routerAddress != "" { @@ -828,7 +826,7 @@ func deployTransferTokenOneEnd( big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), ) return deployment.ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ - USDCTokenAddr, token, tx, deployment.NewTypeAndVersion(ccipdeployment.BurnMintToken, deployment.Version1_0_0), err2, + USDCTokenAddr, token, tx, deployment.NewTypeAndVersion(BurnMintToken, deployment.Version1_0_0), err2, } }) if err != nil { @@ -856,7 +854,7 @@ func deployTransferTokenOneEnd( common.HexToAddress(routerAddress), ) return deployment.ContractDeploy[*burn_mint_token_pool.BurnMintTokenPool]{ - tokenPoolAddress, tokenPoolContract, tx, deployment.NewTypeAndVersion(ccipdeployment.BurnMintTokenPool, deployment.Version1_0_0), err2, + tokenPoolAddress, tokenPoolContract, tx, deployment.NewTypeAndVersion(BurnMintTokenPool, deployment.Version1_0_0), err2, } }) if err != nil { diff --git a/deployment/ccip/changeset/test_usdc_helpers.go b/deployment/ccip/changeset/test_usdc_helpers.go index f114cbef8b4..88e9c07f06a 100644 --- a/deployment/ccip/changeset/test_usdc_helpers.go +++ b/deployment/ccip/changeset/test_usdc_helpers.go @@ -8,7 +8,6 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/reader" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_messenger" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_usdc_token_transmitter" @@ -20,7 +19,7 @@ func ConfigureUSDCTokenPools( lggr logger.Logger, chains map[uint64]deployment.Chain, src, dst uint64, - state ccipdeployment.CCIPOnChainState, + state CCIPOnChainState, ) (*burn_mint_erc677.BurnMintERC677, *burn_mint_erc677.BurnMintERC677, error) { srcToken := state.Chains[src].BurnMintTokens677[USDCSymbol] dstToken := state.Chains[dst].BurnMintTokens677[USDCSymbol] @@ -79,7 +78,7 @@ func ConfigureUSDCTokenPools( func UpdateFeeQuoterForUSDC( lggr logger.Logger, chain deployment.Chain, - state ccipdeployment.CCIPChainState, + state CCIPChainState, dstChain uint64, usdcToken *burn_mint_erc677.BurnMintERC677, ) error { @@ -120,7 +119,7 @@ func DeployUSDC( lggr logger.Logger, chain deployment.Chain, addresses deployment.AddressBook, - state ccipdeployment.CCIPChainState, + state CCIPChainState, ) ( *burn_mint_erc677.BurnMintERC677, *usdc_token_pool.USDCTokenPool, @@ -142,7 +141,7 @@ func DeployUSDC( Address: tokenAddress, Contract: tokenContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCToken, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(USDCToken, deployment.Version1_0_0), Err: err2, } }) @@ -174,7 +173,7 @@ func DeployUSDC( Address: transmitterAddress, Contract: transmitterContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCMockTransmitter, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(USDCMockTransmitter, deployment.Version1_0_0), Err: err2, } }) @@ -197,7 +196,7 @@ func DeployUSDC( Address: messengerAddress, Contract: messengerContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCTokenMessenger, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(USDCTokenMessenger, deployment.Version1_0_0), Err: err2, } }) @@ -222,7 +221,7 @@ func DeployUSDC( Address: tokenPoolAddress, Contract: tokenPoolContract, Tx: tx, - Tv: deployment.NewTypeAndVersion(ccipdeployment.USDCTokenPool, deployment.Version1_0_0), + Tv: deployment.NewTypeAndVersion(USDCTokenPool, deployment.Version1_0_0), Err: err2, } }) diff --git a/deployment/ccip/changeset/view.go b/deployment/ccip/changeset/view.go index 9d3eb8260c7..1fd8fdbe38f 100644 --- a/deployment/ccip/changeset/view.go +++ b/deployment/ccip/changeset/view.go @@ -4,7 +4,6 @@ import ( "encoding/json" "github.com/smartcontractkit/chainlink/deployment" - ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" ccipview "github.com/smartcontractkit/chainlink/deployment/ccip/view" "github.com/smartcontractkit/chainlink/deployment/common/view" ) @@ -12,7 +11,7 @@ import ( var _ deployment.ViewState = ViewCCIP func ViewCCIP(e deployment.Environment) (json.Marshaler, error) { - state, err := ccipdeployment.LoadOnchainState(e) + state, err := LoadOnchainState(e) if err != nil { return nil, err } From b375b3ca23dd4ff5c4c4524e9773e72ea397b58b Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 10:43:57 -0500 Subject: [PATCH 06/27] Move a bunch of home chain stuff to internal --- deployment/ccip/changeset/active_candidate.go | 3 +- .../changeset/active_candidate_helpers.go | 13 +- .../ccip/changeset/active_candidate_test.go | 5 +- deployment/ccip/changeset/add_chain.go | 5 +- deployment/ccip/changeset/add_chain_test.go | 5 +- deployment/ccip/changeset/deploy.go | 9 +- .../ccip/changeset/deploy_home_chain.go | 545 +----------------- .../changeset/internal/deploy_home_chain.go | 535 +++++++++++++++++ deployment/ccip/changeset/jobs.go | 9 +- 9 files changed, 576 insertions(+), 553 deletions(-) diff --git a/deployment/ccip/changeset/active_candidate.go b/deployment/ccip/changeset/active_candidate.go index f75d0e5e942..a336cf69536 100644 --- a/deployment/ccip/changeset/active_candidate.go +++ b/deployment/ccip/changeset/active_candidate.go @@ -7,6 +7,7 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" ) @@ -51,7 +52,7 @@ func SetCandidatePluginChangeset( tokenConfig TokenConfig, pluginType cctypes.PluginType, ) (deployment.ChangesetOutput, error) { - newDONArgs, err := BuildOCR3ConfigForCCIPHome( + newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], diff --git a/deployment/ccip/changeset/active_candidate_helpers.go b/deployment/ccip/changeset/active_candidate_helpers.go index 914f8fc0c17..aea488c36b2 100644 --- a/deployment/ccip/changeset/active_candidate_helpers.go +++ b/deployment/ccip/changeset/active_candidate_helpers.go @@ -7,6 +7,7 @@ import ( "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" @@ -22,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, @@ -45,7 +46,7 @@ func SetCandidateOnExistingDon( nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ { - CapabilityId: CCIPCapabilityID, + CapabilityId: internal.CCIPCapabilityID, Config: encodedSetCandidateCall, }, }, @@ -77,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, @@ -94,7 +95,7 @@ func PromoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ { - CapabilityId: CCIPCapabilityID, + CapabilityId: internal.CCIPCapabilityID, Config: encodedPromotionCall, }, }, @@ -119,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) } diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index 0a85b7ef51d..e917c7a7e31 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -8,6 +8,7 @@ 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" @@ -85,7 +86,7 @@ func TestActiveCandidate(t *testing.T) { // [ACTIVE, CANDIDATE] setup by setting candidate through cap reg capReg, ccipHome := state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome - donID, err := 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) @@ -113,7 +114,7 @@ func TestActiveCandidate(t *testing.T) { // commit and exec plugin we will be using rmnHomeAddress := state.Chains[tenv.HomeChainSel].RMNHome.Address() tokenConfig := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) - ocr3ConfigMap, err := BuildOCR3ConfigForCCIPHome( + ocr3ConfigMap, err := internal.BuildOCR3ConfigForCCIPHome( deployment.XXXGenerateTestOCRSecrets(), state.Chains[tenv.FeedChainSel].OffRamp, e.Chains[tenv.FeedChainSel], diff --git a/deployment/ccip/changeset/add_chain.go b/deployment/ccip/changeset/add_chain.go index f58da7b4e5d..cb7d0701973 100644 --- a/deployment/ccip/changeset/add_chain.go +++ b/deployment/ccip/changeset/add_chain.go @@ -4,6 +4,7 @@ import ( "fmt" "math/big" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" @@ -97,7 +98,7 @@ func AddDonAndSetCandidateChangeset( tokenConfig TokenConfig, pluginType types.PluginType, ) (deployment.ChangesetOutput, error) { - newDONArgs, err := BuildOCR3ConfigForCCIPHome( + newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], @@ -110,7 +111,7 @@ func AddDonAndSetCandidateChangeset( if err != nil { return deployment.ChangesetOutput{}, err } - latestDon, err := LatestCCIPDON(state.Chains[homeChainSel].CapabilityRegistry) + latestDon, err := internal.LatestCCIPDON(state.Chains[homeChainSel].CapabilityRegistry) if err != nil { return deployment.ChangesetOutput{}, err } diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 3dc18f5161c..aa702a002cd 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" 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" @@ -204,9 +205,9 @@ func TestAddChainInbound(t *testing.T) { _, err = deployment.ConfirmIfNoError(e.Env.Chains[newChain], tx, err) require.NoError(t, err) // Set the OCR3 config on new 4th chain to enable the plugin. - latestDON, err := LatestCCIPDON(state.Chains[e.HomeChainSel].CapabilityRegistry) + latestDON, err := internal.LatestCCIPDON(state.Chains[e.HomeChainSel].CapabilityRegistry) require.NoError(t, err) - ocrConfigs, err := BuildSetOCR3ConfigArgs(latestDON.Id, state.Chains[e.HomeChainSel].CCIPHome, newChain) + ocrConfigs, err := internal.BuildSetOCR3ConfigArgs(latestDON.Id, state.Chains[e.HomeChainSel].CCIPHome, newChain) require.NoError(t, err) tx, err = state.Chains[newChain].OffRamp.SetOCR3Configs(e.Env.Chains[newChain].DeployerKey, ocrConfigs) require.NoError(t, err) diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 264127c9030..33459c17678 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -12,6 +12,7 @@ import ( cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" @@ -438,15 +439,15 @@ func DeployChainContractsForChains( return fmt.Errorf("capability registry not found") } cr, err := capReg.GetHashedCapabilityId( - &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) + &bind.CallOpts{}, internal.CapabilityLabelledName, internal.CapabilityVersion) if err != nil { e.Logger.Errorw("Failed to get hashed capability id", "err", err) return err } - if cr != CCIPCapabilityID { - return fmt.Errorf("capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(CCIPCapabilityID[:])) + if cr != internal.CCIPCapabilityID { + return fmt.Errorf("capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(internal.CCIPCapabilityID[:])) } - capability, err := capReg.GetCapability(nil, CCIPCapabilityID) + capability, err := capReg.GetCapability(nil, internal.CCIPCapabilityID) if err != nil { e.Logger.Errorw("Failed to get capability", "err", err) return err diff --git a/deployment/ccip/changeset/deploy_home_chain.go b/deployment/ccip/changeset/deploy_home_chain.go index 47dd5f590e6..446328c0530 100644 --- a/deployment/ccip/changeset/deploy_home_chain.go +++ b/deployment/ccip/changeset/deploy_home_chain.go @@ -7,10 +7,7 @@ import ( "encoding/json" "fmt" "math/big" - "os" - "time" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" @@ -20,16 +17,11 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" - - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" @@ -37,54 +29,6 @@ import ( p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) -const ( - NodeOperatorID = 1 - CapabilityLabelledName = "ccip" - CapabilityVersion = "v1.0.0" - - FirstBlockAge = 8 * time.Hour - RemoteGasPriceBatchWriteFrequency = 30 * time.Minute - TokenPriceBatchWriteFrequency = 30 * time.Minute - BatchGasLimit = 6_500_000 - RelativeBoostPerWaitHour = 1.5 - InflightCacheExpiry = 10 * time.Minute - RootSnoozeTime = 30 * time.Minute - BatchingStrategyID = 0 - DeltaProgress = 30 * time.Second - DeltaResend = 10 * time.Second - DeltaInitial = 20 * time.Second - DeltaRound = 2 * time.Second - DeltaGrace = 2 * time.Second - DeltaCertifiedCommitRequest = 10 * time.Second - DeltaStage = 10 * time.Second - Rmax = 3 - MaxDurationQuery = 500 * time.Millisecond - MaxDurationObservation = 5 * time.Second - MaxDurationShouldAcceptAttestedReport = 10 * time.Second - MaxDurationShouldTransmitAcceptedReport = 10 * time.Second -) - -var ( - CCIPCapabilityID = utils.Keccak256Fixed(MustABIEncode(`[{"type": "string"}, {"type": "string"}]`, CapabilityLabelledName, CapabilityVersion)) - CCIPHomeABI *abi.ABI -) - -func init() { - var err error - CCIPHomeABI, err = ccip_home.CCIPHomeMetaData.GetAbi() - if err != nil { - panic(err) - } -} - -func MustABIEncode(abiString string, args ...interface{}) []byte { - encoded, err := utils.ABIEncode(abiString, args...) - if err != nil { - panic(err) - } - return encoded -} - // DeployCapReg deploys the CapabilitiesRegistry contract if it is not already deployed // and returns a deployment.ContractDeploy struct with the address and contract instance. func DeployCapReg( @@ -212,8 +156,8 @@ func deployHomeChain( tx, err = capReg.Contract.AddCapabilities(chain.DeployerKey, []capabilities_registry.CapabilitiesRegistryCapability{ { - LabelledName: CapabilityLabelledName, - Version: CapabilityVersion, + LabelledName: internal.CapabilityLabelledName, + Version: internal.CapabilityVersion, CapabilityType: 2, // consensus. not used (?) ResponseType: 0, // report. not used (?) ConfigurationContract: ccipHome.Address, @@ -259,27 +203,6 @@ func deployHomeChain( return capReg, nil } -// getNodeOperatorIDMap returns a map of node operator names to their IDs -// If maxNops is greater than the number of node operators, it will return all node operators -func getNodeOperatorIDMap(capReg *capabilities_registry.CapabilitiesRegistry, maxNops uint32) (map[string]uint32, error) { - nopIdByName := make(map[string]uint32) - operators, err := capReg.GetNodeOperators(nil) - if err != nil { - return nil, err - } - if len(operators) < int(maxNops) { - maxNops = uint32(len(operators)) - } - for i := uint32(1); i <= maxNops; i++ { - operator, err := capReg.GetNodeOperator(nil, i) - if err != nil { - return nil, err - } - nopIdByName[operator.Name] = i - } - return nopIdByName, nil -} - func isEqualCapabilitiesRegistryNodeParams(a, b capabilities_registry.CapabilitiesRegistryNodeParams) (bool, error) { aBytes, err := json.Marshal(a) if err != nil { @@ -323,7 +246,7 @@ func AddNodes( Signer: p2pID, // Not used in tests P2pId: p2pID, EncryptionPublicKey: p2pID, // Not used in tests - HashedCapabilityIds: [][32]byte{CCIPCapabilityID}, + HashedCapabilityIds: [][32]byte{internal.CCIPCapabilityID}, } if existing, ok := existingNodeParams[p2pID]; ok { if isEqual, err := isEqualCapabilitiesRegistryNodeParams(existing, nodeParam); err != nil && isEqual { @@ -386,214 +309,6 @@ func AddChainConfig( return chainConfig, nil } -func BuildOCR3ConfigForCCIPHome( - ocrSecrets deployment.OCRSecrets, - offRamp *offramp.OffRamp, - dest deployment.Chain, - feedChainSel uint64, - tokenInfo map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo, - nodes deployment.Nodes, - rmnHomeAddress common.Address, - configs []pluginconfig.TokenDataObserverConfig, -) (map[cctypes.PluginType]ccip_home.CCIPHomeOCR3Config, error) { - p2pIDs := nodes.PeerIDs() - // Get OCR3 Config from helper - var schedule []int - var oracles []confighelper2.OracleIdentityExtra - for _, node := range nodes { - schedule = append(schedule, 1) - cfg := node.SelToOCRConfig[dest.Selector] - oracles = append(oracles, confighelper2.OracleIdentityExtra{ - OracleIdentity: confighelper2.OracleIdentity{ - OnchainPublicKey: cfg.OnchainPublicKey, - TransmitAccount: cfg.TransmitAccount, - OffchainPublicKey: cfg.OffchainPublicKey, - PeerID: cfg.PeerID.String()[4:], - }, ConfigEncryptionPublicKey: cfg.ConfigEncryptionPublicKey, - }) - } - - // Add DON on capability registry contract - ocr3Configs := make(map[cctypes.PluginType]ccip_home.CCIPHomeOCR3Config) - for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { - var encodedOffchainConfig []byte - var err2 error - if pluginType == cctypes.PluginTypeCCIPCommit { - encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ - RemoteGasPriceBatchWriteFrequency: *commonconfig.MustNewDuration(RemoteGasPriceBatchWriteFrequency), - TokenPriceBatchWriteFrequency: *commonconfig.MustNewDuration(TokenPriceBatchWriteFrequency), - PriceFeedChainSelector: ccipocr3.ChainSelector(feedChainSel), - TokenInfo: tokenInfo, - NewMsgScanBatchSize: merklemulti.MaxNumberTreeLeaves, - MaxReportTransmissionCheckAttempts: 5, - MaxMerkleTreeSize: merklemulti.MaxNumberTreeLeaves, - SignObservationPrefix: "chainlink ccip 1.6 rmn observation", - RMNEnabled: os.Getenv("ENABLE_RMN") == "true", // only enabled in manual test - }) - } else { - encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ - BatchGasLimit: BatchGasLimit, - RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, - MessageVisibilityInterval: *commonconfig.MustNewDuration(FirstBlockAge), - InflightCacheExpiry: *commonconfig.MustNewDuration(InflightCacheExpiry), - RootSnoozeTime: *commonconfig.MustNewDuration(RootSnoozeTime), - BatchingStrategyID: BatchingStrategyID, - TokenDataObservers: configs, - }) - } - if err2 != nil { - return nil, err2 - } - signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsDeterministic( - ocrSecrets.EphemeralSk, - ocrSecrets.SharedSecret, - DeltaProgress, - DeltaResend, - DeltaInitial, - DeltaRound, - DeltaGrace, - DeltaCertifiedCommitRequest, - DeltaStage, - Rmax, - schedule, - oracles, - encodedOffchainConfig, - nil, // maxDurationInitialization - MaxDurationQuery, - MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport, - int(nodes.DefaultF()), - []byte{}, // empty OnChainConfig - ) - if err2 != nil { - return nil, err2 - } - - signersBytes := make([][]byte, len(signers)) - for i, signer := range signers { - signersBytes[i] = signer - } - - transmittersBytes := make([][]byte, len(transmitters)) - for i, transmitter := range transmitters { - parsed, err2 := common.ParseHexOrString(string(transmitter)) - if err2 != nil { - return nil, err2 - } - transmittersBytes[i] = parsed - } - - var ocrNodes []ccip_home.CCIPHomeOCR3Node - for i := range nodes { - ocrNodes = append(ocrNodes, ccip_home.CCIPHomeOCR3Node{ - P2pId: p2pIDs[i], - SignerKey: signersBytes[i], - TransmitterKey: transmittersBytes[i], - }) - } - - _, ok := ocr3Configs[pluginType] - if ok { - return nil, fmt.Errorf("pluginType %s already exists in ocr3Configs", pluginType.String()) - } - - ocr3Configs[pluginType] = ccip_home.CCIPHomeOCR3Config{ - PluginType: uint8(pluginType), - ChainSelector: dest.Selector, - FRoleDON: configF, - OffchainConfigVersion: offchainConfigVersion, - OfframpAddress: offRamp.Address().Bytes(), - Nodes: ocrNodes, - OffchainConfig: offchainConfig, - RmnHomeAddress: rmnHomeAddress.Bytes(), - } - } - - return ocr3Configs, nil -} - -func LatestCCIPDON(registry *capabilities_registry.CapabilitiesRegistry) (*capabilities_registry.CapabilitiesRegistryDONInfo, error) { - dons, err := registry.GetDONs(nil) - if err != nil { - return nil, err - } - var ccipDON capabilities_registry.CapabilitiesRegistryDONInfo - for _, don := range dons { - if len(don.CapabilityConfigurations) == 1 && - don.CapabilityConfigurations[0].CapabilityId == CCIPCapabilityID && - don.Id > ccipDON.Id { - ccipDON = don - } - } - return &ccipDON, nil -} - -// DonIDForChain returns the DON ID for the chain with the given selector -// It looks up with the CCIPHome contract to find the OCR3 configs for the DONs, and returns the DON ID for the chain matching with the given selector from the OCR3 configs -func DonIDForChain(registry *capabilities_registry.CapabilitiesRegistry, ccipHome *ccip_home.CCIPHome, chainSelector uint64) (uint32, error) { - dons, err := registry.GetDONs(nil) - if err != nil { - return 0, err - } - // TODO: what happens if there are multiple dons for one chain (accidentally?) - for _, don := range dons { - if len(don.CapabilityConfigurations) == 1 && - don.CapabilityConfigurations[0].CapabilityId == CCIPCapabilityID { - configs, err := ccipHome.GetAllConfigs(nil, don.Id, uint8(cctypes.PluginTypeCCIPCommit)) - if err != nil { - return 0, err - } - if configs.ActiveConfig.Config.ChainSelector == chainSelector || configs.CandidateConfig.Config.ChainSelector == chainSelector { - return don.Id, nil - } - } - } - return 0, fmt.Errorf("no DON found for chain %d", chainSelector) -} - -func BuildSetOCR3ConfigArgs( - donID uint32, - ccipHome *ccip_home.CCIPHome, - destSelector uint64, -) ([]offramp.MultiOCR3BaseOCRConfigArgs, error) { - var offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs - for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { - ocrConfig, err2 := ccipHome.GetAllConfigs(&bind.CallOpts{ - Context: context.Background(), - }, donID, uint8(pluginType)) - if err2 != nil { - return nil, err2 - } - - fmt.Printf("pluginType: %s, destSelector: %d, donID: %d, activeConfig digest: %x, candidateConfig digest: %x\n", - pluginType.String(), destSelector, donID, ocrConfig.ActiveConfig.ConfigDigest, ocrConfig.CandidateConfig.ConfigDigest) - - // we expect only an active config and no candidate config. - if ocrConfig.ActiveConfig.ConfigDigest == [32]byte{} || ocrConfig.CandidateConfig.ConfigDigest != [32]byte{} { - return nil, fmt.Errorf("invalid OCR3 config state, expected active config and no candidate config, donID: %d", donID) - } - - activeConfig := ocrConfig.ActiveConfig - var signerAddresses []common.Address - var transmitterAddresses []common.Address - for _, node := range activeConfig.Config.Nodes { - signerAddresses = append(signerAddresses, common.BytesToAddress(node.SignerKey)) - transmitterAddresses = append(transmitterAddresses, common.BytesToAddress(node.TransmitterKey)) - } - - offrampOCR3Configs = append(offrampOCR3Configs, offramp.MultiOCR3BaseOCRConfigArgs{ - ConfigDigest: activeConfig.ConfigDigest, - OcrPluginType: uint8(pluginType), - F: activeConfig.Config.FRoleDON, - IsSignatureVerificationEnabled: pluginType == cctypes.PluginTypeCCIPCommit, - Signers: signerAddresses, - Transmitters: transmitterAddresses, - }) - } - return offrampOCR3Configs, nil -} - // CreateDON creates one DON with 2 plugins (commit and exec) // It first set a new candidate for the DON with the first plugin type and AddDON on capReg // Then for subsequent operations it uses UpdateDON to promote the first plugin to the active deployment @@ -617,154 +332,26 @@ func CreateDON( return fmt.Errorf("missing exec plugin in ocr3Configs") } - latestDon, err := LatestCCIPDON(capReg) + latestDon, err := internal.LatestCCIPDON(capReg) if err != nil { return err } donID := latestDon.Id + 1 - err = setupCommitDON(donID, commitConfig, capReg, home, nodes, ccipHome) + err = internal.SetupCommitDON(donID, commitConfig, capReg, home, nodes, ccipHome) if err != nil { return fmt.Errorf("setup commit don: %w", err) } // TODO: bug in contract causing this to not work as expected. - err = setupExecDON(donID, execConfig, capReg, home, nodes, ccipHome) + err = internal.SetupExecDON(donID, execConfig, capReg, home, nodes, ccipHome) if err != nil { return fmt.Errorf("setup exec don: %w", err) } return ValidateCCIPHomeConfigSetUp(capReg, ccipHome, newChainSel) } -func setupExecDON( - donID uint32, - execConfig ccip_home.CCIPHomeOCR3Config, - capReg *capabilities_registry.CapabilitiesRegistry, - home deployment.Chain, - nodes deployment.Nodes, - ccipHome *ccip_home.CCIPHome, -) error { - encodedSetCandidateCall, err := CCIPHomeABI.Pack( - "setCandidate", - donID, - execConfig.PluginType, - execConfig, - [32]byte{}, - ) - if err != nil { - return fmt.Errorf("pack set candidate call: %w", err) - } - - // set candidate call - tx, err := capReg.UpdateDON( - home.DeployerKey, - donID, - nodes.PeerIDs(), - []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ - { - CapabilityId: CCIPCapabilityID, - Config: encodedSetCandidateCall, - }, - }, - false, - nodes.DefaultF(), - ) - if err != nil { - return fmt.Errorf("update don w/ exec config: %w", err) - } - - if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { - return fmt.Errorf("confirm update don w/ exec config: %w", err) - } - - execCandidateDigest, err := ccipHome.GetCandidateDigest(nil, donID, execConfig.PluginType) - if err != nil { - return fmt.Errorf("get exec candidate digest 1st time: %w", err) - } - - if execCandidateDigest == [32]byte{} { - return fmt.Errorf("candidate digest is empty, expected nonempty") - } - - // promote candidate call - encodedPromotionCall, err := CCIPHomeABI.Pack( - "promoteCandidateAndRevokeActive", - donID, - execConfig.PluginType, - execCandidateDigest, - [32]byte{}, - ) - if err != nil { - return fmt.Errorf("pack promotion call: %w", err) - } - - tx, err = capReg.UpdateDON( - home.DeployerKey, - donID, - nodes.PeerIDs(), - []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ - { - CapabilityId: CCIPCapabilityID, - Config: encodedPromotionCall, - }, - }, - false, - nodes.DefaultF(), - ) - if err != nil { - return fmt.Errorf("update don w/ exec config: %w", err) - } - bn, err := deployment.ConfirmIfNoError(home, tx, err) - if err != nil { - return fmt.Errorf("confirm update don w/ exec config: %w", err) - } - if bn == 0 { - return fmt.Errorf("UpdateDON tx not confirmed") - } - // check if candidate digest is promoted - pEvent, err := ccipHome.FilterConfigPromoted(&bind.FilterOpts{ - Context: context.Background(), - Start: bn, - }, [][32]byte{execCandidateDigest}) - if err != nil { - return fmt.Errorf("filter exec config promoted: %w", err) - } - if !pEvent.Next() { - return fmt.Errorf("exec config not promoted") - } - // check that candidate digest is empty. - execCandidateDigest, err = ccipHome.GetCandidateDigest(nil, donID, execConfig.PluginType) - if err != nil { - return fmt.Errorf("get exec candidate digest 2nd time: %w", err) - } - - if execCandidateDigest != [32]byte{} { - return fmt.Errorf("candidate digest is nonempty after promotion, expected empty") - } - - // check that active digest is non-empty. - execActiveDigest, err := ccipHome.GetActiveDigest(nil, donID, uint8(cctypes.PluginTypeCCIPExec)) - if err != nil { - return fmt.Errorf("get active exec digest: %w", err) - } - - if execActiveDigest == [32]byte{} { - return fmt.Errorf("active exec digest is empty, expected nonempty") - } - - execConfigs, err := ccipHome.GetAllConfigs(nil, donID, uint8(cctypes.PluginTypeCCIPExec)) - if err != nil { - return fmt.Errorf("get all exec configs 2nd time: %w", err) - } - - // print the above info - fmt.Printf("completed exec DON creation and promotion: donID: %d execCandidateDigest: %x, execActiveDigest: %x, execCandidateDigestFromGetAllConfigs: %x, execActiveDigestFromGetAllConfigs: %x\n", - donID, execCandidateDigest, execActiveDigest, execConfigs.CandidateConfig.ConfigDigest, execConfigs.ActiveConfig.ConfigDigest) - - return nil -} - // SetCandidateCommitPluginWithAddDonOps sets the candidate commit config by calling setCandidate on CCIPHome contract through the AddDON call on CapReg contract // This should be done first before calling any other UpdateDON calls // This proposes to set up OCR3 config for the commit plugin for the DON @@ -774,7 +361,7 @@ func NewDonWithCandidateOp( capReg *capabilities_registry.CapabilitiesRegistry, nodes deployment.Nodes, ) (mcms.Operation, error) { - encodedSetCandidateCall, err := CCIPHomeABI.Pack( + encodedSetCandidateCall, err := internal.CCIPHomeABI.Pack( "setCandidate", donID, pluginConfig.PluginType, @@ -786,7 +373,7 @@ func NewDonWithCandidateOp( } addDonTx, err := capReg.AddDON(deployment.SimTransactOpts(), nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ { - CapabilityId: CCIPCapabilityID, + CapabilityId: internal.CCIPCapabilityID, Config: encodedSetCandidateCall, }, }, false, false, nodes.DefaultF()) @@ -807,7 +394,7 @@ func ValidateCCIPHomeConfigSetUp( chainSel uint64, ) error { // fetch DONID - donID, err := DonIDForChain(capReg, ccipHome, chainSel) + donID, err := internal.DonIDForChain(capReg, ccipHome, chainSel) if err != nil { return fmt.Errorf("fetch don id for chain: %w", err) } @@ -850,112 +437,6 @@ func ValidateCCIPHomeConfigSetUp( return nil } -func setupCommitDON( - donID uint32, - commitConfig ccip_home.CCIPHomeOCR3Config, - capReg *capabilities_registry.CapabilitiesRegistry, - home deployment.Chain, - nodes deployment.Nodes, - ccipHome *ccip_home.CCIPHome, -) error { - encodedSetCandidateCall, err := CCIPHomeABI.Pack( - "setCandidate", - donID, - commitConfig.PluginType, - commitConfig, - [32]byte{}, - ) - if err != nil { - return fmt.Errorf("pack set candidate call: %w", err) - } - tx, err := capReg.AddDON(home.DeployerKey, nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ - { - CapabilityId: CCIPCapabilityID, - Config: encodedSetCandidateCall, - }, - }, false, false, nodes.DefaultF()) - if err != nil { - return fmt.Errorf("add don w/ commit config: %w", err) - } - - if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { - return fmt.Errorf("confirm add don w/ commit config: %w", err) - } - - commitCandidateDigest, err := ccipHome.GetCandidateDigest(nil, donID, commitConfig.PluginType) - if err != nil { - return fmt.Errorf("get commit candidate digest: %w", err) - } - - if commitCandidateDigest == [32]byte{} { - return fmt.Errorf("candidate digest is empty, expected nonempty") - } - fmt.Printf("commit candidate digest after setCandidate: %x\n", commitCandidateDigest) - - encodedPromotionCall, err := CCIPHomeABI.Pack( - "promoteCandidateAndRevokeActive", - donID, - commitConfig.PluginType, - commitCandidateDigest, - [32]byte{}, - ) - if err != nil { - return fmt.Errorf("pack promotion call: %w", err) - } - - tx, err = capReg.UpdateDON( - home.DeployerKey, - donID, - nodes.PeerIDs(), - []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ - { - CapabilityId: CCIPCapabilityID, - Config: encodedPromotionCall, - }, - }, - false, - nodes.DefaultF(), - ) - if err != nil { - return fmt.Errorf("update don w/ commit config: %w", err) - } - - if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { - return fmt.Errorf("confirm update don w/ commit config: %w", err) - } - - // check that candidate digest is empty. - commitCandidateDigest, err = ccipHome.GetCandidateDigest(nil, donID, commitConfig.PluginType) - if err != nil { - return fmt.Errorf("get commit candidate digest 2nd time: %w", err) - } - - if commitCandidateDigest != [32]byte{} { - return fmt.Errorf("candidate digest is nonempty after promotion, expected empty") - } - - // check that active digest is non-empty. - commitActiveDigest, err := ccipHome.GetActiveDigest(nil, donID, uint8(cctypes.PluginTypeCCIPCommit)) - if err != nil { - return fmt.Errorf("get active commit digest: %w", err) - } - - if commitActiveDigest == [32]byte{} { - return fmt.Errorf("active commit digest is empty, expected nonempty") - } - - commitConfigs, err := ccipHome.GetAllConfigs(nil, donID, uint8(cctypes.PluginTypeCCIPCommit)) - if err != nil { - return fmt.Errorf("get all commit configs 2nd time: %w", err) - } - - // print the above information - fmt.Printf("completed commit DON creation and promotion: donID: %d, commitCandidateDigest: %x, commitActiveDigest: %x, commitCandidateDigestFromGetAllConfigs: %x, commitActiveDigestFromGetAllConfigs: %x\n", - donID, commitCandidateDigest, commitActiveDigest, commitConfigs.CandidateConfig.ConfigDigest, commitConfigs.ActiveConfig.ConfigDigest) - - return nil -} - func AddDON( lggr logger.Logger, ocrSecrets deployment.OCRSecrets, @@ -971,7 +452,7 @@ func AddDON( nodes deployment.Nodes, tokenConfigs []pluginconfig.TokenDataObserverConfig, ) error { - ocrConfigs, err := BuildOCR3ConfigForCCIPHome( + ocrConfigs, err := internal.BuildOCR3ConfigForCCIPHome( ocrSecrets, offRamp, dest, feedChainSel, tokenInfo, nodes, rmnHomeAddress, tokenConfigs) if err != nil { return err @@ -980,13 +461,13 @@ func AddDON( if err != nil { return err } - don, err := LatestCCIPDON(capReg) + don, err := internal.LatestCCIPDON(capReg) if err != nil { return err } lggr.Infow("Added DON", "donID", don.Id) - offrampOCR3Configs, err := BuildSetOCR3ConfigArgs(don.Id, ccipHome, dest.Selector) + offrampOCR3Configs, err := internal.BuildSetOCR3ConfigArgs(don.Id, ccipHome, dest.Selector) if err != nil { return err } diff --git a/deployment/ccip/changeset/internal/deploy_home_chain.go b/deployment/ccip/changeset/internal/deploy_home_chain.go index 5bf0569ce8c..af41b290828 100644 --- a/deployment/ccip/changeset/internal/deploy_home_chain.go +++ b/deployment/ccip/changeset/internal/deploy_home_chain.go @@ -1 +1,536 @@ package internal + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + + "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" +) + +const ( + CapabilityLabelledName = "ccip" + CapabilityVersion = "v1.0.0" + + FirstBlockAge = 8 * time.Hour + RemoteGasPriceBatchWriteFrequency = 30 * time.Minute + TokenPriceBatchWriteFrequency = 30 * time.Minute + BatchGasLimit = 6_500_000 + RelativeBoostPerWaitHour = 1.5 + InflightCacheExpiry = 10 * time.Minute + RootSnoozeTime = 30 * time.Minute + BatchingStrategyID = 0 + DeltaProgress = 30 * time.Second + DeltaResend = 10 * time.Second + DeltaInitial = 20 * time.Second + DeltaRound = 2 * time.Second + DeltaGrace = 2 * time.Second + DeltaCertifiedCommitRequest = 10 * time.Second + DeltaStage = 10 * time.Second + Rmax = 3 + MaxDurationQuery = 500 * time.Millisecond + MaxDurationObservation = 5 * time.Second + MaxDurationShouldAcceptAttestedReport = 10 * time.Second + MaxDurationShouldTransmitAcceptedReport = 10 * time.Second +) + +var ( + CCIPCapabilityID = utils.Keccak256Fixed(MustABIEncode(`[{"type": "string"}, {"type": "string"}]`, CapabilityLabelledName, CapabilityVersion)) + CCIPHomeABI *abi.ABI +) + +func init() { + var err error + CCIPHomeABI, err = ccip_home.CCIPHomeMetaData.GetAbi() + if err != nil { + panic(err) + } +} + +func MustABIEncode(abiString string, args ...interface{}) []byte { + encoded, err := utils.ABIEncode(abiString, args...) + if err != nil { + panic(err) + } + return encoded +} + +// getNodeOperatorIDMap returns a map of node operator names to their IDs +// If maxNops is greater than the number of node operators, it will return all node operators +// Unused now but could be useful in the future. +func getNodeOperatorIDMap(capReg *capabilities_registry.CapabilitiesRegistry, maxNops uint32) (map[string]uint32, error) { + nopIdByName := make(map[string]uint32) + operators, err := capReg.GetNodeOperators(nil) + if err != nil { + return nil, err + } + if len(operators) < int(maxNops) { + maxNops = uint32(len(operators)) + } + for i := uint32(1); i <= maxNops; i++ { + operator, err := capReg.GetNodeOperator(nil, i) + if err != nil { + return nil, err + } + nopIdByName[operator.Name] = i + } + return nopIdByName, nil +} + +func LatestCCIPDON(registry *capabilities_registry.CapabilitiesRegistry) (*capabilities_registry.CapabilitiesRegistryDONInfo, error) { + dons, err := registry.GetDONs(nil) + if err != nil { + return nil, err + } + var ccipDON capabilities_registry.CapabilitiesRegistryDONInfo + for _, don := range dons { + if len(don.CapabilityConfigurations) == 1 && + don.CapabilityConfigurations[0].CapabilityId == CCIPCapabilityID && + don.Id > ccipDON.Id { + ccipDON = don + } + } + return &ccipDON, nil +} + +// DonIDForChain returns the DON ID for the chain with the given selector +// It looks up with the CCIPHome contract to find the OCR3 configs for the DONs, and returns the DON ID for the chain matching with the given selector from the OCR3 configs +func DonIDForChain(registry *capabilities_registry.CapabilitiesRegistry, ccipHome *ccip_home.CCIPHome, chainSelector uint64) (uint32, error) { + dons, err := registry.GetDONs(nil) + if err != nil { + return 0, err + } + // TODO: what happens if there are multiple dons for one chain (accidentally?) + for _, don := range dons { + if len(don.CapabilityConfigurations) == 1 && + don.CapabilityConfigurations[0].CapabilityId == CCIPCapabilityID { + configs, err := ccipHome.GetAllConfigs(nil, don.Id, uint8(types.PluginTypeCCIPCommit)) + if err != nil { + return 0, err + } + if configs.ActiveConfig.Config.ChainSelector == chainSelector || configs.CandidateConfig.Config.ChainSelector == chainSelector { + return don.Id, nil + } + } + } + return 0, fmt.Errorf("no DON found for chain %d", chainSelector) +} + +func BuildSetOCR3ConfigArgs( + donID uint32, + ccipHome *ccip_home.CCIPHome, + destSelector uint64, +) ([]offramp.MultiOCR3BaseOCRConfigArgs, error) { + var offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs + for _, pluginType := range []types.PluginType{types.PluginTypeCCIPCommit, types.PluginTypeCCIPExec} { + ocrConfig, err2 := ccipHome.GetAllConfigs(&bind.CallOpts{ + Context: context.Background(), + }, donID, uint8(pluginType)) + if err2 != nil { + return nil, err2 + } + + fmt.Printf("pluginType: %s, destSelector: %d, donID: %d, activeConfig digest: %x, candidateConfig digest: %x\n", + pluginType.String(), destSelector, donID, ocrConfig.ActiveConfig.ConfigDigest, ocrConfig.CandidateConfig.ConfigDigest) + + // we expect only an active config and no candidate config. + if ocrConfig.ActiveConfig.ConfigDigest == [32]byte{} || ocrConfig.CandidateConfig.ConfigDigest != [32]byte{} { + return nil, fmt.Errorf("invalid OCR3 config state, expected active config and no candidate config, donID: %d", donID) + } + + activeConfig := ocrConfig.ActiveConfig + var signerAddresses []common.Address + var transmitterAddresses []common.Address + for _, node := range activeConfig.Config.Nodes { + signerAddresses = append(signerAddresses, common.BytesToAddress(node.SignerKey)) + transmitterAddresses = append(transmitterAddresses, common.BytesToAddress(node.TransmitterKey)) + } + + offrampOCR3Configs = append(offrampOCR3Configs, offramp.MultiOCR3BaseOCRConfigArgs{ + ConfigDigest: activeConfig.ConfigDigest, + OcrPluginType: uint8(pluginType), + F: activeConfig.Config.FRoleDON, + IsSignatureVerificationEnabled: pluginType == types.PluginTypeCCIPCommit, + Signers: signerAddresses, + Transmitters: transmitterAddresses, + }) + } + return offrampOCR3Configs, nil +} + +func SetupExecDON( + donID uint32, + execConfig ccip_home.CCIPHomeOCR3Config, + capReg *capabilities_registry.CapabilitiesRegistry, + home deployment.Chain, + nodes deployment.Nodes, + ccipHome *ccip_home.CCIPHome, +) error { + encodedSetCandidateCall, err := CCIPHomeABI.Pack( + "setCandidate", + donID, + execConfig.PluginType, + execConfig, + [32]byte{}, + ) + if err != nil { + return fmt.Errorf("pack set candidate call: %w", err) + } + + // set candidate call + tx, err := capReg.UpdateDON( + home.DeployerKey, + donID, + nodes.PeerIDs(), + []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: CCIPCapabilityID, + Config: encodedSetCandidateCall, + }, + }, + false, + nodes.DefaultF(), + ) + if err != nil { + return fmt.Errorf("update don w/ exec config: %w", err) + } + + if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { + return fmt.Errorf("confirm update don w/ exec config: %w", err) + } + + execCandidateDigest, err := ccipHome.GetCandidateDigest(nil, donID, execConfig.PluginType) + if err != nil { + return fmt.Errorf("get exec candidate digest 1st time: %w", err) + } + + if execCandidateDigest == [32]byte{} { + return fmt.Errorf("candidate digest is empty, expected nonempty") + } + + // promote candidate call + encodedPromotionCall, err := CCIPHomeABI.Pack( + "promoteCandidateAndRevokeActive", + donID, + execConfig.PluginType, + execCandidateDigest, + [32]byte{}, + ) + if err != nil { + return fmt.Errorf("pack promotion call: %w", err) + } + + tx, err = capReg.UpdateDON( + home.DeployerKey, + donID, + nodes.PeerIDs(), + []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: CCIPCapabilityID, + Config: encodedPromotionCall, + }, + }, + false, + nodes.DefaultF(), + ) + if err != nil { + return fmt.Errorf("update don w/ exec config: %w", err) + } + bn, err := deployment.ConfirmIfNoError(home, tx, err) + if err != nil { + return fmt.Errorf("confirm update don w/ exec config: %w", err) + } + if bn == 0 { + return fmt.Errorf("UpdateDON tx not confirmed") + } + // check if candidate digest is promoted + pEvent, err := ccipHome.FilterConfigPromoted(&bind.FilterOpts{ + Context: context.Background(), + Start: bn, + }, [][32]byte{execCandidateDigest}) + if err != nil { + return fmt.Errorf("filter exec config promoted: %w", err) + } + if !pEvent.Next() { + return fmt.Errorf("exec config not promoted") + } + // check that candidate digest is empty. + execCandidateDigest, err = ccipHome.GetCandidateDigest(nil, donID, execConfig.PluginType) + if err != nil { + return fmt.Errorf("get exec candidate digest 2nd time: %w", err) + } + + if execCandidateDigest != [32]byte{} { + return fmt.Errorf("candidate digest is nonempty after promotion, expected empty") + } + + // check that active digest is non-empty. + execActiveDigest, err := ccipHome.GetActiveDigest(nil, donID, uint8(types.PluginTypeCCIPExec)) + if err != nil { + return fmt.Errorf("get active exec digest: %w", err) + } + + if execActiveDigest == [32]byte{} { + return fmt.Errorf("active exec digest is empty, expected nonempty") + } + + execConfigs, err := ccipHome.GetAllConfigs(nil, donID, uint8(types.PluginTypeCCIPExec)) + if err != nil { + return fmt.Errorf("get all exec configs 2nd time: %w", err) + } + + // print the above info + fmt.Printf("completed exec DON creation and promotion: donID: %d execCandidateDigest: %x, execActiveDigest: %x, execCandidateDigestFromGetAllConfigs: %x, execActiveDigestFromGetAllConfigs: %x\n", + donID, execCandidateDigest, execActiveDigest, execConfigs.CandidateConfig.ConfigDigest, execConfigs.ActiveConfig.ConfigDigest) + + return nil +} + +func SetupCommitDON( + donID uint32, + commitConfig ccip_home.CCIPHomeOCR3Config, + capReg *capabilities_registry.CapabilitiesRegistry, + home deployment.Chain, + nodes deployment.Nodes, + ccipHome *ccip_home.CCIPHome, +) error { + encodedSetCandidateCall, err := CCIPHomeABI.Pack( + "setCandidate", + donID, + commitConfig.PluginType, + commitConfig, + [32]byte{}, + ) + if err != nil { + return fmt.Errorf("pack set candidate call: %w", err) + } + tx, err := capReg.AddDON(home.DeployerKey, nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: CCIPCapabilityID, + Config: encodedSetCandidateCall, + }, + }, false, false, nodes.DefaultF()) + if err != nil { + return fmt.Errorf("add don w/ commit config: %w", err) + } + + if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { + return fmt.Errorf("confirm add don w/ commit config: %w", err) + } + + commitCandidateDigest, err := ccipHome.GetCandidateDigest(nil, donID, commitConfig.PluginType) + if err != nil { + return fmt.Errorf("get commit candidate digest: %w", err) + } + + if commitCandidateDigest == [32]byte{} { + return fmt.Errorf("candidate digest is empty, expected nonempty") + } + fmt.Printf("commit candidate digest after setCandidate: %x\n", commitCandidateDigest) + + encodedPromotionCall, err := CCIPHomeABI.Pack( + "promoteCandidateAndRevokeActive", + donID, + commitConfig.PluginType, + commitCandidateDigest, + [32]byte{}, + ) + if err != nil { + return fmt.Errorf("pack promotion call: %w", err) + } + + tx, err = capReg.UpdateDON( + home.DeployerKey, + donID, + nodes.PeerIDs(), + []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: CCIPCapabilityID, + Config: encodedPromotionCall, + }, + }, + false, + nodes.DefaultF(), + ) + if err != nil { + return fmt.Errorf("update don w/ commit config: %w", err) + } + + if _, err := deployment.ConfirmIfNoError(home, tx, err); err != nil { + return fmt.Errorf("confirm update don w/ commit config: %w", err) + } + + // check that candidate digest is empty. + commitCandidateDigest, err = ccipHome.GetCandidateDigest(nil, donID, commitConfig.PluginType) + if err != nil { + return fmt.Errorf("get commit candidate digest 2nd time: %w", err) + } + + if commitCandidateDigest != [32]byte{} { + return fmt.Errorf("candidate digest is nonempty after promotion, expected empty") + } + + // check that active digest is non-empty. + commitActiveDigest, err := ccipHome.GetActiveDigest(nil, donID, uint8(types.PluginTypeCCIPCommit)) + if err != nil { + return fmt.Errorf("get active commit digest: %w", err) + } + + if commitActiveDigest == [32]byte{} { + return fmt.Errorf("active commit digest is empty, expected nonempty") + } + + commitConfigs, err := ccipHome.GetAllConfigs(nil, donID, uint8(types.PluginTypeCCIPCommit)) + if err != nil { + return fmt.Errorf("get all commit configs 2nd time: %w", err) + } + + // print the above information + fmt.Printf("completed commit DON creation and promotion: donID: %d, commitCandidateDigest: %x, commitActiveDigest: %x, commitCandidateDigestFromGetAllConfigs: %x, commitActiveDigestFromGetAllConfigs: %x\n", + donID, commitCandidateDigest, commitActiveDigest, commitConfigs.CandidateConfig.ConfigDigest, commitConfigs.ActiveConfig.ConfigDigest) + + return nil +} + +func BuildOCR3ConfigForCCIPHome( + ocrSecrets deployment.OCRSecrets, + offRamp *offramp.OffRamp, + dest deployment.Chain, + feedChainSel uint64, + tokenInfo map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo, + nodes deployment.Nodes, + rmnHomeAddress common.Address, + configs []pluginconfig.TokenDataObserverConfig, +) (map[types.PluginType]ccip_home.CCIPHomeOCR3Config, error) { + p2pIDs := nodes.PeerIDs() + // Get OCR3 Config from helper + var schedule []int + var oracles []confighelper.OracleIdentityExtra + for _, node := range nodes { + schedule = append(schedule, 1) + cfg := node.SelToOCRConfig[dest.Selector] + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: cfg.OnchainPublicKey, + TransmitAccount: cfg.TransmitAccount, + OffchainPublicKey: cfg.OffchainPublicKey, + PeerID: cfg.PeerID.String()[4:], + }, ConfigEncryptionPublicKey: cfg.ConfigEncryptionPublicKey, + }) + } + + // Add DON on capability registry contract + ocr3Configs := make(map[types.PluginType]ccip_home.CCIPHomeOCR3Config) + for _, pluginType := range []types.PluginType{types.PluginTypeCCIPCommit, types.PluginTypeCCIPExec} { + var encodedOffchainConfig []byte + var err2 error + if pluginType == types.PluginTypeCCIPCommit { + encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ + RemoteGasPriceBatchWriteFrequency: *config.MustNewDuration(RemoteGasPriceBatchWriteFrequency), + TokenPriceBatchWriteFrequency: *config.MustNewDuration(TokenPriceBatchWriteFrequency), + PriceFeedChainSelector: ccipocr3.ChainSelector(feedChainSel), + TokenInfo: tokenInfo, + NewMsgScanBatchSize: merklemulti.MaxNumberTreeLeaves, + MaxReportTransmissionCheckAttempts: 5, + MaxMerkleTreeSize: merklemulti.MaxNumberTreeLeaves, + SignObservationPrefix: "chainlink ccip 1.6 rmn observation", + RMNEnabled: os.Getenv("ENABLE_RMN") == "true", // only enabled in manual test + }) + } else { + encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ + BatchGasLimit: BatchGasLimit, + RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, + MessageVisibilityInterval: *config.MustNewDuration(FirstBlockAge), + InflightCacheExpiry: *config.MustNewDuration(InflightCacheExpiry), + RootSnoozeTime: *config.MustNewDuration(RootSnoozeTime), + BatchingStrategyID: BatchingStrategyID, + TokenDataObservers: configs, + }) + } + if err2 != nil { + return nil, err2 + } + signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsDeterministic( + ocrSecrets.EphemeralSk, + ocrSecrets.SharedSecret, + DeltaProgress, + DeltaResend, + DeltaInitial, + DeltaRound, + DeltaGrace, + DeltaCertifiedCommitRequest, + DeltaStage, + Rmax, + schedule, + oracles, + encodedOffchainConfig, + nil, // maxDurationInitialization + MaxDurationQuery, + MaxDurationObservation, + MaxDurationShouldAcceptAttestedReport, + MaxDurationShouldTransmitAcceptedReport, + int(nodes.DefaultF()), + []byte{}, // empty OnChainConfig + ) + if err2 != nil { + return nil, err2 + } + + signersBytes := make([][]byte, len(signers)) + for i, signer := range signers { + signersBytes[i] = signer + } + + transmittersBytes := make([][]byte, len(transmitters)) + for i, transmitter := range transmitters { + parsed, err2 := common.ParseHexOrString(string(transmitter)) + if err2 != nil { + return nil, err2 + } + transmittersBytes[i] = parsed + } + + var ocrNodes []ccip_home.CCIPHomeOCR3Node + for i := range nodes { + ocrNodes = append(ocrNodes, ccip_home.CCIPHomeOCR3Node{ + P2pId: p2pIDs[i], + SignerKey: signersBytes[i], + TransmitterKey: transmittersBytes[i], + }) + } + + _, ok := ocr3Configs[pluginType] + if ok { + return nil, fmt.Errorf("pluginType %s already exists in ocr3Configs", pluginType.String()) + } + + ocr3Configs[pluginType] = ccip_home.CCIPHomeOCR3Config{ + PluginType: uint8(pluginType), + ChainSelector: dest.Selector, + FRoleDON: configF, + OffchainConfigVersion: offchainConfigVersion, + OfframpAddress: offRamp.Address().Bytes(), + Nodes: ocrNodes, + OffchainConfig: offchainConfig, + RmnHomeAddress: rmnHomeAddress.Bytes(), + } + } + + return ocr3Configs, nil +} diff --git a/deployment/ccip/changeset/jobs.go b/deployment/ccip/changeset/jobs.go index 5cfe112ff53..3a5b0e294d8 100644 --- a/deployment/ccip/changeset/jobs.go +++ b/deployment/ccip/changeset/jobs.go @@ -2,6 +2,7 @@ package changeset import ( "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) @@ -26,8 +27,8 @@ func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string if !node.IsBootstrap { spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ P2PV2Bootstrappers: nodes.BootstrapLocators(), - CapabilityVersion: CapabilityVersion, - CapabilityLabelledName: CapabilityLabelledName, + CapabilityVersion: internal.CapabilityVersion, + CapabilityLabelledName: internal.CapabilityLabelledName, OCRKeyBundleIDs: map[string]string{ // TODO: Validate that that all EVM chains are using the same keybundle. relay.NetworkEVM: node.FirstOCRKeybundle().KeyBundleID, @@ -39,8 +40,8 @@ func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string } else { spec, err = validate.NewCCIPSpecToml(validate.SpecArgs{ P2PV2Bootstrappers: []string{}, // Intentionally empty for bootstraps. - CapabilityVersion: CapabilityVersion, - CapabilityLabelledName: CapabilityLabelledName, + CapabilityVersion: internal.CapabilityVersion, + CapabilityLabelledName: internal.CapabilityLabelledName, OCRKeyBundleIDs: map[string]string{}, // TODO: validate that all EVM chains are using the same keybundle P2PKeyID: node.PeerID.String(), From 17ca5355bcc2bf34d4918c190bbda0ae64165b34 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 10:47:16 -0500 Subject: [PATCH 07/27] Update README --- deployment/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/deployment/README.md b/deployment/README.md index 723397edc1c..c6579ca6205 100644 --- a/deployment/README.md +++ b/deployment/README.md @@ -100,10 +100,12 @@ TODO: Add various examples in deployment/example. contracts (like MCMS, LinkToken etc) which can be shared by products. -/deployment/ -- package name `deployment` +/deployment//internal - Internal building blocks for changesets -- TODO: can we make this `internal`? + +/deployment//view +- Hold readonly mappings Go bindings to json marshallable objects. +- Used to generate a view of the system. /deployment//changeset - Think of this as the public API for deployment and configuration From 77f11994874cd96e072595ae71822983e2c4c751 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 11:11:51 -0500 Subject: [PATCH 08/27] Fix integration tests --- integration-tests/ccip-tests/testsetups/test_helpers.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index 042a768a96c..e50d4dcf960 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -118,7 +118,7 @@ func NewLocalDevEnvironment( envNodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) require.NoError(t, err) - _, err = changeset.DeployHomeChain(*e, + out, err := changeset.DeployHomeChain(*e, changeset.DeployHomeChainConfig{ HomeChainSel: homeChainSel, RMNStaticConfig: changeset.NewTestRMNStaticConfig(), @@ -130,6 +130,7 @@ func NewLocalDevEnvironment( }, ) require.NoError(t, err) + require.NoError(t, e.ExistingAddresses.Merge(out.AddressBook)) zeroLogLggr := logging.GetTestLogger(t) // fund the nodes FundNodes(t, zeroLogLggr, testEnv, cfg, don.PluginNodes()) From 8e9de1730f7cf7df8a77cad95d4e94ca91651998 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 11:28:31 -0500 Subject: [PATCH 09/27] More merge conflicts --- deployment/ccip/changeset/active_candidate_test.go | 4 ++-- deployment/ccip/changeset/initial_deploy_test.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index 18a6a52f3f6..7e0b90fecbe 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -35,7 +35,7 @@ func TestActiveCandidate(t *testing.T) { // 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 { @@ -52,7 +52,7 @@ func TestActiveCandidate(t *testing.T) { FeeToken: common.HexToAddress("0x0"), ExtraArgs: nil, }) - expectedSeqNum[ccdeploy.SourceDestPair{ + expectedSeqNum[SourceDestPair{ SourceChainSelector: src, DestChainSelector: dest, }] = msgSentEvent.SequenceNumber diff --git a/deployment/ccip/changeset/initial_deploy_test.go b/deployment/ccip/changeset/initial_deploy_test.go index dcf44e8bdf4..14ce267d646 100644 --- a/deployment/ccip/changeset/initial_deploy_test.go +++ b/deployment/ccip/changeset/initial_deploy_test.go @@ -81,7 +81,7 @@ func TestInitialDeploy(t *testing.T) { // 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 { @@ -99,7 +99,7 @@ func TestInitialDeploy(t *testing.T) { FeeToken: common.HexToAddress("0x0"), ExtraArgs: nil, }) - expectedSeqNum[ccdeploy.SourceDestPair{ + expectedSeqNum[SourceDestPair{ SourceChainSelector: src, DestChainSelector: dest, }] = msgSentEvent.SequenceNumber @@ -113,7 +113,7 @@ func TestInitialDeploy(t *testing.T) { ConfirmTokenPriceUpdatedForAll(t, e, state, startBlocks, DefaultInitialPrices.LinkPrice, DefaultInitialPrices.WethPrice) // TODO: Fix gas prices? - //ccdeploy.ConfirmGasPriceUpdatedForAll(t, e, state, startBlocks) + //ConfirmGasPriceUpdatedForAll(t, e, state, startBlocks) // //// Wait for all exec reports to land ConfirmExecWithSeqNrForAll(t, e, state, expectedSeqNum, startBlocks) From 7d2bd9c5ae6582061b76ddd90b9e9884baf21652 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Wed, 20 Nov 2024 11:40:12 -0500 Subject: [PATCH 10/27] More merge conflicts --- integration-tests/smoke/ccip_messaging_test.go | 4 ++-- integration-tests/smoke/ccip_rmn_test.go | 4 ++-- integration-tests/smoke/ccip_test.go | 10 +++++----- integration-tests/smoke/ccip_usdc_test.go | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/integration-tests/smoke/ccip_messaging_test.go b/integration-tests/smoke/ccip_messaging_test.go index 3e6ac5b192e..654946d620a 100644 --- a/integration-tests/smoke/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip_messaging_test.go @@ -317,8 +317,8 @@ func runMessagingTestCase( FeeToken: common.HexToAddress("0x0"), ExtraArgs: extraArgs, }) - expectedSeqNum := make(map[ccdeploy.SourceDestPair]uint64) - expectedSeqNum[ccdeploy.SourceDestPair{ + expectedSeqNum := make(map[changeset.SourceDestPair]uint64) + expectedSeqNum[changeset.SourceDestPair{ SourceChainSelector: tc.sourceChain, DestChainSelector: tc.destChain, }] = msgSentEvent.SequenceNumber diff --git a/integration-tests/smoke/ccip_rmn_test.go b/integration-tests/smoke/ccip_rmn_test.go index 68f3b71eee4..6b7d54e0224 100644 --- a/integration-tests/smoke/ccip_rmn_test.go +++ b/integration-tests/smoke/ccip_rmn_test.go @@ -341,7 +341,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { // 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) - expectedSeqNum := make(map[ccipdeployment.SourceDestPair]uint64) + expectedSeqNum := make(map[changeset.SourceDestPair]uint64) for _, msg := range tc.messagesToSend { fromChain := chainSelectors[msg.fromChainIdx] toChain := chainSelectors[msg.toChainIdx] @@ -354,7 +354,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { FeeToken: common.HexToAddress("0x0"), ExtraArgs: nil, }) - expectedSeqNum[ccipdeployment.SourceDestPair{ + expectedSeqNum[changeset.SourceDestPair{ SourceChainSelector: fromChain, DestChainSelector: toChain, }] = msgSentEvent.SequenceNumber diff --git a/integration-tests/smoke/ccip_test.go b/integration-tests/smoke/ccip_test.go index 9b4e89d82d3..7996a4ccf0a 100644 --- a/integration-tests/smoke/ccip_test.go +++ b/integration-tests/smoke/ccip_test.go @@ -27,7 +27,7 @@ func TestInitialDeployOnLocal(t *testing.T) { // 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[changeset.SourceDestPair]uint64) for src := range e.Chains { for dest, destChain := range e.Chains { if src == dest { @@ -44,7 +44,7 @@ func TestInitialDeployOnLocal(t *testing.T) { FeeToken: common.HexToAddress("0x0"), ExtraArgs: nil, }) - expectedSeqNum[ccdeploy.SourceDestPair{ + expectedSeqNum[changeset.SourceDestPair{ SourceChainSelector: src, DestChainSelector: dest, }] = msgSentEvent.SequenceNumber @@ -93,7 +93,7 @@ func TestTokenTransfer(t *testing.T) { // 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[changeset.SourceDestPair]uint64) twoCoins := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2)) tx, err := srcToken.Mint( @@ -157,7 +157,7 @@ func TestTokenTransfer(t *testing.T) { FeeToken: feeToken, ExtraArgs: nil, }) - expectedSeqNum[ccdeploy.SourceDestPair{ + expectedSeqNum[changeset.SourceDestPair{ SourceChainSelector: src, DestChainSelector: dest, }] = msgSentEvent.SequenceNumber @@ -169,7 +169,7 @@ func TestTokenTransfer(t *testing.T) { FeeToken: feeToken, ExtraArgs: nil, }) - expectedSeqNum[ccdeploy.SourceDestPair{ + expectedSeqNum[changeset.SourceDestPair{ SourceChainSelector: src, DestChainSelector: dest, }] = msgSentEvent.SequenceNumber diff --git a/integration-tests/smoke/ccip_usdc_test.go b/integration-tests/smoke/ccip_usdc_test.go index d1bdf3b1f60..aef2c916842 100644 --- a/integration-tests/smoke/ccip_usdc_test.go +++ b/integration-tests/smoke/ccip_usdc_test.go @@ -213,7 +213,7 @@ func transferAndWaitForSuccess( data []byte, ) { startBlocks := make(map[uint64]*uint64) - expectedSeqNum := make(map[ccdeploy.SourceDestPair]uint64) + expectedSeqNum := make(map[changeset.SourceDestPair]uint64) latesthdr, err := env.Chains[destChain].Client.HeaderByNumber(testcontext.Get(t), nil) require.NoError(t, err) @@ -227,7 +227,7 @@ func transferAndWaitForSuccess( FeeToken: common.HexToAddress("0x0"), ExtraArgs: nil, }) - expectedSeqNum[ccdeploy.SourceDestPair{ + expectedSeqNum[changeset.SourceDestPair{ SourceChainSelector: sourceChain, DestChainSelector: destChain, }] = msgSentEvent.SequenceNumber From ef60262dd53c977453dbe4322f4d567fdf6e10a8 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 10:35:04 -0800 Subject: [PATCH 11/27] updates --- deployment/environment/devenv/environment.go | 44 ++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/deployment/environment/devenv/environment.go b/deployment/environment/devenv/environment.go index af39e59e3bf..4cae1b075b9 100644 --- a/deployment/environment/devenv/environment.go +++ b/deployment/environment/devenv/environment.go @@ -34,15 +34,17 @@ func NewEnvironment(ctx context.Context, lggr logger.Logger, config EnvironmentC if !ok { return nil, nil, fmt.Errorf("offchain client does not implement JobDistributor") } - if jd == nil || jd.don == nil { - return nil, nil, fmt.Errorf("offchain client does not have a DON") + if jd == nil { + return nil, nil, fmt.Errorf("offchain client is not set up") } - - err = jd.don.CreateSupportedChains(ctx, config.Chains, *jd) - if err != nil { - return nil, nil, err + var nodeIDs []string + if jd.don != nil { + err = jd.don.CreateSupportedChains(ctx, config.Chains, *jd) + if err != nil { + return nil, nil, err + } + nodeIDs = jd.don.NodeIds() } - nodeIDs := jd.don.NodeIds() return deployment.NewEnvironment( DevEnv, @@ -53,3 +55,31 @@ func NewEnvironment(ctx context.Context, lggr logger.Logger, config EnvironmentC offChain, ), jd.don, nil } + +func AddDonToEnvironment(ctx context.Context, config EnvironmentConfig, e *deployment.Environment) error { + if e.Offchain == nil { + return fmt.Errorf("offchain client not set up") + } + jd, ok := e.Offchain.(*JobDistributor) + if !ok { + return fmt.Errorf("offchain client does not implement JobDistributor") + } + if jd == nil { + return fmt.Errorf("offchain client is not set up") + } + if len(config.JDConfig.NodeInfo) == 0 { + return fmt.Errorf("no node info provided") + } + var err error + + jd.don, err = NewRegisteredDON(ctx, config.JDConfig.NodeInfo, *jd) + if err != nil { + return fmt.Errorf("failed to create registered DON: %w", err) + } + err = jd.don.CreateSupportedChains(ctx, config.Chains, *jd) + if err != nil { + return fmt.Errorf("failed to create supported chains: %w", err) + } + e.NodeIDs = jd.don.NodeIds() + return nil +} From aa9e9c9d784c5e2f417ad994a6178141d4d38a07 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 11:30:55 -0800 Subject: [PATCH 12/27] changes --- deployment/ccip/changeset/add_chain_test.go | 4 +- deployment/ccip/changeset/deploy.go | 261 +++++++++++------- deployment/ccip/changeset/deploy_chain.go | 5 + .../ccip/changeset/initial_add_chain.go | 32 +++ deployment/ccip/changeset/prerequisites.go | 2 +- deployment/ccip/changeset/test_helpers.go | 3 +- .../ccip/changeset/test_usdc_helpers.go | 8 +- 7 files changed, 205 insertions(+), 110 deletions(-) create mode 100644 deployment/ccip/changeset/initial_add_chain.go diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index aa702a002cd..ef255a55b09 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -39,7 +39,7 @@ func TestAddChainInbound(t *testing.T) { // We deploy to the rest. initialDeploy := e.Env.AllChainSelectorsExcluding([]uint64{newChain}) newAddresses := deployment.NewMemoryAddressBook() - err = DeployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy) + err = DeployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy, nil) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) @@ -94,7 +94,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) newAddresses = deployment.NewMemoryAddressBook() - err = DeployPrerequisiteChainContracts(e.Env, newAddresses, []uint64{newChain}) + err = DeployPrerequisiteChainContracts(e.Env, newAddresses, []uint64{newChain}, nil) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) newAddresses = deployment.NewMemoryAddressBook() diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 33459c17678..e67933bd9e4 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -8,10 +8,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" - cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment" @@ -33,29 +34,24 @@ import ( ) var ( - MockRMN deployment.ContractType = "MockRMN" - RMNRemote deployment.ContractType = "RMNRemote" - LinkToken deployment.ContractType = "LinkToken" - ARMProxy deployment.ContractType = "ARMProxy" - WETH9 deployment.ContractType = "WETH9" - Router deployment.ContractType = "Router" - CommitStore deployment.ContractType = "CommitStore" - TokenAdminRegistry deployment.ContractType = "TokenAdminRegistry" - RegistryModule deployment.ContractType = "RegistryModuleOwnerCustom" - NonceManager deployment.ContractType = "NonceManager" - FeeQuoter deployment.ContractType = "FeeQuoter" - AdminManyChainMultisig deployment.ContractType = "AdminManyChainMultiSig" - BypasserManyChainMultisig deployment.ContractType = "BypasserManyChainMultiSig" - CancellerManyChainMultisig deployment.ContractType = "CancellerManyChainMultiSig" - ProposerManyChainMultisig deployment.ContractType = "ProposerManyChainMultiSig" - CCIPHome deployment.ContractType = "CCIPHome" - CCIPConfig deployment.ContractType = "CCIPConfig" - RMNHome deployment.ContractType = "RMNHome" - RBACTimelock deployment.ContractType = "RBACTimelock" - OnRamp deployment.ContractType = "OnRamp" - OffRamp deployment.ContractType = "OffRamp" - CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" - PriceFeed deployment.ContractType = "PriceFeed" + MockRMN deployment.ContractType = "MockRMN" + RMNRemote deployment.ContractType = "RMNRemote" + LinkToken deployment.ContractType = "LinkToken" + ARMProxy deployment.ContractType = "ARMProxy" + WETH9 deployment.ContractType = "WETH9" + Router deployment.ContractType = "Router" + CommitStore deployment.ContractType = "CommitStore" + TokenAdminRegistry deployment.ContractType = "TokenAdminRegistry" + RegistryModule deployment.ContractType = "RegistryModuleOwnerCustom" + NonceManager deployment.ContractType = "NonceManager" + FeeQuoter deployment.ContractType = "FeeQuoter" + CCIPHome deployment.ContractType = "CCIPHome" + CCIPConfig deployment.ContractType = "CCIPConfig" + RMNHome deployment.ContractType = "RMNHome" + OnRamp deployment.ContractType = "OnRamp" + OffRamp deployment.ContractType = "OffRamp" + CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" + PriceFeed deployment.ContractType = "PriceFeed" // Note test router maps to a regular router contract. TestRouter deployment.ContractType = "TestRouter" CCIPReceiver deployment.ContractType = "CCIPReceiver" @@ -67,15 +63,20 @@ var ( USDCTokenPool deployment.ContractType = "USDCTokenPool" ) -func DeployPrerequisiteChainContracts(e deployment.Environment, ab deployment.AddressBook, selectors []uint64) error { +func DeployPrerequisiteChainContracts(e deployment.Environment, ab deployment.AddressBook, selectors []uint64, usdcEnabledChains []uint64) error { state, err := LoadOnchainState(e) if err != nil { e.Logger.Errorw("Failed to load existing onchain state", "err") return err } + mapUSDCEnabledChains := make(map[uint64]bool) + for _, chain := range usdcEnabledChains { + mapUSDCEnabledChains[chain] = true + } for _, sel := range selectors { chain := e.Chains[sel] - err = DeployPrerequisiteContracts(e, ab, state, chain) + usdcEnabled := mapUSDCEnabledChains[sel] + err = DeployPrerequisiteContracts(e, ab, state, chain, usdcEnabled) if err != nil { return errors.Wrapf(err, "failed to deploy prerequisite contracts for chain %d", sel) } @@ -85,7 +86,7 @@ func DeployPrerequisiteChainContracts(e deployment.Environment, ab deployment.Ad // DeployPrerequisiteContracts deploys the contracts that can be ported from previous CCIP version to the new one. // This is only required for staging and test environments where the contracts are not already deployed. -func DeployPrerequisiteContracts(e deployment.Environment, ab deployment.AddressBook, state CCIPOnChainState, chain deployment.Chain) error { +func DeployPrerequisiteContracts(e deployment.Environment, ab deployment.AddressBook, state CCIPOnChainState, chain deployment.Chain, usdcEnabled bool) error { lggr := e.Logger chainState, chainExists := state.Chains[chain.Selector] var weth9Contract *weth9.WETH9 @@ -265,43 +266,31 @@ func DeployPrerequisiteContracts(e deployment.Environment, ab deployment.Address } else { e.Logger.Infow("router already deployed", "addr", chainState.Router.Address) } + if usdcEnabled { + token, pool, messenger, transmitter, err1 := DeployUSDC(e.Logger, chain, ab, rmnProxy.Address(), r.Address()) + if err1 != nil { + return err1 + } + e.Logger.Infow("Deployed USDC contracts", + "chainSelector", chain.Selector, + "token", token.Address(), + "pool", pool.Address(), + "transmitter", transmitter.Address(), + "messenger", messenger.Address(), + ) + } return nil } -type USDCConfig struct { - Enabled bool - USDCAttestationConfig -} - -type USDCAttestationConfig struct { - API string - APITimeout *commonconfig.Duration - APIInterval *commonconfig.Duration -} - -type DeployCCIPContractConfig struct { - HomeChainSel uint64 - FeedChainSel uint64 - ChainsToDeploy []uint64 - TokenConfig TokenConfig - USDCConfig USDCConfig - // For setting OCR configuration - OCRSecrets deployment.OCRSecrets -} - -// DeployCCIPContracts assumes the following contracts are deployed: -// - Capability registry -// - CCIP home -// - RMN home -// - Fee tokens on all chains. -// and present in ExistingAddressBook. -// It then deploys the rest of the CCIP chain contracts to the selected chains -// registers the nodes with the capability registry and creates a DON for -// each new chain. TODO: Might be better to break this down a bit? -func DeployCCIPContracts( +// ConfigureChain assumes the all the Home chain contracts and CCIP contracts are deployed +// It does - +// 1. AddChainConfig for each chain in CCIPHome +// 2. Registers the nodes with the capability registry +// 3. SetOCR3Config on the remote chain +func ConfigureChain( e deployment.Environment, - ab deployment.AddressBook, - c DeployCCIPContractConfig) error { + c DeployCCIPContractConfig, +) error { if c.OCRSecrets.IsEmpty() { return fmt.Errorf("OCR secrets are empty") } @@ -331,52 +320,16 @@ func DeployCCIPContracts( return fmt.Errorf("rmn home not found") } - usdcConfiguration := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) - for _, chainSel := range c.ChainsToDeploy { - chain, exists := e.Chains[chainSel] - if !exists { - return fmt.Errorf("chain %d not found", chainSel) - } - if c.USDCConfig.Enabled { - token, pool, messenger, transmitter, err1 := DeployUSDC(e.Logger, chain, ab, existingState.Chains[chainSel]) - if err1 != nil { - return err1 - } - e.Logger.Infow("Deployed USDC contracts", - "chainSelector", chainSel, - "token", token.Address(), - "pool", pool.Address(), - "transmitter", transmitter.Address(), - "messenger", messenger.Address(), - ) - - usdcConfiguration[cciptypes.ChainSelector(chainSel)] = pluginconfig.USDCCCTPTokenConfig{ - SourcePoolAddress: pool.Address().Hex(), - SourceMessageTransmitterAddr: transmitter.Address().Hex(), - } - } - } - err = DeployChainContractsForChains(e, ab, c.HomeChainSel, c.ChainsToDeploy) - if err != nil { - e.Logger.Errorw("Failed to deploy chain contracts", "err", err) - return err - } for _, chainSel := range c.ChainsToDeploy { chain, _ := e.Chains[chainSel] - chainAddresses, err := ab.AddressesForChain(chain.Selector) - if err != nil { - e.Logger.Errorw("Failed to get chain addresses", "err", err) - return err + chainState, ok := existingState.Chains[chain.Selector] + if !ok { + return fmt.Errorf("chain state not found for chain %d", chain.Selector) } - chainState, err := LoadChainState(chain, chainAddresses) - if err != nil { - e.Logger.Errorw("Failed to load chain state", "err", err) - return err + if chainState.OffRamp == nil { + return fmt.Errorf("off ramp not found for chain %d", chain.Selector) } - tokenInfo := c.TokenConfig.GetTokenInfo(e.Logger, existingState.Chains[chainSel].LinkToken, existingState.Chains[chainSel].Weth9) - // TODO: Do we want to extract this? - // Add chain config for each chain. _, err = AddChainConfig( e.Logger, e.Chains[c.HomeChainSel], @@ -387,12 +340,12 @@ func DeployCCIPContracts( return err } var tokenDataObserversConf []pluginconfig.TokenDataObserverConfig - if c.USDCConfig.Enabled { + if enabled, ok := c.USDCConfig.EnabledChainMap()[chainSel]; ok && enabled { tokenDataObserversConf = []pluginconfig.TokenDataObserverConfig{{ Type: pluginconfig.USDCCCTPHandlerType, Version: "1.0", USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ - Tokens: usdcConfiguration, + Tokens: c.USDCConfig.CCTPTokenConfig, AttestationAPI: c.USDCConfig.API, AttestationAPITimeout: c.USDCConfig.APITimeout, AttestationAPIInterval: c.USDCConfig.APIInterval, @@ -422,6 +375,108 @@ func DeployCCIPContracts( return nil } +type USDCConfig struct { + EnabledChains []uint64 + USDCAttestationConfig + CCTPTokenConfig map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig +} + +func (cfg USDCConfig) EnabledChainMap() map[uint64]bool { + m := make(map[uint64]bool) + for _, chain := range cfg.EnabledChains { + m[chain] = true + } + return m +} + +type USDCAttestationConfig struct { + API string + APITimeout *commonconfig.Duration + APIInterval *commonconfig.Duration +} + +type DeployCCIPContractConfig struct { + HomeChainSel uint64 + FeedChainSel uint64 + ChainsToDeploy []uint64 + TokenConfig TokenConfig + USDCConfig USDCConfig + // For setting OCR configuration + OCRSecrets deployment.OCRSecrets +} + +func (c DeployCCIPContractConfig) Validate() error { + if err := deployment.IsValidChainSelector(c.HomeChainSel); err != nil { + return fmt.Errorf("invalid home chain selector: %d - %w", c.HomeChainSel, err) + } + if err := deployment.IsValidChainSelector(c.FeedChainSel); err != nil { + return fmt.Errorf("invalid feed chain selector: %d - %w", c.FeedChainSel, err) + } + mapChainsToDeploy := make(map[uint64]bool) + for _, cs := range c.ChainsToDeploy { + mapChainsToDeploy[cs] = true + if err := deployment.IsValidChainSelector(cs); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", cs, err) + } + } + for token := range c.TokenConfig.TokenSymbolToInfo { + if err := c.TokenConfig.TokenSymbolToInfo[token].Validate(); err != nil { + return fmt.Errorf("invalid token config for token %s: %w", token, err) + } + } + if c.OCRSecrets.IsEmpty() { + return fmt.Errorf("no OCR secrets provided") + } + usdcEnabledChainMap := c.USDCConfig.EnabledChainMap() + for chain := range usdcEnabledChainMap { + if _, exists := mapChainsToDeploy[chain]; !exists { + return fmt.Errorf("chain %d is not in chains to deploy", chain) + } + if err := deployment.IsValidChainSelector(chain); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", chain, err) + } + } + for chain := range c.USDCConfig.CCTPTokenConfig { + if _, exists := mapChainsToDeploy[uint64(chain)]; !exists { + return fmt.Errorf("chain %d is not in chains to deploy", chain) + } + if _, exists := usdcEnabledChainMap[uint64(chain)]; !exists { + return fmt.Errorf("chain %d is not enabled in USDC config", chain) + } + if err := deployment.IsValidChainSelector(uint64(chain)); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", chain, err) + } + } + return nil +} + +// DeployCCIPContracts assumes the following contracts are deployed: +// - Capability registry +// - CCIP home +// - RMN home +// - Fee tokens on all chains. +// and present in ExistingAddressBook. +// It then deploys the rest of the CCIP chain contracts to the selected chains +// registers the nodes with the capability registry and creates a DON for +// each new chain. +func DeployCCIPContracts( + e deployment.Environment, + ab deployment.AddressBook, + c DeployCCIPContractConfig) error { + err := DeployChainContractsForChains(e, ab, c.HomeChainSel, c.ChainsToDeploy) + if err != nil { + e.Logger.Errorw("Failed to deploy chain contracts", "err", err) + return err + } + err = ConfigureChain(e, c) + if err != nil { + e.Logger.Errorw("Failed to add chain", "err", err) + return err + } + + return nil +} + func DeployChainContractsForChains( e deployment.Environment, ab deployment.AddressBook, diff --git a/deployment/ccip/changeset/deploy_chain.go b/deployment/ccip/changeset/deploy_chain.go index cb60f1ddabd..c1ab11a994e 100644 --- a/deployment/ccip/changeset/deploy_chain.go +++ b/deployment/ccip/changeset/deploy_chain.go @@ -10,6 +10,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 := DeployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors) diff --git a/deployment/ccip/changeset/initial_add_chain.go b/deployment/ccip/changeset/initial_add_chain.go new file mode 100644 index 00000000000..e3f3b558784 --- /dev/null +++ b/deployment/ccip/changeset/initial_add_chain.go @@ -0,0 +1,32 @@ +package changeset + +import ( + "fmt" + + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + + "github.com/smartcontractkit/chainlink/deployment" +) + +var _ deployment.ChangeSet[DeployCCIPContractConfig] = 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 +// ConfigureChain assumes that the home chain is already enabled and all CCIP contracts are already deployed. +func InitialAddChain(env deployment.Environment, c DeployCCIPContractConfig) (deployment.ChangesetOutput, error) { + if err := c.Validate(); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("invalid InitialAddChainConfig: %w", err) + } + err := ConfigureChain(env, c) + if err != nil { + env.Logger.Errorw("Failed to configure chain", "err", err) + return deployment.ChangesetOutput{}, deployment.MaybeDataErr(err) + } + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{}, + AddressBook: nil, + JobSpecs: nil, + }, nil +} diff --git a/deployment/ccip/changeset/prerequisites.go b/deployment/ccip/changeset/prerequisites.go index 3136c5cc35e..b562f4d71a4 100644 --- a/deployment/ccip/changeset/prerequisites.go +++ b/deployment/ccip/changeset/prerequisites.go @@ -22,7 +22,7 @@ func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfi return deployment.ChangesetOutput{}, errors.Wrapf(deployment.ErrInvalidConfig, "%v", err) } ab := deployment.NewMemoryAddressBook() - err = DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors) + err = DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors, nil) if err != nil { env.Logger.Errorw("Failed to deploy prerequisite contracts", "err", err, "addressBook", ab) return deployment.ChangesetOutput{ diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index ffc7e9a1a1f..337bc1f261f 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -17,6 +17,7 @@ import ( "github.com/pkg/errors" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -247,7 +248,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, e.SetupJobs(t) // Take first non-home chain as the new chain. newAddresses := deployment.NewMemoryAddressBook() - err := DeployPrerequisiteChainContracts(e.Env, newAddresses, e.Env.AllChainSelectors()) + err := DeployPrerequisiteChainContracts(e.Env, newAddresses, e.Env.AllChainSelectors(), nil) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) diff --git a/deployment/ccip/changeset/test_usdc_helpers.go b/deployment/ccip/changeset/test_usdc_helpers.go index 88e9c07f06a..4a39f4e7ba1 100644 --- a/deployment/ccip/changeset/test_usdc_helpers.go +++ b/deployment/ccip/changeset/test_usdc_helpers.go @@ -7,6 +7,7 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/reader" "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/mock_usdc_token_messenger" @@ -119,7 +120,8 @@ func DeployUSDC( lggr logger.Logger, chain deployment.Chain, addresses deployment.AddressBook, - state CCIPChainState, + rmnProxy common.Address, + router common.Address, ) ( *burn_mint_erc677.BurnMintERC677, *usdc_token_pool.USDCTokenPool, @@ -214,8 +216,8 @@ func DeployUSDC( messenger.Address, token.Address, []common.Address{}, - state.RMNProxyExisting.Address(), - state.Router.Address(), + rmnProxy, + router, ) return deployment.ContractDeploy[*usdc_token_pool.USDCTokenPool]{ Address: tokenPoolAddress, From 374c0d5b1565f23ac381369186e7d1850b34635e Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 11:50:12 -0800 Subject: [PATCH 13/27] changes --- deployment/ccip/changeset/jobspec.go | 4 +++- deployment/ccip/changeset/jobspec_test.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deployment/ccip/changeset/jobspec.go b/deployment/ccip/changeset/jobspec.go index bd968c97e1e..edee1d150b9 100644 --- a/deployment/ccip/changeset/jobspec.go +++ b/deployment/ccip/changeset/jobspec.go @@ -7,7 +7,9 @@ import ( "github.com/smartcontractkit/chainlink/deployment" ) -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 := NewCCIPJobSpecs(env.NodeIDs, env.Offchain) if err != nil { return deployment.ChangesetOutput{}, errors.Wrapf(err, "failed to create job specs") diff --git a/deployment/ccip/changeset/jobspec_test.go b/deployment/ccip/changeset/jobspec_test.go index 4a10bdc2436..21e80e85aa2 100644 --- a/deployment/ccip/changeset/jobspec_test.go +++ b/deployment/ccip/changeset/jobspec_test.go @@ -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) From 7fba91dc495638c8e62c7fce490622292f3c36fe Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 13:11:22 -0800 Subject: [PATCH 14/27] changes --- .../ccip/changeset/active_candidate_test.go | 21 +- deployment/ccip/changeset/add_chain_test.go | 5 +- deployment/ccip/changeset/prerequisites.go | 17 +- deployment/ccip/changeset/save_existing.go | 2 + deployment/ccip/changeset/state.go | 15 +- deployment/ccip/changeset/test_helpers.go | 98 ++++++--- deployment/common/changeset/apply.go | 86 ++++++++ .../common/changeset/mcms_test_helpers.go | 65 ++++-- deployment/environment.go | 11 ++ .../ccip-tests/testsetups/test_helpers.go | 186 +++++++++++------- .../smoke/ccip_messaging_test.go | 3 +- integration-tests/smoke/ccip_test.go | 5 +- integration-tests/smoke/ccip_usdc_test.go | 3 +- integration-tests/smoke/fee_boosting_test.go | 5 +- 14 files changed, 373 insertions(+), 149 deletions(-) create mode 100644 deployment/common/changeset/apply.go diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index 7e0b90fecbe..ba764cd0713 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -8,6 +8,7 @@ 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" @@ -78,9 +79,10 @@ func TestActiveCandidate(t *testing.T) { TransferAllOwnership(t, state, tenv.HomeChainSel, e) acceptOwnershipProposal, err := 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) + require.NoError(t, commonchangeset.ExecuteProposal(e, acceptOwnershipExec, state.Chains[sel].Timelock, sel)) } // Apply the accept ownership proposal to all the chains. @@ -142,8 +144,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 := SetCandidateOnExistingDon( @@ -160,8 +163,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) @@ -187,8 +191,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 diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index eedb5b0f21a..2b6b79dde55 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -138,10 +138,11 @@ func TestAddChainInbound(t *testing.T) { acceptOwnershipProposal, err := 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) diff --git a/deployment/ccip/changeset/prerequisites.go b/deployment/ccip/changeset/prerequisites.go index b562f4d71a4..dac00b4535d 100644 --- a/deployment/ccip/changeset/prerequisites.go +++ b/deployment/ccip/changeset/prerequisites.go @@ -16,13 +16,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 = DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors, nil) + err = 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{ @@ -37,14 +39,25 @@ 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[TokenSymbol]common.Address Feeds map[TokenSymbol]common.Address } func (c DeployPrerequisiteConfig) Validate() error { + mapAllChainSelectors := make(map[uint64]struct{}) for _, cs := range c.ChainSelectors { + mapAllChainSelectors[cs] = struct{}{} + if err := deployment.IsValidChainSelector(cs); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", cs, err) + } + } + for _, cs := range c.USDCEnabledChainSelectors { + if _, ok := mapAllChainSelectors[cs]; !ok { + return fmt.Errorf("chain selector %d is not present in ChainSelectors", cs) + } if err := deployment.IsValidChainSelector(cs); err != nil { return fmt.Errorf("invalid chain selector: %d - %w", cs, err) } diff --git a/deployment/ccip/changeset/save_existing.go b/deployment/ccip/changeset/save_existing.go index 76330a3a20a..a5177c8e49b 100644 --- a/deployment/ccip/changeset/save_existing.go +++ b/deployment/ccip/changeset/save_existing.go @@ -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 { diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index a8b3fb04c96..0e1c76221fc 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -48,10 +48,17 @@ import ( // on a chain. If a binding is nil, it means here is no such contract on the chain. type CCIPChainState struct { commoncs.MCMSWithTimelockState - OnRamp *onramp.OnRamp - OffRamp *offramp.OffRamp - FeeQuoter *fee_quoter.FeeQuoter - RMNProxyNew *rmn_proxy_contract.RMNProxyContract + OnRamp *onramp.OnRamp + OffRamp *offramp.OffRamp + FeeQuoter *fee_quoter.FeeQuoter + // We need 2 RMNProxy contracts because we are in the process of migrating to a new version. + // We will switch to the existing one once the migration is complete. + // This is the new RMNProxy contract that will be used for testing RMNRemote before migration. + // Initially RMNProxyNew will point to RMNRemote + RMNProxyNew *rmn_proxy_contract.RMNProxyContract + // Existing RMNProxy contract that is used in production, This already has existing 1.5 RMN set. + // once RMNRemote is tested with RMNProxyNew, as part of migration + // RMNProxyExisting will point to RMNRemote. This will switch over CCIP 1.5 to 1.6 RMNProxyExisting *rmn_proxy_contract.RMNProxyContract NonceManager *nonce_manager.NonceManager TokenAdminRegistry *token_admin_registry.TokenAdminRegistry diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 337bc1f261f..1123551d4df 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -15,7 +15,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" - + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" @@ -244,14 +245,10 @@ func mockAttestationResponse() *httptest.Server { } func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, numChains int, numNodes int) DeployedEnv { + var err error e := NewMemoryEnvironment(t, lggr, numChains, numNodes, MockLinkPrice, MockWethPrice) e.SetupJobs(t) - // Take first non-home chain as the new chain. - newAddresses := deployment.NewMemoryAddressBook() - err := DeployPrerequisiteChainContracts(e.Env, newAddresses, e.Env.AllChainSelectors(), nil) - require.NoError(t, err) - require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - + allChains := e.Env.AllChainSelectors() cfg := commontypes.MCMSWithTimelockConfig{ Canceller: commonchangeset.SingleGroupMCMS(t), Bypasser: commonchangeset.SingleGroupMCMS(t), @@ -263,37 +260,76 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, for _, c := range e.Env.AllChainSelectors() { mcmsCfg[c] = cfg } - out, err := commonchangeset.DeployMCMSWithTimelock(e.Env, mcmsCfg) + // Need to deploy prerequisites first so that we can for the CCIP contracts. + cs01 := []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(DeployPrerequisites), + Config: DeployPrerequisiteConfig{ + ChainSelectors: allChains, + USDCEnabledChainSelectors: allChains, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), + Config: mcmsCfg, + }, + } + // no proposals to be made, timelock can be passed as nil here + e.Env, err = commonchangeset.ApplyChangesets(context.Background(), e.Env, nil, cs01) require.NoError(t, err) - require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) + state, err := LoadOnchainState(e.Env) require.NoError(t, err) - - newAddresses = deployment.NewMemoryAddressBook() tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + USDCCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) + timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) + for _, chain := range allChains { + require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) + require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) + require.NotNil(t, state.Chains[chain].USDCTokenPool) + USDCCCTPConfig[cciptypes.ChainSelector(chain)] = pluginconfig.USDCCCTPTokenConfig{ + SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), + SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), + } + timelocksPerChain[chain] = state.Chains[chain].Timelock + } + server := mockAttestationResponse() defer server.Close() endpoint := server.URL - err = DeployCCIPContracts(e.Env, newAddresses, DeployCCIPContractConfig{ - HomeChainSel: e.HomeChainSel, - FeedChainSel: e.FeedChainSel, - ChainsToDeploy: e.Env.AllChainSelectors(), - TokenConfig: tokenConfig, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - USDCConfig: USDCConfig{ - Enabled: true, - USDCAttestationConfig: USDCAttestationConfig{ - API: endpoint, - APITimeout: commonconfig.MustNewDuration(time.Second), - APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + + // Deploy second set of changesets to deploy and configure the CCIP contracts. + cs02 := []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), + Config: DeployChainContractsConfig{ + ChainSelectors: allChains, + HomeChainSelector: e.HomeChainSel, }, }, - }) - require.NoError(t, err) - require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - state, err = LoadOnchainState(e.Env) - require.NoError(t, err) + { + Changeset: commonchangeset.WrapChangeSet(InitialAddChain), + Config: DeployCCIPContractConfig{ + HomeChainSel: e.HomeChainSel, + FeedChainSel: e.FeedChainSel, + ChainsToDeploy: e.Env.AllChainSelectors(), + TokenConfig: tokenConfig, + OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + USDCConfig: USDCConfig{ + EnabledChains: allChains, + USDCAttestationConfig: USDCAttestationConfig{ + API: endpoint, + APITimeout: commonconfig.MustNewDuration(time.Second), + APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + }, + CCTPTokenConfig: USDCCCTPConfig, + }, + }, + }, + } + e.Env, err = commonchangeset.ApplyChangesets(context.Background(), e.Env, timelocksPerChain, cs02) + require.NoError(t, err) return e } @@ -572,6 +608,7 @@ func ConfirmRequestOnSourceAndDest(t *testing.T, env deployment.Environment, sta return nil } +// TODO: Remove this to replace with ApplyChangeset func ProcessChangeset(t *testing.T, e deployment.Environment, c deployment.ChangesetOutput) { // TODO: Add support for jobspecs as well @@ -586,9 +623,10 @@ func ProcessChangeset(t *testing.T, e deployment.Environment, c deployment.Chang chains.Add(uint64(op.ChainIdentifier)) } - signed := commonchangeset.SignProposal(t, e, &prop) + signed, err := commonchangeset.SignProposal(e, &prop) + require.NoError(t, err) for _, sel := range chains.ToSlice() { - commonchangeset.ExecuteProposal(t, e, signed, state.Chains[sel].Timelock, sel) + require.NoError(t, commonchangeset.ExecuteProposal(e, signed, state.Chains[sel].Timelock, sel)) } } } diff --git a/deployment/common/changeset/apply.go b/deployment/common/changeset/apply.go new file mode 100644 index 00000000000..1c712eb1dd2 --- /dev/null +++ b/deployment/common/changeset/apply.go @@ -0,0 +1,86 @@ +package changeset + +import ( + "context" + "fmt" + + mapset "github.com/deckarep/golang-set/v2" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" + + "github.com/smartcontractkit/chainlink/deployment" +) + +type ChangesetApplication struct { + Changeset func(e deployment.Environment, config any) (deployment.ChangesetOutput, error) + Config any +} + +func WrapChangeSet[C any](fn deployment.ChangeSet[C]) func(e deployment.Environment, config any) (deployment.ChangesetOutput, error) { + return func(e deployment.Environment, config any) (deployment.ChangesetOutput, error) { + c, ok := config.(C) + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("invalid config type, expected %T", c) + } + return fn(e, c) + } +} + +// ApplyChangesets applies the changeset applications to the environment and returns the updated environment. +func ApplyChangesets(ctx context.Context, e deployment.Environment, timelocksPerChain map[uint64]*gethwrappers.RBACTimelock, changesetApplications []ChangesetApplication) (deployment.Environment, error) { + currentEnv, err := e.Copy() + if err != nil { + return e, fmt.Errorf("failed to copy environment: %w", err) + } + for i, csa := range changesetApplications { + out, err := csa.Changeset(currentEnv, csa.Config) + if err != nil { + return e, fmt.Errorf("failed to apply changeset at index %d: %w", i, err) + } + if out.AddressBook != nil { + err := currentEnv.ExistingAddresses.Merge(out.AddressBook) + if err != nil { + return e, fmt.Errorf("failed to merge address book: %w", err) + } + } + if out.JobSpecs != nil { + for nodeID, jobs := range out.JobSpecs { + for _, job := range jobs { + // Note these auto-accept + _, err := e.Offchain.ProposeJob(ctx, + &jobv1.ProposeJobRequest{ + NodeId: nodeID, + Spec: job, + }) + if err != nil { + return e, fmt.Errorf("failed to propose job: %w", err) + } + } + } + } + if out.Proposals != nil { + for _, prop := range out.Proposals { + chains := mapset.NewSet[uint64]() + for _, op := range prop.Transactions { + chains.Add(uint64(op.ChainIdentifier)) + } + + signed, err := SignProposal(e, &prop) + if err != nil { + return deployment.Environment{}, fmt.Errorf("failed to sign proposal: %w", err) + } + for _, sel := range chains.ToSlice() { + timelock, ok := timelocksPerChain[sel] + if !ok || timelock == nil { + return deployment.Environment{}, fmt.Errorf("timelock not found for chain %d", sel) + } + err := ExecuteProposal(e, signed, timelock, sel) + if err != nil { + return deployment.Environment{}, fmt.Errorf("failed to execute proposal: %w", err) + } + } + } + } + } + return currentEnv, nil +} diff --git a/deployment/common/changeset/mcms_test_helpers.go b/deployment/common/changeset/mcms_test_helpers.go index 3951149815c..ac0699570d2 100644 --- a/deployment/common/changeset/mcms_test_helpers.go +++ b/deployment/common/changeset/mcms_test_helpers.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "crypto/ecdsa" + "fmt" "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -42,38 +43,51 @@ func SingleGroupMCMS(t *testing.T) config.Config { return *c } -func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.MCMSWithTimelockProposal) *mcms.Executor { +func SignProposal(env deployment.Environment, proposal *timelock.MCMSWithTimelockProposal) (*mcms.Executor, error) { executorClients := make(map[mcms.ChainIdentifier]mcms.ContractDeployBackend) for _, chain := range env.Chains { chainselc, exists := chainsel.ChainBySelector(chain.Selector) - require.True(t, exists) + if !exists { + return nil, fmt.Errorf("failed to find chain by selector: %d", chain.Selector) + } chainSel := mcms.ChainIdentifier(chainselc.Selector) executorClients[chainSel] = chain.Client } executor, err := proposal.ToExecutor(true) - require.NoError(t, err) + if err != nil { + return nil, fmt.Errorf("failed to convert proposal to executor: %w", err) + } payload, err := executor.SigningHash() - require.NoError(t, err) + if err != nil { + return nil, fmt.Errorf("failed to get signing hash: %w", err) + } // Sign the payload sig, err := crypto.Sign(payload.Bytes(), TestXXXMCMSSigner) - require.NoError(t, err) + if err != nil { + return nil, fmt.Errorf("failed to sign payload: %w", err) + } mcmSig, err := mcms.NewSignatureFromBytes(sig) - require.NoError(t, err) + if err != nil { + return nil, fmt.Errorf("failed to create signature from bytes: %w", err) + } executor.Proposal.AddSignature(mcmSig) - require.NoError(t, executor.Proposal.Validate()) - return executor + if err := executor.Proposal.Validate(); err != nil { + return nil, fmt.Errorf("failed to validate proposal: %w", err) + } + return executor, nil } -func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Executor, - timelock *owner_helpers.RBACTimelock, sel uint64) { - t.Log("Executing proposal on chain", sel) +func ExecuteProposal(env deployment.Environment, executor *mcms.Executor, timelock *owner_helpers.RBACTimelock, sel uint64) error { + env.Logger.Infow("Executing proposal on chain", "selector", sel) // Set the root. tx, err2 := executor.SetRootOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, mcms.ChainIdentifier(sel)) if err2 != nil { - require.NoError(t, deployment.MaybeDataErr(err2)) + return fmt.Errorf("failed to set root: %w", deployment.MaybeDataErr(err2)) } _, err2 = env.Chains[sel].Confirm(tx) - require.NoError(t, err2) + if err2 != nil { + return fmt.Errorf("failed to confirm set-root: %w", err2) + } // TODO: This sort of helper probably should move to the MCMS lib. // Execute all the transactions in the proposal which are for this chain. @@ -81,23 +95,29 @@ func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Ex for idx, op := range executor.ChainAgnosticOps { if bytes.Equal(op.Data, chainOp.Data) && op.To == chainOp.To { opTx, err3 := executor.ExecuteOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, idx) - require.NoError(t, err3) + if err3 != nil { + return fmt.Errorf("failed to execute operation: %w", deployment.MaybeDataErr(err3)) + } block, err3 := env.Chains[sel].Confirm(opTx) - require.NoError(t, err3) - t.Log("executed", chainOp) + if err3 != nil { + return fmt.Errorf("failed to confirm operation ExecuteOnChain: %w", err3) + } + env.Logger.Infow("executed", "chainOp", chainOp) it, err3 := timelock.FilterCallScheduled(&bind.FilterOpts{ Start: block, End: &block, Context: context.Background(), }, nil, nil) - require.NoError(t, err3) + if err3 != nil { + return fmt.Errorf("failed to filter call scheduled: %w", err3) + } var calls []owner_helpers.RBACTimelockCall var pred, salt [32]byte for it.Next() { // Note these are the same for the whole batch, can overwrite pred = it.Event.Predecessor salt = it.Event.Salt - t.Log("scheduled", it.Event) + env.Logger.Infow("scheduled", "Event", it.Event) calls = append(calls, owner_helpers.RBACTimelockCall{ Target: it.Event.Target, Data: it.Event.Data, @@ -106,10 +126,15 @@ func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Ex } tx, err := timelock.ExecuteBatch( env.Chains[sel].DeployerKey, calls, pred, salt) - require.NoError(t, err) + if err != nil { + return fmt.Errorf("failed to execute batch: %w", deployment.MaybeDataErr(err)) + } _, err = env.Chains[sel].Confirm(tx) - require.NoError(t, err) + if err != nil { + return fmt.Errorf("failed to confirm execute batch: %w", err) + } } } } + return nil } diff --git a/deployment/environment.go b/deployment/environment.go index 2fd1876afd8..bda3a5331fc 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -77,6 +77,17 @@ type Environment struct { Offchain OffchainClient } +func (e Environment) Copy() (Environment, error) { + newEnv := e + addr := NewMemoryAddressBook() + err := addr.Merge(e.ExistingAddresses) + if err != nil { + return Environment{}, err + } + newEnv.ExistingAddresses = addr + return newEnv, nil +} + func NewEnvironment( name string, logger logger.Logger, diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index 4700c6fd14f..4d6741d6af1 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -8,10 +8,12 @@ import ( "testing" "time" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" chainsel "github.com/smartcontractkit/chain-selectors" + cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" @@ -21,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink-testing-framework/seth" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" @@ -31,7 +34,6 @@ import ( ccipactions "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - "github.com/smartcontractkit/chainlink/integration-tests/testconfig" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/integration-tests/utils" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -74,16 +76,16 @@ func (d DeployedLocalDevEnvironment) RestartChainlinkNodes(t *testing.T) error { return errGrp.Wait() } -func NewLocalDevEnvironmentWithDefaultPrice( - t *testing.T, - lggr logger.Logger) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, testconfig.TestConfig) { - return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice) +func NewLocalDevEnvironmentWithDefaultPrice(t *testing.T, lggr logger.Logger, isUSDC bool) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { + return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice, false) } func NewLocalDevEnvironment( t *testing.T, lggr logger.Logger, - linkPrice, wethPrice *big.Int) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, testconfig.TestConfig) { + linkPrice, wethPrice *big.Int, + isUSDC bool, +) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { ctx := testcontext.Get(t) // create a local docker environment with simulated chains and job-distributor // we cannot create the chainlink nodes yet as we need to deploy the capability registry first @@ -112,90 +114,124 @@ func NewLocalDevEnvironment( e, don, err := devenv.NewEnvironment(ctx, lggr, *envConfig) require.NoError(t, err) require.NotNil(t, e) - e.ExistingAddresses = ab - - envNodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) - require.NoError(t, err) - out, err := changeset.DeployHomeChain(*e, - changeset.DeployHomeChainConfig{ - HomeChainSel: homeChainSel, - RMNStaticConfig: changeset.NewTestRMNStaticConfig(), - RMNDynamicConfig: changeset.NewTestRMNDynamicConfig(), - NodeOperators: changeset.NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), - NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ - "NodeOperator": envNodes.NonBootstraps().PeerIDs(), - }, - }, - ) - require.NoError(t, err) - require.NoError(t, e.ExistingAddresses.Merge(out.AddressBook)) - zeroLogLggr := logging.GetTestLogger(t) // fund the nodes + zeroLogLggr := logging.GetTestLogger(t) FundNodes(t, zeroLogLggr, testEnv, cfg, don.PluginNodes()) - output, err := changeset.DeployPrerequisites(*e, changeset.DeployPrerequisiteConfig{ - ChainSelectors: e.AllChainSelectors(), - }) + env := *e + + envNodes, err := deployment.NodeInfo(env.NodeIDs, env.Offchain) require.NoError(t, err) - require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) + allChains := env.AllChainSelectors() + var usdcChains []uint64 + if isUSDC { + usdcChains = allChains + } + mcmsCfgPerChain := commontypes.MCMSWithTimelockConfig{ + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockExecutors: env.AllDeployerKeys(), + TimelockMinDelay: big.NewInt(0), + } mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) - for _, chain := range e.AllChainSelectors() { - mcmsCfg[chain] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } + for _, c := range env.AllChainSelectors() { + mcmsCfg[c] = mcmsCfgPerChain } - output, err = commonchangeset.DeployMCMSWithTimelock(*e, mcmsCfg) - require.NoError(t, err) - require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) - - state, err := changeset.LoadOnchainState(*e) + // Need to deploy prerequisites first so that we can for the CCIP contracts. + cs01 := []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployHomeChain), + Config: changeset.DeployHomeChainConfig{ + HomeChainSel: homeChainSel, + RMNStaticConfig: changeset.NewTestRMNStaticConfig(), + RMNDynamicConfig: changeset.NewTestRMNDynamicConfig(), + NodeOperators: changeset.NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), + NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ + "NodeOperator": envNodes.NonBootstraps().PeerIDs(), + }, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployPrerequisites), + Config: changeset.DeployPrerequisiteConfig{ + ChainSelectors: allChains, + USDCEnabledChainSelectors: usdcChains, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), + Config: mcmsCfg, + }, + } + ctx = testcontext.Get(t) + // no proposals to be made, timelock can be passed as nil here + env, err = commonchangeset.ApplyChangesets(ctx, env, nil, cs01) require.NoError(t, err) - var endpoint string - err = ccipactions.SetMockServerWithUSDCAttestation(testEnv.MockAdapter, nil) + state, err := changeset.LoadOnchainState(env) require.NoError(t, err) - endpoint = testEnv.MockAdapter.InternalEndpoint - tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) - // Apply migration - output, err = changeset.InitialDeploy(*e, changeset.DeployCCIPContractConfig{ - HomeChainSel: homeChainSel, - FeedChainSel: feedSel, - ChainsToDeploy: e.AllChainSelectors(), - TokenConfig: tokenConfig, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - USDCConfig: changeset.USDCConfig{ - Enabled: true, - USDCAttestationConfig: changeset.USDCAttestationConfig{ - API: endpoint, - APITimeout: commonconfig.MustNewDuration(time.Second), - APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + USDCCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) + timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) + for _, chain := range usdcChains { + require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) + require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) + require.NotNil(t, state.Chains[chain].USDCTokenPool) + USDCCCTPConfig[cciptypes.ChainSelector(chain)] = pluginconfig.USDCCCTPTokenConfig{ + SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), + SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), + } + timelocksPerChain[chain] = state.Chains[chain].Timelock + } + var usdcAttestationCfg changeset.USDCAttestationConfig + if len(usdcChains) > 0 { + var endpoint string + err = ccipactions.SetMockServerWithUSDCAttestation(testEnv.MockAdapter, nil) + require.NoError(t, err) + endpoint = testEnv.MockAdapter.InternalEndpoint + usdcAttestationCfg = changeset.USDCAttestationConfig{ + API: endpoint, + APITimeout: commonconfig.MustNewDuration(time.Second), + APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + } + } + + // Deploy second set of changesets to deploy and configure the CCIP contracts. + cs02 := []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContracts), + Config: changeset.DeployChainContractsConfig{ + ChainSelectors: allChains, + HomeChainSelector: homeChainSel, }, }, - }) + { + Changeset: commonchangeset.WrapChangeSet(changeset.CCIPCapabilityJobspec), + }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.InitialAddChain), + Config: changeset.DeployCCIPContractConfig{ + HomeChainSel: homeChainSel, + FeedChainSel: feedSel, + ChainsToDeploy: allChains, + TokenConfig: tokenConfig, + OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + USDCConfig: changeset.USDCConfig{ + EnabledChains: usdcChains, + USDCAttestationConfig: usdcAttestationCfg, + CCTPTokenConfig: USDCCCTPConfig, + }, + }, + }, + } + + env, err = commonchangeset.ApplyChangesets(ctx, env, timelocksPerChain, cs02) require.NoError(t, err) - require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) // Ensure capreg logs are up to date. changeset.ReplayLogs(t, e.Offchain, 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) - } - } - return changeset.DeployedEnv{ Env: *e, HomeChainSel: homeChainSel, @@ -209,7 +245,7 @@ func NewLocalDevEnvironmentWithRMN( lggr logger.Logger, numRmnNodes int, ) (changeset.DeployedEnv, devenv.RMNCluster) { - tenv, dockerenv, testCfg := NewLocalDevEnvironmentWithDefaultPrice(t, lggr) + tenv, dockerenv, testCfg := NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) l := logging.GetTestLogger(t) config := GenerateTestRMNConfig(t, numRmnNodes, tenv, MustNetworksToRPCMap(dockerenv.EVMNetworks)) require.NotNil(t, testCfg.CCIP) diff --git a/integration-tests/smoke/ccip_messaging_test.go b/integration-tests/smoke/ccip_messaging_test.go index 654946d620a..32d68577b72 100644 --- a/integration-tests/smoke/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip_messaging_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/hashutil" "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" @@ -48,7 +49,7 @@ func Test_CCIPMessaging(t *testing.T) { // Setup 2 chains and a single lane. lggr := logger.TestLogger(t) ctx := changeset.Context(t) - e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) + e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip_test.go b/integration-tests/smoke/ccip_test.go index 7996a4ccf0a..cccfcc20dc8 100644 --- a/integration-tests/smoke/ccip_test.go +++ b/integration-tests/smoke/ccip_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -17,7 +18,7 @@ import ( func TestInitialDeployOnLocal(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) + tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) e := tenv.Env state, err := changeset.LoadOnchainState(e) require.NoError(t, err) @@ -72,7 +73,7 @@ func TestInitialDeployOnLocal(t *testing.T) { func TestTokenTransfer(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) + tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) e := tenv.Env state, err := changeset.LoadOnchainState(e) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip_usdc_test.go b/integration-tests/smoke/ccip_usdc_test.go index aef2c916842..880e9fa8ea7 100644 --- a/integration-tests/smoke/ccip_usdc_test.go +++ b/integration-tests/smoke/ccip_usdc_test.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups" @@ -25,7 +26,7 @@ import ( func TestUSDCTokenTransfer(t *testing.T) { lggr := logger.TestLogger(t) - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr) + tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, true) e := tenv.Env state, err := changeset.LoadOnchainState(e) diff --git a/integration-tests/smoke/fee_boosting_test.go b/integration-tests/smoke/fee_boosting_test.go index 087715a80a2..363ab445f50 100644 --- a/integration-tests/smoke/fee_boosting_test.go +++ b/integration-tests/smoke/fee_boosting_test.go @@ -34,10 +34,7 @@ type priceFeedPrices struct { // TODO: find a way to reuse the same test setup for all tests func Test_CCIPFeeBoosting(t *testing.T) { setupTestEnv := func(t *testing.T, numChains int) (changeset.DeployedEnv, changeset.CCIPOnChainState, []uint64) { - e, _, _ := testsetups.NewLocalDevEnvironment( - t, logger.TestLogger(t), - deployment.E18Mult(5), - big.NewInt(9e8)) + e, _, _ := testsetups.NewLocalDevEnvironment(t, logger.TestLogger(t), deployment.E18Mult(5), big.NewInt(9e8), false) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) From b53d58a61969c7b764d90fa63e30d48f2f87de01 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 14:58:42 -0800 Subject: [PATCH 15/27] more changes --- .../ccip/changeset/active_candidate_test.go | 2 +- deployment/ccip/changeset/add_lane_test.go | 3 +- deployment/ccip/changeset/deploy.go | 10 +++- deployment/ccip/changeset/deploy_test.go | 5 +- deployment/ccip/changeset/initial_deploy.go | 28 --------- .../ccip/changeset/initial_deploy_test.go | 60 +------------------ deployment/ccip/changeset/jobspec.go | 4 +- deployment/ccip/changeset/test_helpers.go | 60 ++++++++++++++----- deployment/common/changeset/apply.go | 15 +++-- 9 files changed, 71 insertions(+), 116 deletions(-) delete mode 100644 deployment/ccip/changeset/initial_deploy.go diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index ba764cd0713..5fbbc08329b 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -26,7 +26,7 @@ func TestActiveCandidate(t *testing.T) { t.Skipf("to be enabled after latest cl-ccip is compatible") lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5) + tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5, false) e := tenv.Env state, err := LoadOnchainState(tenv.Env) require.NoError(t, err) diff --git a/deployment/ccip/changeset/add_lane_test.go b/deployment/ccip/changeset/add_lane_test.go index 4ad6f992bbd..ec79224d408 100644 --- a/deployment/ccip/changeset/add_lane_test.go +++ b/deployment/ccip/changeset/add_lane_test.go @@ -9,6 +9,7 @@ import ( commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -20,7 +21,7 @@ import ( func TestAddLane(t *testing.T) { t.Parallel() // We add more chains to the chainlink nodes than the number of chains where CCIP is deployed. - e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4) + e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4, false) // Here we have CR + nodes set up, but no CCIP contracts deployed. state, err := LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 5fbd91006f6..205c58711c0 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -12,7 +12,6 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" @@ -469,6 +468,11 @@ func DeployCCIPContracts( e.Logger.Errorw("Failed to deploy chain contracts", "err", err) return err } + err = e.ExistingAddresses.Merge(ab) + if err != nil { + e.Logger.Errorw("Failed to merge address book", "err", err) + return err + } err = ConfigureChain(e, c) if err != nil { e.Logger.Errorw("Failed to add chain", "err", err) @@ -501,7 +505,9 @@ func DeployChainContractsForChains( return err } if cr != internal.CCIPCapabilityID { - return fmt.Errorf("capability registry does not support CCIP %s %s", hexutil.Encode(cr[:]), hexutil.Encode(internal.CCIPCapabilityID[:])) + return fmt.Errorf("unexpected mismatch between calculated ccip capability id (%s) and expected ccip capability id constant (%s)", + hexutil.Encode(cr[:]), + hexutil.Encode(internal.CCIPCapabilityID[:])) } capability, err := capReg.GetCapability(nil, internal.CCIPCapabilityID) if err != nil { diff --git a/deployment/ccip/changeset/deploy_test.go b/deployment/ccip/changeset/deploy_test.go index 5054ac2dba5..0e30eb6c73d 100644 --- a/deployment/ccip/changeset/deploy_test.go +++ b/deployment/ccip/changeset/deploy_test.go @@ -12,10 +12,7 @@ import ( func TestDeployCCIPContracts(t *testing.T) { lggr := logger.TestLogger(t) - e := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, - 2, - 4, - ) + e := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, false) // Deploy all the CCIP contracts. state, err := LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/deployment/ccip/changeset/initial_deploy.go b/deployment/ccip/changeset/initial_deploy.go deleted file mode 100644 index 29cfde18ec2..00000000000 --- a/deployment/ccip/changeset/initial_deploy.go +++ /dev/null @@ -1,28 +0,0 @@ -package changeset - -import ( - "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" - - "github.com/smartcontractkit/chainlink/deployment" -) - -var _ deployment.ChangeSet[DeployCCIPContractConfig] = InitialDeploy - -func InitialDeploy(env deployment.Environment, c DeployCCIPContractConfig) (deployment.ChangesetOutput, error) { - newAddresses := deployment.NewMemoryAddressBook() - err := DeployCCIPContracts(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) - } - js, err := NewCCIPJobSpecs(env.NodeIDs, env.Offchain) - if err != nil { - return deployment.ChangesetOutput{AddressBook: newAddresses}, err - } - return deployment.ChangesetOutput{ - Proposals: []timelock.MCMSWithTimelockProposal{}, - AddressBook: newAddresses, - // Mapping of which nodes get which jobs. - JobSpecs: js, - }, nil -} diff --git a/deployment/ccip/changeset/initial_deploy_test.go b/deployment/ccip/changeset/initial_deploy_test.go index 14ce267d646..c0eaaa70e85 100644 --- a/deployment/ccip/changeset/initial_deploy_test.go +++ b/deployment/ccip/changeset/initial_deploy_test.go @@ -1,17 +1,11 @@ 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-testing-framework/lib/utils/testcontext" - "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -21,61 +15,11 @@ import ( func TestInitialDeploy(t *testing.T) { lggr := logger.TestLogger(t) - ctx := Context(t) - tenv := NewMemoryEnvironment(t, lggr, 3, 4, MockLinkPrice, MockWethPrice) + tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 4, false) e := tenv.Env - state, err := LoadOnchainState(tenv.Env) - require.NoError(t, err) - output, err := DeployPrerequisites(e, DeployPrerequisiteConfig{ - ChainSelectors: tenv.Env.AllChainSelectors(), - }) - require.NoError(t, err) - require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook)) - - cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) - 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, DeployCCIPContractConfig{ - HomeChainSel: tenv.HomeChainSel, - FeedChainSel: tenv.FeedChainSel, - ChainsToDeploy: tenv.Env.AllChainSelectors(), - TokenConfig: NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds), - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - }) - require.NoError(t, err) - // Get new state after migration. - require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook)) - state, err = LoadOnchainState(e) + state, err := LoadOnchainState(e) require.NoError(t, err) - require.NotNil(t, state.Chains[tenv.HomeChainSel].LinkToken) - // Ensure capreg logs are up to date. - 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, AddLanesForAll(e, state)) // Need to keep track of the block number for each chain so that event subscription can be done from that block. diff --git a/deployment/ccip/changeset/jobspec.go b/deployment/ccip/changeset/jobspec.go index edee1d150b9..04b658202ea 100644 --- a/deployment/ccip/changeset/jobspec.go +++ b/deployment/ccip/changeset/jobspec.go @@ -7,6 +7,8 @@ import ( "github.com/smartcontractkit/chainlink/deployment" ) +var _ deployment.ChangeSet[any] = CCIPCapabilityJobspec + // 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) { @@ -16,7 +18,7 @@ func CCIPCapabilityJobspec(env deployment.Environment, _ any) (deployment.Change } return deployment.ChangesetOutput{ Proposals: []timelock.MCMSWithTimelockProposal{}, - AddressBook: deployment.NewMemoryAddressBook(), + AddressBook: nil, JobSpecs: js, }, nil } diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 1123551d4df..9b45dcba965 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -244,10 +244,9 @@ func mockAttestationResponse() *httptest.Server { return server } -func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, numChains int, numNodes int) DeployedEnv { +func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, numChains int, numNodes int, isUSDC bool) DeployedEnv { var err error e := NewMemoryEnvironment(t, lggr, numChains, numNodes, MockLinkPrice, MockWethPrice) - e.SetupJobs(t) allChains := e.Env.AllChainSelectors() cfg := commontypes.MCMSWithTimelockConfig{ Canceller: commonchangeset.SingleGroupMCMS(t), @@ -260,13 +259,17 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, for _, c := range e.Env.AllChainSelectors() { mcmsCfg[c] = cfg } + var usdcChains []uint64 + if isUSDC { + usdcChains = allChains + } // Need to deploy prerequisites first so that we can for the CCIP contracts. cs01 := []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(DeployPrerequisites), Config: DeployPrerequisiteConfig{ ChainSelectors: allChains, - USDCEnabledChainSelectors: allChains, + USDCEnabledChainSelectors: usdcChains, }, }, { @@ -283,7 +286,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) USDCCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) - for _, chain := range allChains { + for _, chain := range usdcChains { require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) require.NotNil(t, state.Chains[chain].USDCTokenPool) @@ -293,10 +296,17 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, } timelocksPerChain[chain] = state.Chains[chain].Timelock } - - server := mockAttestationResponse() - defer server.Close() - endpoint := server.URL + var usdcCfg USDCAttestationConfig + if isUSDC { + server := mockAttestationResponse() + defer server.Close() + endpoint := server.URL + usdcCfg = USDCAttestationConfig{ + API: endpoint, + APITimeout: commonconfig.MustNewDuration(time.Second), + APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + } + } // Deploy second set of changesets to deploy and configure the CCIP contracts. cs02 := []commonchangeset.ChangesetApplication{ @@ -312,24 +322,42 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, Config: DeployCCIPContractConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, - ChainsToDeploy: e.Env.AllChainSelectors(), + ChainsToDeploy: allChains, TokenConfig: tokenConfig, OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), USDCConfig: USDCConfig{ - EnabledChains: allChains, - USDCAttestationConfig: USDCAttestationConfig{ - API: endpoint, - APITimeout: commonconfig.MustNewDuration(time.Second), - APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), - }, - CCTPTokenConfig: USDCCCTPConfig, + EnabledChains: usdcChains, + USDCAttestationConfig: usdcCfg, + CCTPTokenConfig: USDCCCTPConfig, }, }, }, + { + Changeset: commonchangeset.WrapChangeSet(CCIPCapabilityJobspec), + }, } e.Env, err = commonchangeset.ApplyChangesets(context.Background(), e.Env, timelocksPerChain, cs02) require.NoError(t, err) + + state, err = LoadOnchainState(e.Env) + require.NoError(t, err) + require.NotNil(t, state.Chains[e.HomeChainSel].CapabilityRegistry) + require.NotNil(t, state.Chains[e.HomeChainSel].CCIPHome) + require.NotNil(t, state.Chains[e.HomeChainSel].RMNHome) + for _, chain := range allChains { + require.NotNil(t, state.Chains[chain].LinkToken) + require.NotNil(t, state.Chains[chain].Weth9) + require.NotNil(t, state.Chains[chain].TokenAdminRegistry) + require.NotNil(t, state.Chains[chain].RegistryModule) + require.NotNil(t, state.Chains[chain].Router) + require.NotNil(t, state.Chains[chain].RMNRemote) + require.NotNil(t, state.Chains[chain].TestRouter) + require.NotNil(t, state.Chains[chain].NonceManager) + require.NotNil(t, state.Chains[chain].FeeQuoter) + require.NotNil(t, state.Chains[chain].OffRamp) + require.NotNil(t, state.Chains[chain].OnRamp) + } return e } diff --git a/deployment/common/changeset/apply.go b/deployment/common/changeset/apply.go index 1c712eb1dd2..2537ca7dd01 100644 --- a/deployment/common/changeset/apply.go +++ b/deployment/common/changeset/apply.go @@ -18,11 +18,16 @@ type ChangesetApplication struct { func WrapChangeSet[C any](fn deployment.ChangeSet[C]) func(e deployment.Environment, config any) (deployment.ChangesetOutput, error) { return func(e deployment.Environment, config any) (deployment.ChangesetOutput, error) { - c, ok := config.(C) - if !ok { - return deployment.ChangesetOutput{}, fmt.Errorf("invalid config type, expected %T", c) + var zeroC C + if config != nil { + c, ok := config.(C) + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("invalid config type, expected %T", c) + } + return fn(e, config.(C)) } - return fn(e, c) + + return fn(e, zeroC) } } @@ -47,7 +52,7 @@ func ApplyChangesets(ctx context.Context, e deployment.Environment, timelocksPer for nodeID, jobs := range out.JobSpecs { for _, job := range jobs { // Note these auto-accept - _, err := e.Offchain.ProposeJob(ctx, + _, err := currentEnv.Offchain.ProposeJob(ctx, &jobv1.ProposeJobRequest{ NodeId: nodeID, Spec: job, From defa97f6662bd3475ef1dd4ecebf582dfe311446 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 15:03:57 -0800 Subject: [PATCH 16/27] fix go mod --- integration-tests/go.mod | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 80aa69c3a52..b9a39a4f952 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -34,10 +34,11 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.15.0 + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 github.com/smartcontractkit/chain-selectors v1.0.29 github.com/smartcontractkit/chainlink-automation v0.8.1 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b - github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.14 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 @@ -412,11 +413,10 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect + github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 // indirect github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.0 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241115191142-8b8369c1f44e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241017135645-176a23722fd8 // indirect From 43c58a3484dd0c75890c770aa039f9cf61ab6275 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 15:40:59 -0800 Subject: [PATCH 17/27] quick fix --- integration-tests/ccip-tests/testsetups/test_helpers.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index 4d6741d6af1..1177630dfff 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" chainsel "github.com/smartcontractkit/chain-selectors" + cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" @@ -114,6 +115,8 @@ func NewLocalDevEnvironment( e, don, err := devenv.NewEnvironment(ctx, lggr, *envConfig) require.NoError(t, err) require.NotNil(t, e) + e.ExistingAddresses = ab + // fund the nodes zeroLogLggr := logging.GetTestLogger(t) FundNodes(t, zeroLogLggr, testEnv, cfg, don.PluginNodes()) From a662514e71535745318fd41ffd5f6aa8be74b176 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 15:45:41 -0800 Subject: [PATCH 18/27] fix tests --- deployment/ccip/changeset/add_chain_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 2b6b79dde55..a9ca20ca127 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -67,7 +67,7 @@ func TestAddChainInbound(t *testing.T) { OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), }) require.NoError(t, err) - require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) + state, err = LoadOnchainState(e.Env) require.NoError(t, err) From 060c7fe681ae4a571b41f23480362d36038a7f0c Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 17:18:06 -0800 Subject: [PATCH 19/27] more optimize --- deployment/ccip/changeset/deploy.go | 38 +++++-- .../ccip/changeset/save_existing_test.go | 9 +- .../changeset/save_existing.go | 0 deployment/environment/devenv/environment.go | 16 +-- .../ccip-tests/testsetups/test_helpers.go | 105 ++++++++++-------- 5 files changed, 100 insertions(+), 68 deletions(-) rename deployment/{ccip => common}/changeset/save_existing.go (100%) diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 205c58711c0..488e36d7381 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -7,8 +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/pkg/errors" cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "golang.org/x/sync/errgroup" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" @@ -73,15 +73,20 @@ func DeployPrerequisiteChainContracts(e deployment.Environment, ab deployment.Ad for _, chain := range usdcEnabledChains { mapUSDCEnabledChains[chain] = true } + deployGrp := errgroup.Group{} for _, sel := range selectors { chain := e.Chains[sel] usdcEnabled := mapUSDCEnabledChains[sel] - err = DeployPrerequisiteContracts(e, ab, state, chain, usdcEnabled) - if err != nil { - return errors.Wrapf(err, "failed to deploy prerequisite contracts for chain %d", sel) - } - } - return nil + deployGrp.Go(func() error { + err := DeployPrerequisiteContracts(e, ab, state, chain, usdcEnabled) + if err != nil { + e.Logger.Errorw("Failed to deploy prerequisite contracts", "chain", sel, "err", err) + return err + } + return nil + }) + } + return deployGrp.Wait() } // DeployPrerequisiteContracts deploys the contracts that can be ported from previous CCIP version to the new one. @@ -527,6 +532,7 @@ func DeployChainContractsForChains( e.Logger.Errorw("Failed to get rmn home", "err", err) return fmt.Errorf("rmn home not found") } + deployGrp := errgroup.Group{} for _, chainSel := range chainsToDeploy { chain, ok := e.Chains[chainSel] if !ok { @@ -535,11 +541,19 @@ func DeployChainContractsForChains( if existingState.Chains[chainSel].LinkToken == nil || existingState.Chains[chainSel].Weth9 == nil { return fmt.Errorf("fee tokens not found for chain %d", chainSel) } - err := deployChainContracts(e, chain, ab, rmnHome) - if err != nil { - e.Logger.Errorw("Failed to deploy chain contracts", "chain", chainSel, "err", err) - return fmt.Errorf("failed to deploy chain contracts for chain %d: %w", chainSel, err) - } + deployGrp.Go( + func() error { + err := deployChainContracts(e, chain, ab, rmnHome) + if err != nil { + e.Logger.Errorw("Failed to deploy chain contracts", "chain", chainSel, "err", err) + return fmt.Errorf("failed to deploy chain contracts for chain %d: %w", chainSel, err) + } + return nil + }) + } + if err := deployGrp.Wait(); err != nil { + e.Logger.Errorw("Failed to deploy chain contracts", "err", err) + return err } return nil } diff --git a/deployment/ccip/changeset/save_existing_test.go b/deployment/ccip/changeset/save_existing_test.go index c3f25870d2e..93f3d7e067d 100644 --- a/deployment/ccip/changeset/save_existing_test.go +++ b/deployment/ccip/changeset/save_existing_test.go @@ -9,11 +9,12 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink/deployment" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" ) -func TestSaveExisting(t *testing.T) { +func TestSaveExistingCCIP(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ @@ -24,8 +25,8 @@ func TestSaveExisting(t *testing.T) { chains := e.AllChainSelectors() chain1 := chains[0] chain2 := chains[1] - cfg := ExistingContractsConfig{ - ExistingContracts: []Contract{ + cfg := commonchangeset.ExistingContractsConfig{ + ExistingContracts: []commonchangeset.Contract{ { Address: common.BigToAddress(big.NewInt(1)), TypeAndVersion: deployment.NewTypeAndVersion(LinkToken, deployment.Version1_0_0), @@ -54,7 +55,7 @@ func TestSaveExisting(t *testing.T) { }, } - output, err := SaveExistingContracts(e, cfg) + output, err := commonchangeset.SaveExistingContracts(e, cfg) require.NoError(t, err) err = e.ExistingAddresses.Merge(output.AddressBook) require.NoError(t, err) diff --git a/deployment/ccip/changeset/save_existing.go b/deployment/common/changeset/save_existing.go similarity index 100% rename from deployment/ccip/changeset/save_existing.go rename to deployment/common/changeset/save_existing.go diff --git a/deployment/environment/devenv/environment.go b/deployment/environment/devenv/environment.go index 4cae1b075b9..c11bc01cba6 100644 --- a/deployment/environment/devenv/environment.go +++ b/deployment/environment/devenv/environment.go @@ -56,30 +56,30 @@ func NewEnvironment(ctx context.Context, lggr logger.Logger, config EnvironmentC ), jd.don, nil } -func AddDonToEnvironment(ctx context.Context, config EnvironmentConfig, e *deployment.Environment) error { +func AddDonToEnvironment(ctx context.Context, config EnvironmentConfig, e *deployment.Environment) (*DON, error) { if e.Offchain == nil { - return fmt.Errorf("offchain client not set up") + return nil, fmt.Errorf("offchain client not set up") } jd, ok := e.Offchain.(*JobDistributor) if !ok { - return fmt.Errorf("offchain client does not implement JobDistributor") + return nil, fmt.Errorf("offchain client does not implement JobDistributor") } if jd == nil { - return fmt.Errorf("offchain client is not set up") + return nil, fmt.Errorf("offchain client is not set up") } if len(config.JDConfig.NodeInfo) == 0 { - return fmt.Errorf("no node info provided") + return nil, fmt.Errorf("no node info provided") } var err error jd.don, err = NewRegisteredDON(ctx, config.JDConfig.NodeInfo, *jd) if err != nil { - return fmt.Errorf("failed to create registered DON: %w", err) + return nil, fmt.Errorf("failed to create registered DON: %w", err) } err = jd.don.CreateSupportedChains(ctx, config.Chains, *jd) if err != nil { - return fmt.Errorf("failed to create supported chains: %w", err) + return nil, fmt.Errorf("failed to create supported chains: %w", err) } e.NodeIDs = jd.don.NodeIds() - return nil + return jd.don, nil } diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index 1177630dfff..f58527b64c3 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -112,6 +112,7 @@ func NewLocalDevEnvironment( crConfig, testEnv, cfg) require.NoError(t, err) + e, don, err := devenv.NewEnvironment(ctx, lggr, *envConfig) require.NoError(t, err) require.NotNil(t, e) @@ -122,7 +123,6 @@ func NewLocalDevEnvironment( FundNodes(t, zeroLogLggr, testEnv, cfg, don.PluginNodes()) env := *e - envNodes, err := deployment.NodeInfo(env.NodeIDs, env.Offchain) require.NoError(t, err) allChains := env.AllChainSelectors() @@ -166,6 +166,13 @@ func NewLocalDevEnvironment( Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), Config: mcmsCfg, }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContracts), + Config: changeset.DeployChainContractsConfig{ + ChainSelectors: allChains, + HomeChainSelector: homeChainSel, + }, + }, } ctx = testcontext.Get(t) // no proposals to be made, timelock can be passed as nil here @@ -202,16 +209,6 @@ func NewLocalDevEnvironment( // Deploy second set of changesets to deploy and configure the CCIP contracts. cs02 := []commonchangeset.ChangesetApplication{ - { - Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContracts), - Config: changeset.DeployChainContractsConfig{ - ChainSelectors: allChains, - HomeChainSelector: homeChainSel, - }, - }, - { - Changeset: commonchangeset.WrapChangeSet(changeset.CCIPCapabilityJobspec), - }, { Changeset: commonchangeset.WrapChangeSet(changeset.InitialAddChain), Config: changeset.DeployCCIPContractConfig{ @@ -227,6 +224,9 @@ func NewLocalDevEnvironment( }, }, }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.CCIPCapabilityJobspec), + }, } env, err = commonchangeset.ApplyChangesets(ctx, env, timelocksPerChain, cs02) @@ -236,7 +236,7 @@ func NewLocalDevEnvironment( changeset.ReplayLogs(t, e.Offchain, replayBlocks) return changeset.DeployedEnv{ - Env: *e, + Env: env, HomeChainSel: homeChainSel, FeedChainSel: feedSel, ReplayBlocks: replayBlocks, @@ -579,41 +579,58 @@ func FundNodes(t *testing.T, lggr zerolog.Logger, env *test_env.CLClusterTestEnv } } }) + fundGrp := errgroup.Group{} for i := range evmNetworks { - evmNetwork := evmNetworks[i] - sethClient, err := utils.TestAwareSethClient(t, cfg, &evmNetwork) - require.NoError(t, err, "Error getting seth client for network %s", evmNetwork.Name) - require.Greater(t, len(sethClient.PrivateKeys), 0, seth.ErrNoKeyLoaded) - privateKey := sethClient.PrivateKeys[0] - if evmNetwork.ChainID < 0 { - t.Fatalf("negative chain ID: %d", evmNetwork.ChainID) - } - for _, node := range nodes { - nodeAddr, ok := node.AccountAddr[uint64(evmNetwork.ChainID)] - require.True(t, ok, "Account address not found for chain %d", evmNetwork.ChainID) - fromAddress, err := actions.PrivateKeyToAddress(privateKey) - require.NoError(t, err, "Error getting address from private key") - amount := big.NewFloat(pointer.GetFloat64(cfg.Common.ChainlinkNodeFunding)) - toAddr := common.HexToAddress(nodeAddr) - receipt, err := actions.SendFunds(lggr, sethClient, actions.FundsToSendPayload{ - ToAddress: toAddr, - Amount: conversions.EtherToWei(amount), - PrivateKey: privateKey, - }) - require.NoError(t, err, "Error sending funds to node %s", node.Name) - require.NotNil(t, receipt, "Receipt is nil") - txHash := "(none)" - if receipt != nil { - txHash = receipt.TxHash.String() + fundGrp.Go(func() error { + evmNetwork := evmNetworks[i] + sethClient, err := utils.TestAwareSethClient(t, cfg, &evmNetwork) + if err != nil { + return fmt.Errorf("error getting seth client for network %s: %w", evmNetwork.Name, err) } - lggr.Info(). - Str("From", fromAddress.Hex()). - Str("To", toAddr.String()). - Str("TxHash", txHash). - Str("Amount", amount.String()). - Msg("Funded Chainlink node") - } + if len(sethClient.PrivateKeys) == 0 { + return fmt.Errorf(seth.ErrNoKeyLoaded) + } + privateKey := sethClient.PrivateKeys[0] + if evmNetwork.ChainID < 0 { + return fmt.Errorf("negative chain ID: %d", evmNetwork.ChainID) + } + for _, node := range nodes { + nodeAddr, ok := node.AccountAddr[uint64(evmNetwork.ChainID)] + if !ok { + return fmt.Errorf("account address not found for chain %d", evmNetwork.ChainID) + } + fromAddress, err := actions.PrivateKeyToAddress(privateKey) + if err != nil { + return fmt.Errorf("error getting address from private key: %w", err) + } + amount := big.NewFloat(pointer.GetFloat64(cfg.Common.ChainlinkNodeFunding)) + toAddr := common.HexToAddress(nodeAddr) + receipt, err := actions.SendFunds(lggr, sethClient, actions.FundsToSendPayload{ + ToAddress: toAddr, + Amount: conversions.EtherToWei(amount), + PrivateKey: privateKey, + }) + if err != nil { + return fmt.Errorf("error sending funds to node %s: %w", node.Name, err) + } + if receipt == nil { + return fmt.Errorf("receipt is nil") + } + txHash := "(none)" + if receipt != nil { + txHash = receipt.TxHash.String() + } + lggr.Info(). + Str("From", fromAddress.Hex()). + Str("To", toAddr.String()). + Str("TxHash", txHash). + Str("Amount", amount.String()). + Msg("Funded Chainlink node") + } + return nil + }) } + require.NoError(t, fundGrp.Wait(), "Error funding chainlink nodes") } // CreateChainConfigFromNetworks creates a list of ChainConfig from the network config provided in test config. From 55f9099f2330bd17b1be6bce97f131538a7fca2e Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 17:20:09 -0800 Subject: [PATCH 20/27] more fix --- integration-tests/ccip-tests/testsetups/test_helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index f58527b64c3..001aee3a8df 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -78,7 +78,7 @@ func (d DeployedLocalDevEnvironment) RestartChainlinkNodes(t *testing.T) error { } func NewLocalDevEnvironmentWithDefaultPrice(t *testing.T, lggr logger.Logger, isUSDC bool) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { - return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice, false) + return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice, isUSDC) } func NewLocalDevEnvironment( From b2128b486f183f382092bccd6a6acd677b0f28eb Mon Sep 17 00:00:00 2001 From: AnieeG Date: Wed, 20 Nov 2024 17:51:23 -0800 Subject: [PATCH 21/27] remove unnecessary methods --- deployment/environment/devenv/environment.go | 28 -------------------- 1 file changed, 28 deletions(-) diff --git a/deployment/environment/devenv/environment.go b/deployment/environment/devenv/environment.go index c11bc01cba6..94319d2247e 100644 --- a/deployment/environment/devenv/environment.go +++ b/deployment/environment/devenv/environment.go @@ -55,31 +55,3 @@ func NewEnvironment(ctx context.Context, lggr logger.Logger, config EnvironmentC offChain, ), jd.don, nil } - -func AddDonToEnvironment(ctx context.Context, config EnvironmentConfig, e *deployment.Environment) (*DON, error) { - if e.Offchain == nil { - return nil, fmt.Errorf("offchain client not set up") - } - jd, ok := e.Offchain.(*JobDistributor) - if !ok { - return nil, fmt.Errorf("offchain client does not implement JobDistributor") - } - if jd == nil { - return nil, fmt.Errorf("offchain client is not set up") - } - if len(config.JDConfig.NodeInfo) == 0 { - return nil, fmt.Errorf("no node info provided") - } - var err error - - jd.don, err = NewRegisteredDON(ctx, config.JDConfig.NodeInfo, *jd) - if err != nil { - return nil, fmt.Errorf("failed to create registered DON: %w", err) - } - err = jd.don.CreateSupportedChains(ctx, config.Chains, *jd) - if err != nil { - return nil, fmt.Errorf("failed to create supported chains: %w", err) - } - e.NodeIDs = jd.don.NodeIds() - return jd.don, nil -} From ea1bc144c3777210e6f9c65a018c39bb4d1cc7fc Mon Sep 17 00:00:00 2001 From: AnieeG Date: Thu, 21 Nov 2024 09:27:54 -0800 Subject: [PATCH 22/27] fix review comments --- .../ccip/changeset/active_candidate_test.go | 22 ++- deployment/ccip/changeset/add_chain_test.go | 11 +- deployment/ccip/changeset/add_lane_test.go | 2 +- deployment/ccip/changeset/deploy.go | 132 ++++++------------ deployment/ccip/changeset/deploy_test.go | 2 +- .../ccip/changeset/initial_add_chain.go | 90 +++++++++++- .../ccip/changeset/initial_deploy_test.go | 2 +- deployment/ccip/changeset/prerequisites.go | 14 +- deployment/ccip/changeset/test_helpers.go | 47 ++++--- .../common/changeset/mcms_test_helpers.go | 65 +++------ .../changeset/{apply.go => test_helpers.go} | 18 +-- .../ccip-tests/testsetups/test_helpers.go | 42 +++--- .../smoke/ccip_messaging_test.go | 2 +- integration-tests/smoke/ccip_test.go | 4 +- integration-tests/smoke/ccip_usdc_test.go | 4 +- 15 files changed, 222 insertions(+), 235 deletions(-) rename deployment/common/changeset/{apply.go => test_helpers.go} (77%) diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index 5fbbc08329b..be3cc9ac121 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -26,7 +26,7 @@ func TestActiveCandidate(t *testing.T) { t.Skipf("to be enabled after latest cl-ccip is compatible") lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5, false) + tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 5, nil) e := tenv.Env state, err := LoadOnchainState(tenv.Env) require.NoError(t, err) @@ -79,10 +79,9 @@ func TestActiveCandidate(t *testing.T) { TransferAllOwnership(t, state, tenv.HomeChainSel, e) acceptOwnershipProposal, err := GenerateAcceptOwnershipProposal(state, tenv.HomeChainSel, e.AllChainSelectors()) require.NoError(t, err) - acceptOwnershipExec, err := commonchangeset.SignProposal(e, acceptOwnershipProposal) - require.NoError(t, err) + acceptOwnershipExec := commonchangeset.SignProposal(t, e, acceptOwnershipProposal) for _, sel := range e.AllChainSelectors() { - require.NoError(t, commonchangeset.ExecuteProposal(e, acceptOwnershipExec, state.Chains[sel].Timelock, sel)) + commonchangeset.ExecuteProposal(t, e, acceptOwnershipExec, state.Chains[sel].Timelock, sel) } // Apply the accept ownership proposal to all the chains. @@ -144,9 +143,8 @@ func TestActiveCandidate(t *testing.T) { Batch: setCommitCandidateOp, }}, "set new candidates on commit plugin", 0) require.NoError(t, err) - setCommitCandidateSigned, err := commonchangeset.SignProposal(e, setCommitCandidateProposal) - require.NoError(t, err) - require.NoError(t, commonchangeset.ExecuteProposal(e, setCommitCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel)) + 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 := SetCandidateOnExistingDon( @@ -163,9 +161,8 @@ func TestActiveCandidate(t *testing.T) { Batch: setExecCandidateOp, }}, "set new candidates on commit and exec plugins", 0) require.NoError(t, err) - setExecCandidateSigned, err := commonchangeset.SignProposal(e, setExecCandidateProposal) - require.NoError(t, err) - require.NoError(t, commonchangeset.ExecuteProposal(e, setExecCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel)) + 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[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) @@ -191,9 +188,8 @@ func TestActiveCandidate(t *testing.T) { Batch: promoteOps, }}, "promote candidates and revoke actives", 0) require.NoError(t, err) - promoteSigned, err := commonchangeset.SignProposal(e, promoteProposal) - require.NoError(t, err) - require.NoError(t, commonchangeset.ExecuteProposal(e, promoteSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel)) + 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 diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index a9ca20ca127..b54abbcd66b 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -39,7 +39,7 @@ func TestAddChainInbound(t *testing.T) { // We deploy to the rest. initialDeploy := e.Env.AllChainSelectorsExcluding([]uint64{newChain}) newAddresses := deployment.NewMemoryAddressBook() - err = DeployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy, nil) + err = deployPrerequisiteChainContracts(e.Env, newAddresses, initialDeploy, nil) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) @@ -59,7 +59,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) newAddresses = deployment.NewMemoryAddressBook() tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - err = DeployCCIPContracts(e.Env, newAddresses, DeployCCIPContractConfig{ + err = DeployCCIPContracts(e.Env, newAddresses, NewChainConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: initialDeploy, @@ -95,7 +95,7 @@ func TestAddChainInbound(t *testing.T) { newAddresses = deployment.NewMemoryAddressBook() - err = DeployPrerequisiteChainContracts(e.Env, newAddresses, []uint64{newChain}, nil) + err = deployPrerequisiteChainContracts(e.Env, newAddresses, []uint64{newChain}, nil) require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) newAddresses = deployment.NewMemoryAddressBook() @@ -138,11 +138,10 @@ func TestAddChainInbound(t *testing.T) { acceptOwnershipProposal, err := GenerateAcceptOwnershipProposal(state, e.HomeChainSel, initialDeploy) require.NoError(t, err) - acceptOwnershipExec, err := commonchangeset.SignProposal(e.Env, acceptOwnershipProposal) - require.NoError(t, err) + acceptOwnershipExec := commonchangeset.SignProposal(t, e.Env, acceptOwnershipProposal) // Apply the accept ownership proposal to all the chains. for _, sel := range initialDeploy { - require.NoError(t, commonchangeset.ExecuteProposal(e.Env, acceptOwnershipExec, state.Chains[sel].Timelock, sel)) + commonchangeset.ExecuteProposal(t, e.Env, acceptOwnershipExec, state.Chains[sel].Timelock, sel) } for _, chain := range initialDeploy { owner, err2 := state.Chains[chain].OnRamp.Owner(nil) diff --git a/deployment/ccip/changeset/add_lane_test.go b/deployment/ccip/changeset/add_lane_test.go index ec79224d408..367fd68ba75 100644 --- a/deployment/ccip/changeset/add_lane_test.go +++ b/deployment/ccip/changeset/add_lane_test.go @@ -21,7 +21,7 @@ import ( func TestAddLane(t *testing.T) { t.Parallel() // We add more chains to the chainlink nodes than the number of chains where CCIP is deployed. - e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4, false) + e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4, nil) // Here we have CR + nodes set up, but no CCIP contracts deployed. state, err := LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 488e36d7381..eaa20d33c0f 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -7,11 +7,9 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "golang.org/x/sync/errgroup" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" @@ -63,22 +61,36 @@ var ( USDCTokenPool deployment.ContractType = "USDCTokenPool" ) -func DeployPrerequisiteChainContracts(e deployment.Environment, ab deployment.AddressBook, selectors []uint64, usdcEnabledChains []uint64) error { +type DeployPrerequisiteContractsOpts struct { + USDCEnabledChains []uint64 + Multicall3Enabled bool +} + +type PrerequisiteOpt func(o *DeployPrerequisiteContractsOpts) + +func WithUSDCChains(chains []uint64) PrerequisiteOpt { + return func(o *DeployPrerequisiteContractsOpts) { + o.USDCEnabledChains = chains + } +} + +func WithMulticall3(enabled bool) PrerequisiteOpt { + return func(o *DeployPrerequisiteContractsOpts) { + o.Multicall3Enabled = enabled + } +} + +func deployPrerequisiteChainContracts(e deployment.Environment, ab deployment.AddressBook, selectors []uint64, opts ...PrerequisiteOpt) error { state, err := LoadOnchainState(e) if err != nil { e.Logger.Errorw("Failed to load existing onchain state", "err") return err } - mapUSDCEnabledChains := make(map[uint64]bool) - for _, chain := range usdcEnabledChains { - mapUSDCEnabledChains[chain] = true - } deployGrp := errgroup.Group{} for _, sel := range selectors { chain := e.Chains[sel] - usdcEnabled := mapUSDCEnabledChains[sel] deployGrp.Go(func() error { - err := DeployPrerequisiteContracts(e, ab, state, chain, usdcEnabled) + err := deployPrerequisiteContracts(e, ab, state, chain, opts...) if err != nil { e.Logger.Errorw("Failed to deploy prerequisite contracts", "chain", sel, "err", err) return err @@ -89,9 +101,20 @@ func DeployPrerequisiteChainContracts(e deployment.Environment, ab deployment.Ad return deployGrp.Wait() } -// DeployPrerequisiteContracts deploys the contracts that can be ported from previous CCIP version to the new one. +// deployPrerequisiteContracts deploys the contracts that can be ported from previous CCIP version to the new one. // This is only required for staging and test environments where the contracts are not already deployed. -func DeployPrerequisiteContracts(e deployment.Environment, ab deployment.AddressBook, state CCIPOnChainState, chain deployment.Chain, usdcEnabled bool) error { +func deployPrerequisiteContracts(e deployment.Environment, ab deployment.AddressBook, state CCIPOnChainState, chain deployment.Chain, opts ...PrerequisiteOpt) error { + deployOpts := &DeployPrerequisiteContractsOpts{} + for _, opt := range opts { + opt(deployOpts) + } + var isUSDC bool + for _, sel := range deployOpts.USDCEnabledChains { + if sel == chain.Selector { + isUSDC = true + break + } + } lggr := e.Logger chainState, chainExists := state.Chains[chain.Selector] var weth9Contract *weth9.WETH9 @@ -271,7 +294,7 @@ func DeployPrerequisiteContracts(e deployment.Environment, ab deployment.Address } else { e.Logger.Infow("router already deployed", "addr", chainState.Router.Address) } - if usdcEnabled { + if isUSDC { token, pool, messenger, transmitter, err1 := DeployUSDC(e.Logger, chain, ab, rmnProxy.Address(), r.Address()) if err1 != nil { return err1 @@ -287,14 +310,14 @@ func DeployPrerequisiteContracts(e deployment.Environment, ab deployment.Address return nil } -// ConfigureChain assumes the all the Home chain contracts and CCIP contracts are deployed +// configureChain assumes the all the Home chain contracts and CCIP contracts are deployed // It does - // 1. AddChainConfig for each chain in CCIPHome // 2. Registers the nodes with the capability registry // 3. SetOCR3Config on the remote chain -func ConfigureChain( +func configureChain( e deployment.Environment, - c DeployCCIPContractConfig, + c NewChainConfig, ) error { if c.OCRSecrets.IsEmpty() { return fmt.Errorf("OCR secrets are empty") @@ -380,81 +403,6 @@ func ConfigureChain( return nil } -type USDCConfig struct { - EnabledChains []uint64 - USDCAttestationConfig - CCTPTokenConfig map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig -} - -func (cfg USDCConfig) EnabledChainMap() map[uint64]bool { - m := make(map[uint64]bool) - for _, chain := range cfg.EnabledChains { - m[chain] = true - } - return m -} - -type USDCAttestationConfig struct { - API string - APITimeout *commonconfig.Duration - APIInterval *commonconfig.Duration -} - -type DeployCCIPContractConfig struct { - HomeChainSel uint64 - FeedChainSel uint64 - ChainsToDeploy []uint64 - TokenConfig TokenConfig - USDCConfig USDCConfig - // For setting OCR configuration - OCRSecrets deployment.OCRSecrets -} - -func (c DeployCCIPContractConfig) Validate() error { - if err := deployment.IsValidChainSelector(c.HomeChainSel); err != nil { - return fmt.Errorf("invalid home chain selector: %d - %w", c.HomeChainSel, err) - } - if err := deployment.IsValidChainSelector(c.FeedChainSel); err != nil { - return fmt.Errorf("invalid feed chain selector: %d - %w", c.FeedChainSel, err) - } - mapChainsToDeploy := make(map[uint64]bool) - for _, cs := range c.ChainsToDeploy { - mapChainsToDeploy[cs] = true - if err := deployment.IsValidChainSelector(cs); err != nil { - return fmt.Errorf("invalid chain selector: %d - %w", cs, err) - } - } - for token := range c.TokenConfig.TokenSymbolToInfo { - if err := c.TokenConfig.TokenSymbolToInfo[token].Validate(); err != nil { - return fmt.Errorf("invalid token config for token %s: %w", token, err) - } - } - if c.OCRSecrets.IsEmpty() { - return fmt.Errorf("no OCR secrets provided") - } - usdcEnabledChainMap := c.USDCConfig.EnabledChainMap() - for chain := range usdcEnabledChainMap { - if _, exists := mapChainsToDeploy[chain]; !exists { - return fmt.Errorf("chain %d is not in chains to deploy", chain) - } - if err := deployment.IsValidChainSelector(chain); err != nil { - return fmt.Errorf("invalid chain selector: %d - %w", chain, err) - } - } - for chain := range c.USDCConfig.CCTPTokenConfig { - if _, exists := mapChainsToDeploy[uint64(chain)]; !exists { - return fmt.Errorf("chain %d is not in chains to deploy", chain) - } - if _, exists := usdcEnabledChainMap[uint64(chain)]; !exists { - return fmt.Errorf("chain %d is not enabled in USDC config", chain) - } - if err := deployment.IsValidChainSelector(uint64(chain)); err != nil { - return fmt.Errorf("invalid chain selector: %d - %w", chain, err) - } - } - return nil -} - // DeployCCIPContracts assumes the following contracts are deployed: // - Capability registry // - CCIP home @@ -467,7 +415,7 @@ func (c DeployCCIPContractConfig) Validate() error { func DeployCCIPContracts( e deployment.Environment, ab deployment.AddressBook, - c DeployCCIPContractConfig) error { + c NewChainConfig) error { err := DeployChainContractsForChains(e, ab, c.HomeChainSel, c.ChainsToDeploy) if err != nil { e.Logger.Errorw("Failed to deploy chain contracts", "err", err) @@ -478,7 +426,7 @@ func DeployCCIPContracts( e.Logger.Errorw("Failed to merge address book", "err", err) return err } - err = ConfigureChain(e, c) + err = configureChain(e, c) if err != nil { e.Logger.Errorw("Failed to add chain", "err", err) return err diff --git a/deployment/ccip/changeset/deploy_test.go b/deployment/ccip/changeset/deploy_test.go index 0e30eb6c73d..fb5729c5b77 100644 --- a/deployment/ccip/changeset/deploy_test.go +++ b/deployment/ccip/changeset/deploy_test.go @@ -12,7 +12,7 @@ import ( func TestDeployCCIPContracts(t *testing.T) { lggr := logger.TestLogger(t) - e := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, false) + e := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, nil) // Deploy all the CCIP contracts. state, err := LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/deployment/ccip/changeset/initial_add_chain.go b/deployment/ccip/changeset/initial_add_chain.go index e3f3b558784..488c48e1e41 100644 --- a/deployment/ccip/changeset/initial_add_chain.go +++ b/deployment/ccip/changeset/initial_add_chain.go @@ -4,22 +4,25 @@ import ( "fmt" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/deployment" ) -var _ deployment.ChangeSet[DeployCCIPContractConfig] = InitialAddChain +var _ deployment.ChangeSet[NewChainConfig] = ConfigureNewChains -// InitialAddChain enables new chains as destination for CCIP +// ConfigureNewChains 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 -// ConfigureChain assumes that the home chain is already enabled and all CCIP contracts are already deployed. -func InitialAddChain(env deployment.Environment, c DeployCCIPContractConfig) (deployment.ChangesetOutput, error) { +// ConfigureNewChains assumes that the home chain is already enabled and all CCIP contracts are already deployed. +func ConfigureNewChains(env deployment.Environment, c NewChainConfig) (deployment.ChangesetOutput, error) { if err := c.Validate(); err != nil { - return deployment.ChangesetOutput{}, fmt.Errorf("invalid InitialAddChainConfig: %w", err) + return deployment.ChangesetOutput{}, fmt.Errorf("invalid NewChainConfig: %w", err) } - err := ConfigureChain(env, c) + err := configureChain(env, c) if err != nil { env.Logger.Errorw("Failed to configure chain", "err", err) return deployment.ChangesetOutput{}, deployment.MaybeDataErr(err) @@ -30,3 +33,78 @@ func InitialAddChain(env deployment.Environment, c DeployCCIPContractConfig) (de JobSpecs: nil, }, nil } + +type USDCConfig struct { + EnabledChains []uint64 + USDCAttestationConfig + CCTPTokenConfig map[ccipocr3.ChainSelector]pluginconfig.USDCCCTPTokenConfig +} + +func (cfg USDCConfig) EnabledChainMap() map[uint64]bool { + m := make(map[uint64]bool) + for _, chain := range cfg.EnabledChains { + m[chain] = true + } + return m +} + +type USDCAttestationConfig struct { + API string + APITimeout *config.Duration + APIInterval *config.Duration +} + +type NewChainConfig struct { + HomeChainSel uint64 + FeedChainSel uint64 + ChainsToDeploy []uint64 + TokenConfig TokenConfig + USDCConfig USDCConfig + // For setting OCR configuration + OCRSecrets deployment.OCRSecrets +} + +func (c NewChainConfig) Validate() error { + if err := deployment.IsValidChainSelector(c.HomeChainSel); err != nil { + return fmt.Errorf("invalid home chain selector: %d - %w", c.HomeChainSel, err) + } + if err := deployment.IsValidChainSelector(c.FeedChainSel); err != nil { + return fmt.Errorf("invalid feed chain selector: %d - %w", c.FeedChainSel, err) + } + mapChainsToDeploy := make(map[uint64]bool) + for _, cs := range c.ChainsToDeploy { + mapChainsToDeploy[cs] = true + if err := deployment.IsValidChainSelector(cs); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", cs, err) + } + } + for token := range c.TokenConfig.TokenSymbolToInfo { + if err := c.TokenConfig.TokenSymbolToInfo[token].Validate(); err != nil { + return fmt.Errorf("invalid token config for token %s: %w", token, err) + } + } + if c.OCRSecrets.IsEmpty() { + return fmt.Errorf("no OCR secrets provided") + } + usdcEnabledChainMap := c.USDCConfig.EnabledChainMap() + for chain := range usdcEnabledChainMap { + if _, exists := mapChainsToDeploy[chain]; !exists { + return fmt.Errorf("chain %d is not in chains to deploy", chain) + } + if err := deployment.IsValidChainSelector(chain); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", chain, err) + } + } + for chain := range c.USDCConfig.CCTPTokenConfig { + if _, exists := mapChainsToDeploy[uint64(chain)]; !exists { + return fmt.Errorf("chain %d is not in chains to deploy", chain) + } + if _, exists := usdcEnabledChainMap[uint64(chain)]; !exists { + return fmt.Errorf("chain %d is not enabled in USDC config", chain) + } + if err := deployment.IsValidChainSelector(uint64(chain)); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", chain, err) + } + } + return nil +} diff --git a/deployment/ccip/changeset/initial_deploy_test.go b/deployment/ccip/changeset/initial_deploy_test.go index c0eaaa70e85..ff68659102f 100644 --- a/deployment/ccip/changeset/initial_deploy_test.go +++ b/deployment/ccip/changeset/initial_deploy_test.go @@ -15,7 +15,7 @@ import ( func TestInitialDeploy(t *testing.T) { lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 4, false) + tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 3, 4, nil) e := tenv.Env state, err := LoadOnchainState(e) diff --git a/deployment/ccip/changeset/prerequisites.go b/deployment/ccip/changeset/prerequisites.go index dac00b4535d..34780809827 100644 --- a/deployment/ccip/changeset/prerequisites.go +++ b/deployment/ccip/changeset/prerequisites.go @@ -24,7 +24,7 @@ func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfi return deployment.ChangesetOutput{}, errors.Wrapf(deployment.ErrInvalidConfig, "%v", err) } ab := deployment.NewMemoryAddressBook() - err = DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors, cfg.USDCEnabledChainSelectors) + err = deployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors, cfg.Opts...) if err != nil { env.Logger.Errorw("Failed to deploy prerequisite contracts", "err", err, "addressBook", ab) return deployment.ChangesetOutput{ @@ -39,8 +39,8 @@ func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfi } type DeployPrerequisiteConfig struct { - ChainSelectors []uint64 - USDCEnabledChainSelectors []uint64 + ChainSelectors []uint64 + Opts []PrerequisiteOpt // TODO handle tokens and feeds in prerequisite config Tokens map[TokenSymbol]common.Address Feeds map[TokenSymbol]common.Address @@ -54,13 +54,5 @@ func (c DeployPrerequisiteConfig) Validate() error { return fmt.Errorf("invalid chain selector: %d - %w", cs, err) } } - for _, cs := range c.USDCEnabledChainSelectors { - if _, ok := mapAllChainSelectors[cs]; !ok { - return fmt.Errorf("chain selector %d is not present in ChainSelectors", cs) - } - if err := deployment.IsValidChainSelector(cs); err != nil { - return fmt.Errorf("invalid chain selector: %d - %w", cs, err) - } - } return nil } diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 9b45dcba965..40c5da21e96 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -244,7 +244,12 @@ func mockAttestationResponse() *httptest.Server { return server } -func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, numChains int, numNodes int, isUSDC bool) DeployedEnv { +type TestConfigs struct { + IsUSDC bool + IsMultiCall3 bool +} + +func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, numChains int, numNodes int, tCfg *TestConfigs) DeployedEnv { var err error e := NewMemoryEnvironment(t, lggr, numChains, numNodes, MockLinkPrice, MockWethPrice) allChains := e.Env.AllChainSelectors() @@ -260,44 +265,45 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, mcmsCfg[c] = cfg } var usdcChains []uint64 - if isUSDC { + if tCfg != nil && tCfg.IsUSDC { usdcChains = allChains } - // Need to deploy prerequisites first so that we can for the CCIP contracts. - cs01 := []commonchangeset.ChangesetApplication{ + // Need to deploy prerequisites first so that we can form the USDC config + // no proposals to be made, timelock can be passed as nil here + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(DeployPrerequisites), Config: DeployPrerequisiteConfig{ - ChainSelectors: allChains, - USDCEnabledChainSelectors: usdcChains, + ChainSelectors: allChains, + Opts: []PrerequisiteOpt{ + WithUSDCChains(usdcChains), + }, }, }, { Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), Config: mcmsCfg, }, - } - // no proposals to be made, timelock can be passed as nil here - e.Env, err = commonchangeset.ApplyChangesets(context.Background(), e.Env, nil, cs01) + }) require.NoError(t, err) state, err := LoadOnchainState(e.Env) require.NoError(t, err) tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - USDCCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) + usdcCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) for _, chain := range usdcChains { require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) require.NotNil(t, state.Chains[chain].USDCTokenPool) - USDCCCTPConfig[cciptypes.ChainSelector(chain)] = pluginconfig.USDCCCTPTokenConfig{ + usdcCCTPConfig[cciptypes.ChainSelector(chain)] = pluginconfig.USDCCCTPTokenConfig{ SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), } timelocksPerChain[chain] = state.Chains[chain].Timelock } var usdcCfg USDCAttestationConfig - if isUSDC { + if len(usdcChains) > 0 { server := mockAttestationResponse() defer server.Close() endpoint := server.URL @@ -309,7 +315,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, } // Deploy second set of changesets to deploy and configure the CCIP contracts. - cs02 := []commonchangeset.ChangesetApplication{ + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), Config: DeployChainContractsConfig{ @@ -318,8 +324,8 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, }, }, { - Changeset: commonchangeset.WrapChangeSet(InitialAddChain), - Config: DeployCCIPContractConfig{ + Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), + Config: NewChainConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: allChains, @@ -328,16 +334,14 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, USDCConfig: USDCConfig{ EnabledChains: usdcChains, USDCAttestationConfig: usdcCfg, - CCTPTokenConfig: USDCCCTPConfig, + CCTPTokenConfig: usdcCCTPConfig, }, }, }, { Changeset: commonchangeset.WrapChangeSet(CCIPCapabilityJobspec), }, - } - - e.Env, err = commonchangeset.ApplyChangesets(context.Background(), e.Env, timelocksPerChain, cs02) + }) require.NoError(t, err) state, err = LoadOnchainState(e.Env) @@ -651,10 +655,9 @@ func ProcessChangeset(t *testing.T, e deployment.Environment, c deployment.Chang chains.Add(uint64(op.ChainIdentifier)) } - signed, err := commonchangeset.SignProposal(e, &prop) - require.NoError(t, err) + signed := commonchangeset.SignProposal(t, e, &prop) for _, sel := range chains.ToSlice() { - require.NoError(t, commonchangeset.ExecuteProposal(e, signed, state.Chains[sel].Timelock, sel)) + commonchangeset.ExecuteProposal(t, e, signed, state.Chains[sel].Timelock, sel) } } } diff --git a/deployment/common/changeset/mcms_test_helpers.go b/deployment/common/changeset/mcms_test_helpers.go index ac0699570d2..3951149815c 100644 --- a/deployment/common/changeset/mcms_test_helpers.go +++ b/deployment/common/changeset/mcms_test_helpers.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "crypto/ecdsa" - "fmt" "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -43,51 +42,38 @@ func SingleGroupMCMS(t *testing.T) config.Config { return *c } -func SignProposal(env deployment.Environment, proposal *timelock.MCMSWithTimelockProposal) (*mcms.Executor, error) { +func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.MCMSWithTimelockProposal) *mcms.Executor { executorClients := make(map[mcms.ChainIdentifier]mcms.ContractDeployBackend) for _, chain := range env.Chains { chainselc, exists := chainsel.ChainBySelector(chain.Selector) - if !exists { - return nil, fmt.Errorf("failed to find chain by selector: %d", chain.Selector) - } + require.True(t, exists) chainSel := mcms.ChainIdentifier(chainselc.Selector) executorClients[chainSel] = chain.Client } executor, err := proposal.ToExecutor(true) - if err != nil { - return nil, fmt.Errorf("failed to convert proposal to executor: %w", err) - } + require.NoError(t, err) payload, err := executor.SigningHash() - if err != nil { - return nil, fmt.Errorf("failed to get signing hash: %w", err) - } + require.NoError(t, err) // Sign the payload sig, err := crypto.Sign(payload.Bytes(), TestXXXMCMSSigner) - if err != nil { - return nil, fmt.Errorf("failed to sign payload: %w", err) - } + require.NoError(t, err) mcmSig, err := mcms.NewSignatureFromBytes(sig) - if err != nil { - return nil, fmt.Errorf("failed to create signature from bytes: %w", err) - } + require.NoError(t, err) executor.Proposal.AddSignature(mcmSig) - if err := executor.Proposal.Validate(); err != nil { - return nil, fmt.Errorf("failed to validate proposal: %w", err) - } - return executor, nil + require.NoError(t, executor.Proposal.Validate()) + return executor } -func ExecuteProposal(env deployment.Environment, executor *mcms.Executor, timelock *owner_helpers.RBACTimelock, sel uint64) error { - env.Logger.Infow("Executing proposal on chain", "selector", sel) +func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Executor, + timelock *owner_helpers.RBACTimelock, sel uint64) { + t.Log("Executing proposal on chain", sel) // Set the root. tx, err2 := executor.SetRootOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, mcms.ChainIdentifier(sel)) if err2 != nil { - return fmt.Errorf("failed to set root: %w", deployment.MaybeDataErr(err2)) + require.NoError(t, deployment.MaybeDataErr(err2)) } _, err2 = env.Chains[sel].Confirm(tx) - if err2 != nil { - return fmt.Errorf("failed to confirm set-root: %w", err2) - } + require.NoError(t, err2) // TODO: This sort of helper probably should move to the MCMS lib. // Execute all the transactions in the proposal which are for this chain. @@ -95,29 +81,23 @@ func ExecuteProposal(env deployment.Environment, executor *mcms.Executor, timelo for idx, op := range executor.ChainAgnosticOps { if bytes.Equal(op.Data, chainOp.Data) && op.To == chainOp.To { opTx, err3 := executor.ExecuteOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, idx) - if err3 != nil { - return fmt.Errorf("failed to execute operation: %w", deployment.MaybeDataErr(err3)) - } + require.NoError(t, err3) block, err3 := env.Chains[sel].Confirm(opTx) - if err3 != nil { - return fmt.Errorf("failed to confirm operation ExecuteOnChain: %w", err3) - } - env.Logger.Infow("executed", "chainOp", chainOp) + require.NoError(t, err3) + t.Log("executed", chainOp) it, err3 := timelock.FilterCallScheduled(&bind.FilterOpts{ Start: block, End: &block, Context: context.Background(), }, nil, nil) - if err3 != nil { - return fmt.Errorf("failed to filter call scheduled: %w", err3) - } + require.NoError(t, err3) var calls []owner_helpers.RBACTimelockCall var pred, salt [32]byte for it.Next() { // Note these are the same for the whole batch, can overwrite pred = it.Event.Predecessor salt = it.Event.Salt - env.Logger.Infow("scheduled", "Event", it.Event) + t.Log("scheduled", it.Event) calls = append(calls, owner_helpers.RBACTimelockCall{ Target: it.Event.Target, Data: it.Event.Data, @@ -126,15 +106,10 @@ func ExecuteProposal(env deployment.Environment, executor *mcms.Executor, timelo } tx, err := timelock.ExecuteBatch( env.Chains[sel].DeployerKey, calls, pred, salt) - if err != nil { - return fmt.Errorf("failed to execute batch: %w", deployment.MaybeDataErr(err)) - } + require.NoError(t, err) _, err = env.Chains[sel].Confirm(tx) - if err != nil { - return fmt.Errorf("failed to confirm execute batch: %w", err) - } + require.NoError(t, err) } } } - return nil } diff --git a/deployment/common/changeset/apply.go b/deployment/common/changeset/test_helpers.go similarity index 77% rename from deployment/common/changeset/apply.go rename to deployment/common/changeset/test_helpers.go index 2537ca7dd01..cf6dc809d0a 100644 --- a/deployment/common/changeset/apply.go +++ b/deployment/common/changeset/test_helpers.go @@ -1,18 +1,19 @@ package changeset import ( - "context" "fmt" + "testing" mapset "github.com/deckarep/golang-set/v2" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment" ) type ChangesetApplication struct { - Changeset func(e deployment.Environment, config any) (deployment.ChangesetOutput, error) + Changeset deployment.ChangeSet[any] Config any } @@ -32,7 +33,7 @@ func WrapChangeSet[C any](fn deployment.ChangeSet[C]) func(e deployment.Environm } // ApplyChangesets applies the changeset applications to the environment and returns the updated environment. -func ApplyChangesets(ctx context.Context, e deployment.Environment, timelocksPerChain map[uint64]*gethwrappers.RBACTimelock, changesetApplications []ChangesetApplication) (deployment.Environment, error) { +func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain map[uint64]*gethwrappers.RBACTimelock, changesetApplications []ChangesetApplication) (deployment.Environment, error) { currentEnv, err := e.Copy() if err != nil { return e, fmt.Errorf("failed to copy environment: %w", err) @@ -49,6 +50,7 @@ func ApplyChangesets(ctx context.Context, e deployment.Environment, timelocksPer } } if out.JobSpecs != nil { + ctx := testcontext.Get(t) for nodeID, jobs := range out.JobSpecs { for _, job := range jobs { // Note these auto-accept @@ -70,19 +72,13 @@ func ApplyChangesets(ctx context.Context, e deployment.Environment, timelocksPer chains.Add(uint64(op.ChainIdentifier)) } - signed, err := SignProposal(e, &prop) - if err != nil { - return deployment.Environment{}, fmt.Errorf("failed to sign proposal: %w", err) - } + signed := SignProposal(t, e, &prop) for _, sel := range chains.ToSlice() { timelock, ok := timelocksPerChain[sel] if !ok || timelock == nil { return deployment.Environment{}, fmt.Errorf("timelock not found for chain %d", sel) } - err := ExecuteProposal(e, signed, timelock, sel) - if err != nil { - return deployment.Environment{}, fmt.Errorf("failed to execute proposal: %w", err) - } + ExecuteProposal(t, e, signed, timelock, sel) } } } diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index 001aee3a8df..9b210b36847 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -77,15 +77,15 @@ func (d DeployedLocalDevEnvironment) RestartChainlinkNodes(t *testing.T) error { return errGrp.Wait() } -func NewLocalDevEnvironmentWithDefaultPrice(t *testing.T, lggr logger.Logger, isUSDC bool) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { - return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice, isUSDC) +func NewLocalDevEnvironmentWithDefaultPrice(t *testing.T, lggr logger.Logger, tCfg *changeset.TestConfigs) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { + return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice, tCfg) } func NewLocalDevEnvironment( t *testing.T, lggr logger.Logger, linkPrice, wethPrice *big.Int, - isUSDC bool, + tCfg *changeset.TestConfigs, ) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { ctx := testcontext.Get(t) // create a local docker environment with simulated chains and job-distributor @@ -127,7 +127,7 @@ func NewLocalDevEnvironment( require.NoError(t, err) allChains := env.AllChainSelectors() var usdcChains []uint64 - if isUSDC { + if tCfg != nil && tCfg.IsUSDC { usdcChains = allChains } mcmsCfgPerChain := commontypes.MCMSWithTimelockConfig{ @@ -141,8 +141,9 @@ func NewLocalDevEnvironment( for _, c := range env.AllChainSelectors() { mcmsCfg[c] = mcmsCfgPerChain } - // Need to deploy prerequisites first so that we can for the CCIP contracts. - cs01 := []commonchangeset.ChangesetApplication{ + // Need to deploy prerequisites first so that we can form the USDC config + // no proposals to be made, timelock can be passed as nil here + env, err = commonchangeset.ApplyChangesets(t, env, nil, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.DeployHomeChain), Config: changeset.DeployHomeChainConfig{ @@ -158,8 +159,10 @@ func NewLocalDevEnvironment( { Changeset: commonchangeset.WrapChangeSet(changeset.DeployPrerequisites), Config: changeset.DeployPrerequisiteConfig{ - ChainSelectors: allChains, - USDCEnabledChainSelectors: usdcChains, + ChainSelectors: allChains, + Opts: []changeset.PrerequisiteOpt{ + changeset.WithUSDCChains(usdcChains), + }, }, }, { @@ -173,22 +176,19 @@ func NewLocalDevEnvironment( HomeChainSelector: homeChainSel, }, }, - } - ctx = testcontext.Get(t) - // no proposals to be made, timelock can be passed as nil here - env, err = commonchangeset.ApplyChangesets(ctx, env, nil, cs01) + }) require.NoError(t, err) state, err := changeset.LoadOnchainState(env) require.NoError(t, err) tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) - USDCCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) + usdcCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) for _, chain := range usdcChains { require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) require.NotNil(t, state.Chains[chain].USDCTokenPool) - USDCCCTPConfig[cciptypes.ChainSelector(chain)] = pluginconfig.USDCCCTPTokenConfig{ + usdcCCTPConfig[cciptypes.ChainSelector(chain)] = pluginconfig.USDCCCTPTokenConfig{ SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), } @@ -208,10 +208,10 @@ func NewLocalDevEnvironment( } // Deploy second set of changesets to deploy and configure the CCIP contracts. - cs02 := []commonchangeset.ChangesetApplication{ + env, err = commonchangeset.ApplyChangesets(t, env, timelocksPerChain, []commonchangeset.ChangesetApplication{ { - Changeset: commonchangeset.WrapChangeSet(changeset.InitialAddChain), - Config: changeset.DeployCCIPContractConfig{ + Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureNewChains), + Config: changeset.NewChainConfig{ HomeChainSel: homeChainSel, FeedChainSel: feedSel, ChainsToDeploy: allChains, @@ -220,16 +220,14 @@ func NewLocalDevEnvironment( USDCConfig: changeset.USDCConfig{ EnabledChains: usdcChains, USDCAttestationConfig: usdcAttestationCfg, - CCTPTokenConfig: USDCCCTPConfig, + CCTPTokenConfig: usdcCCTPConfig, }, }, }, { Changeset: commonchangeset.WrapChangeSet(changeset.CCIPCapabilityJobspec), }, - } - - env, err = commonchangeset.ApplyChangesets(ctx, env, timelocksPerChain, cs02) + }) require.NoError(t, err) // Ensure capreg logs are up to date. @@ -248,7 +246,7 @@ func NewLocalDevEnvironmentWithRMN( lggr logger.Logger, numRmnNodes int, ) (changeset.DeployedEnv, devenv.RMNCluster) { - tenv, dockerenv, testCfg := NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) + tenv, dockerenv, testCfg := NewLocalDevEnvironmentWithDefaultPrice(t, lggr, nil) l := logging.GetTestLogger(t) config := GenerateTestRMNConfig(t, numRmnNodes, tenv, MustNetworksToRPCMap(dockerenv.EVMNetworks)) require.NotNil(t, testCfg.CCIP) diff --git a/integration-tests/smoke/ccip_messaging_test.go b/integration-tests/smoke/ccip_messaging_test.go index 32d68577b72..e64a36a8a9a 100644 --- a/integration-tests/smoke/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip_messaging_test.go @@ -49,7 +49,7 @@ func Test_CCIPMessaging(t *testing.T) { // Setup 2 chains and a single lane. lggr := logger.TestLogger(t) ctx := changeset.Context(t) - e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) + e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, nil) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip_test.go b/integration-tests/smoke/ccip_test.go index cccfcc20dc8..26804eb5fff 100644 --- a/integration-tests/smoke/ccip_test.go +++ b/integration-tests/smoke/ccip_test.go @@ -18,7 +18,7 @@ import ( func TestInitialDeployOnLocal(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) + tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, nil) e := tenv.Env state, err := changeset.LoadOnchainState(e) require.NoError(t, err) @@ -73,7 +73,7 @@ func TestInitialDeployOnLocal(t *testing.T) { func TestTokenTransfer(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, false) + tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, nil) e := tenv.Env state, err := changeset.LoadOnchainState(e) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip_usdc_test.go b/integration-tests/smoke/ccip_usdc_test.go index 880e9fa8ea7..25db383bb22 100644 --- a/integration-tests/smoke/ccip_usdc_test.go +++ b/integration-tests/smoke/ccip_usdc_test.go @@ -26,7 +26,9 @@ import ( func TestUSDCTokenTransfer(t *testing.T) { lggr := logger.TestLogger(t) - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, true) + tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, &changeset.TestConfigs{ + IsUSDC: true, + }) e := tenv.Env state, err := changeset.LoadOnchainState(e) From 49dcad3ed6f6e572dd92f44e63932d7f171e144a Mon Sep 17 00:00:00 2001 From: AnieeG Date: Thu, 21 Nov 2024 09:44:46 -0800 Subject: [PATCH 23/27] fixes --- deployment/ccip/changeset/deploy.go | 4 +++- integration-tests/smoke/ccip/fee_boosting_test.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index eaa20d33c0f..5f59812fd0c 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -106,7 +106,9 @@ func deployPrerequisiteChainContracts(e deployment.Environment, ab deployment.Ad func deployPrerequisiteContracts(e deployment.Environment, ab deployment.AddressBook, state CCIPOnChainState, chain deployment.Chain, opts ...PrerequisiteOpt) error { deployOpts := &DeployPrerequisiteContractsOpts{} for _, opt := range opts { - opt(deployOpts) + if opt != nil { + opt(deployOpts) + } } var isUSDC bool for _, sel := range deployOpts.USDCEnabledChains { diff --git a/integration-tests/smoke/ccip/fee_boosting_test.go b/integration-tests/smoke/ccip/fee_boosting_test.go index 83711d85ab5..37d6d8523ce 100644 --- a/integration-tests/smoke/ccip/fee_boosting_test.go +++ b/integration-tests/smoke/ccip/fee_boosting_test.go @@ -34,7 +34,7 @@ type priceFeedPrices struct { // TODO: find a way to reuse the same test setup for all tests func Test_CCIPFeeBoosting(t *testing.T) { setupTestEnv := func(t *testing.T, numChains int) (changeset.DeployedEnv, changeset.CCIPOnChainState, []uint64) { - e, _, _ := testsetups.NewLocalDevEnvironment(t, logger.TestLogger(t), deployment.E18Mult(5), big.NewInt(9e8), false) + e, _, _ := testsetups.NewLocalDevEnvironment(t, logger.TestLogger(t), deployment.E18Mult(5), big.NewInt(9e8), nil) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) From 7cb2a624940b7c25e244bc07bbddececb855bdb6 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Thu, 21 Nov 2024 10:35:58 -0800 Subject: [PATCH 24/27] add a test --- .../common/changeset/save_existing_test.go | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 deployment/common/changeset/save_existing_test.go diff --git a/deployment/common/changeset/save_existing_test.go b/deployment/common/changeset/save_existing_test.go new file mode 100644 index 00000000000..2a2618c8f54 --- /dev/null +++ b/deployment/common/changeset/save_existing_test.go @@ -0,0 +1,54 @@ +package changeset + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestSaveExisting(t *testing.T) { + dummyEnv := deployment.Environment{ + Name: "dummy", + Logger: logger.TestLogger(t), + ExistingAddresses: deployment.NewMemoryAddressBook(), + Chains: map[uint64]deployment.Chain{ + chainsel.TEST_90000001.Selector: {}, + chainsel.TEST_90000002.Selector: {}, + }, + } + ExistingContracts := ExistingContractsConfig{ + ExistingContracts: []Contract{ + { + Address: common.BigToAddress(big.NewInt(1)), + TypeAndVersion: deployment.TypeAndVersion{ + Type: "dummy1", + Version: deployment.Version1_5_0, + }, + ChainSelector: chainsel.TEST_90000001.Selector, + }, + { + Address: common.BigToAddress(big.NewInt(2)), + TypeAndVersion: deployment.TypeAndVersion{ + Type: "dummy2", + Version: deployment.Version1_1_0, + }, + ChainSelector: chainsel.TEST_90000002.Selector, + }, + }, + } + + output, err := SaveExistingContracts(dummyEnv, ExistingContracts) + require.NoError(t, err) + require.NoError(t, dummyEnv.ExistingAddresses.Merge(output.AddressBook)) + addresses, err := dummyEnv.ExistingAddresses.Addresses() + require.Len(t, addresses, 2) + addressForChain1, exists := addresses[chainsel.TEST_90000001.Selector] + require.True(t, exists) + require.Len(t, addressForChain1, 1) +} From 8d4a5bb66eb87fe4f316ec17c1fcbe7c15c22274 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Thu, 21 Nov 2024 11:02:49 -0800 Subject: [PATCH 25/27] more fix --- deployment/ccip/changeset/add_chain_test.go | 2 +- deployment/ccip/changeset/deploy.go | 4 ++-- deployment/ccip/changeset/initial_add_chain.go | 10 +++++----- deployment/ccip/changeset/test_helpers.go | 2 +- integration-tests/testsetups/test_helpers.go | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index b54abbcd66b..5f8380436bd 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -59,7 +59,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) newAddresses = deployment.NewMemoryAddressBook() tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - err = DeployCCIPContracts(e.Env, newAddresses, NewChainConfig{ + err = DeployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: initialDeploy, diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 5f59812fd0c..f3cd5ebf210 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -319,7 +319,7 @@ func deployPrerequisiteContracts(e deployment.Environment, ab deployment.Address // 3. SetOCR3Config on the remote chain func configureChain( e deployment.Environment, - c NewChainConfig, + c NewChainsConfig, ) error { if c.OCRSecrets.IsEmpty() { return fmt.Errorf("OCR secrets are empty") @@ -417,7 +417,7 @@ func configureChain( func DeployCCIPContracts( e deployment.Environment, ab deployment.AddressBook, - c NewChainConfig) error { + c NewChainsConfig) error { err := DeployChainContractsForChains(e, ab, c.HomeChainSel, c.ChainsToDeploy) if err != nil { e.Logger.Errorw("Failed to deploy chain contracts", "err", err) diff --git a/deployment/ccip/changeset/initial_add_chain.go b/deployment/ccip/changeset/initial_add_chain.go index 488c48e1e41..0e8da566626 100644 --- a/deployment/ccip/changeset/initial_add_chain.go +++ b/deployment/ccip/changeset/initial_add_chain.go @@ -11,16 +11,16 @@ import ( "github.com/smartcontractkit/chainlink/deployment" ) -var _ deployment.ChangeSet[NewChainConfig] = ConfigureNewChains +var _ deployment.ChangeSet[NewChainsConfig] = ConfigureNewChains // ConfigureNewChains 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 // ConfigureNewChains assumes that the home chain is already enabled and all CCIP contracts are already deployed. -func ConfigureNewChains(env deployment.Environment, c NewChainConfig) (deployment.ChangesetOutput, error) { +func ConfigureNewChains(env deployment.Environment, c NewChainsConfig) (deployment.ChangesetOutput, error) { if err := c.Validate(); err != nil { - return deployment.ChangesetOutput{}, fmt.Errorf("invalid NewChainConfig: %w", err) + return deployment.ChangesetOutput{}, fmt.Errorf("invalid NewChainsConfig: %w", err) } err := configureChain(env, c) if err != nil { @@ -54,7 +54,7 @@ type USDCAttestationConfig struct { APIInterval *config.Duration } -type NewChainConfig struct { +type NewChainsConfig struct { HomeChainSel uint64 FeedChainSel uint64 ChainsToDeploy []uint64 @@ -64,7 +64,7 @@ type NewChainConfig struct { OCRSecrets deployment.OCRSecrets } -func (c NewChainConfig) Validate() error { +func (c NewChainsConfig) Validate() error { if err := deployment.IsValidChainSelector(c.HomeChainSel); err != nil { return fmt.Errorf("invalid home chain selector: %d - %w", c.HomeChainSel, err) } diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 40c5da21e96..921d0a222eb 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -325,7 +325,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, }, { Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), - Config: NewChainConfig{ + Config: NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: allChains, diff --git a/integration-tests/testsetups/test_helpers.go b/integration-tests/testsetups/test_helpers.go index e4dde005a14..ed3e6aafea5 100644 --- a/integration-tests/testsetups/test_helpers.go +++ b/integration-tests/testsetups/test_helpers.go @@ -216,7 +216,7 @@ func NewLocalDevEnvironment( env, err = commonchangeset.ApplyChangesets(t, env, timelocksPerChain, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureNewChains), - Config: changeset.NewChainConfig{ + Config: changeset.NewChainsConfig{ HomeChainSel: homeChainSel, FeedChainSel: feedSel, ChainsToDeploy: allChains, From 9ca4940f87020ea3caccceae61f453870eb92050 Mon Sep 17 00:00:00 2001 From: AnieeG Date: Thu, 21 Nov 2024 11:39:50 -0800 Subject: [PATCH 26/27] more review comments --- deployment/ccip/changeset/add_chain_test.go | 2 +- deployment/ccip/changeset/deploy.go | 8 ++++---- deployment/ccip/changeset/deploy_chain.go | 4 ++-- deployment/common/changeset/test_helpers.go | 19 +++++++++++++------ deployment/environment.go | 11 ----------- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 5f8380436bd..d369a481c7d 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -59,7 +59,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) newAddresses = deployment.NewMemoryAddressBook() tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - err = DeployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ + err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: initialDeploy, diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index f3cd5ebf210..8d2b6a63e12 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -405,7 +405,7 @@ func configureChain( return nil } -// DeployCCIPContracts assumes the following contracts are deployed: +// deployCCIPContracts assumes the following contracts are deployed: // - Capability registry // - CCIP home // - RMN home @@ -414,11 +414,11 @@ func configureChain( // It then deploys the rest of the CCIP chain contracts to the selected chains // registers the nodes with the capability registry and creates a DON for // each new chain. -func DeployCCIPContracts( +func deployCCIPContracts( e deployment.Environment, ab deployment.AddressBook, c NewChainsConfig) error { - err := DeployChainContractsForChains(e, ab, c.HomeChainSel, c.ChainsToDeploy) + err := deployChainContractsForChains(e, ab, c.HomeChainSel, c.ChainsToDeploy) if err != nil { e.Logger.Errorw("Failed to deploy chain contracts", "err", err) return err @@ -437,7 +437,7 @@ func DeployCCIPContracts( return nil } -func DeployChainContractsForChains( +func deployChainContractsForChains( e deployment.Environment, ab deployment.AddressBook, homeChainSel uint64, diff --git a/deployment/ccip/changeset/deploy_chain.go b/deployment/ccip/changeset/deploy_chain.go index c1ab11a994e..4c37603c64d 100644 --- a/deployment/ccip/changeset/deploy_chain.go +++ b/deployment/ccip/changeset/deploy_chain.go @@ -12,12 +12,12 @@ 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 +// DeployChainContracts is idempotent. 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 := DeployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors) + err := deployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors) if err != nil { env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "newAddresses", newAddresses) return deployment.ChangesetOutput{AddressBook: newAddresses}, deployment.MaybeDataErr(err) diff --git a/deployment/common/changeset/test_helpers.go b/deployment/common/changeset/test_helpers.go index cf6dc809d0a..ae20ba61abf 100644 --- a/deployment/common/changeset/test_helpers.go +++ b/deployment/common/changeset/test_helpers.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/deployment" ) @@ -34,12 +35,18 @@ func WrapChangeSet[C any](fn deployment.ChangeSet[C]) func(e deployment.Environm // ApplyChangesets applies the changeset applications to the environment and returns the updated environment. func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain map[uint64]*gethwrappers.RBACTimelock, changesetApplications []ChangesetApplication) (deployment.Environment, error) { - currentEnv, err := e.Copy() - if err != nil { - return e, fmt.Errorf("failed to copy environment: %w", err) - } + addrBook := deployment.NewMemoryAddressBook() + require.NoError(t, addrBook.Merge(e.ExistingAddresses)) + currentEnv := deployment.NewEnvironment( + e.Name, + e.Logger, + addrBook, + e.Chains, + e.NodeIDs, + e.Offchain, + ) for i, csa := range changesetApplications { - out, err := csa.Changeset(currentEnv, csa.Config) + out, err := csa.Changeset(*currentEnv, csa.Config) if err != nil { return e, fmt.Errorf("failed to apply changeset at index %d: %w", i, err) } @@ -83,5 +90,5 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain m } } } - return currentEnv, nil + return *currentEnv, nil } diff --git a/deployment/environment.go b/deployment/environment.go index 3918d1ba5e1..b9f3700bdc4 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -76,17 +76,6 @@ type Environment struct { Offchain OffchainClient } -func (e Environment) Copy() (Environment, error) { - newEnv := e - addr := NewMemoryAddressBook() - err := addr.Merge(e.ExistingAddresses) - if err != nil { - return Environment{}, err - } - newEnv.ExistingAddresses = addr - return newEnv, nil -} - func NewEnvironment( name string, logger logger.Logger, From 321539ef50389221ffb9de04e13868082b0cacfb Mon Sep 17 00:00:00 2001 From: AnieeG Date: Thu, 21 Nov 2024 11:53:57 -0800 Subject: [PATCH 27/27] fix ApplyChangesets --- deployment/common/changeset/test_helpers.go | 30 +++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/deployment/common/changeset/test_helpers.go b/deployment/common/changeset/test_helpers.go index ae20ba61abf..913b4544f30 100644 --- a/deployment/common/changeset/test_helpers.go +++ b/deployment/common/changeset/test_helpers.go @@ -8,7 +8,6 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/deployment" ) @@ -35,26 +34,21 @@ func WrapChangeSet[C any](fn deployment.ChangeSet[C]) func(e deployment.Environm // ApplyChangesets applies the changeset applications to the environment and returns the updated environment. func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain map[uint64]*gethwrappers.RBACTimelock, changesetApplications []ChangesetApplication) (deployment.Environment, error) { - addrBook := deployment.NewMemoryAddressBook() - require.NoError(t, addrBook.Merge(e.ExistingAddresses)) - currentEnv := deployment.NewEnvironment( - e.Name, - e.Logger, - addrBook, - e.Chains, - e.NodeIDs, - e.Offchain, - ) + currentEnv := e for i, csa := range changesetApplications { - out, err := csa.Changeset(*currentEnv, csa.Config) + out, err := csa.Changeset(currentEnv, csa.Config) if err != nil { return e, fmt.Errorf("failed to apply changeset at index %d: %w", i, err) } + var addresses deployment.AddressBook if out.AddressBook != nil { - err := currentEnv.ExistingAddresses.Merge(out.AddressBook) + addresses = out.AddressBook + err := addresses.Merge(currentEnv.ExistingAddresses) if err != nil { return e, fmt.Errorf("failed to merge address book: %w", err) } + } else { + addresses = currentEnv.ExistingAddresses } if out.JobSpecs != nil { ctx := testcontext.Get(t) @@ -89,6 +83,14 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain m } } } + currentEnv = deployment.Environment{ + Name: e.Name, + Logger: e.Logger, + ExistingAddresses: addresses, + Chains: e.Chains, + NodeIDs: e.NodeIDs, + Offchain: e.Offchain, + } } - return *currentEnv, nil + return currentEnv, nil }