From 4b6f8eeaa94b62dcef1752a0354f3d3010ef00f1 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Mon, 2 Dec 2024 15:25:45 -0500 Subject: [PATCH 1/3] Simplify new chain config --- .../ccip/changeset/accept_ownership_test.go | 45 +------- deployment/ccip/changeset/active_candidate.go | 1 + .../ccip/changeset/active_candidate_test.go | 1 + deployment/ccip/changeset/add_chain.go | 3 + deployment/ccip/changeset/add_chain_test.go | 19 +++- deployment/ccip/changeset/deploy.go | 32 ++---- .../ccip/changeset/deploy_home_chain.go | 2 +- .../ccip/changeset/initial_add_chain.go | 101 +++++++----------- deployment/ccip/changeset/test_helpers.go | 70 +++++++----- .../testsetups/ccip/test_helpers.go | 89 +++++++-------- 10 files changed, 156 insertions(+), 207 deletions(-) diff --git a/deployment/ccip/changeset/accept_ownership_test.go b/deployment/ccip/changeset/accept_ownership_test.go index c3407e0e6e7..97a5e1f9aa9 100644 --- a/deployment/ccip/changeset/accept_ownership_test.go +++ b/deployment/ccip/changeset/accept_ownership_test.go @@ -1,25 +1,24 @@ package changeset import ( - "math/big" "testing" "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + + "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - "github.com/smartcontractkit/chainlink/deployment" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" - commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/stretchr/testify/require" - "golang.org/x/exp/maps" ) func Test_NewAcceptOwnershipChangeset(t *testing.T) { - e := NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), 2, 4) + e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4, &TestConfigs{}) state, err := LoadOnchainState(e.Env) require.NoError(t, err) @@ -27,40 +26,6 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) { source := allChains[0] dest := allChains[1] - newAddresses := deployment.NewMemoryAddressBook() - err = deployPrerequisiteChainContracts(e.Env, newAddresses, allChains, nil) - require.NoError(t, err) - require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - - mcmConfig := commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.Env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } - out, err := commonchangeset.DeployMCMSWithTimelock(e.Env, map[uint64]commontypes.MCMSWithTimelockConfig{ - source: mcmConfig, - dest: mcmConfig, - }) - require.NoError(t, err) - require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) - newAddresses = deployment.NewMemoryAddressBook() - tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - ocrParams := make(map[uint64]CCIPOCRParams) - for _, chain := range allChains { - ocrParams[chain] = DefaultOCRParams(e.FeedChainSel, nil) - } - err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ - HomeChainSel: e.HomeChainSel, - FeedChainSel: e.FeedChainSel, - ChainsToDeploy: allChains, - TokenConfig: tokenConfig, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - OCRParams: ocrParams, - }) - require.NoError(t, err) - // at this point we have the initial deploys done, now we need to transfer ownership // to the timelock contract state, err = LoadOnchainState(e.Env) diff --git a/deployment/ccip/changeset/active_candidate.go b/deployment/ccip/changeset/active_candidate.go index bc65cef71e7..e3391c9226c 100644 --- a/deployment/ccip/changeset/active_candidate.go +++ b/deployment/ccip/changeset/active_candidate.go @@ -74,6 +74,7 @@ func SetCandidatePluginChangeset( ccipOCRParams := DefaultOCRParams( feedChainSel, tokenConfig.GetTokenInfo(e.Logger, state.Chains[newChainSel].LinkToken, state.Chains[newChainSel].Weth9), + nil, ) newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( ocrSecrets, diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index 70280a33bb0..4d72ab6ccf2 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -141,6 +141,7 @@ func TestActiveCandidate(t *testing.T) { ccipOCRParams := DefaultOCRParams( tenv.FeedChainSel, tokenConfig.GetTokenInfo(e.Logger, state.Chains[tenv.FeedChainSel].LinkToken, state.Chains[tenv.FeedChainSel].Weth9), + nil, ) ocr3ConfigMap, err := internal.BuildOCR3ConfigForCCIPHome( deployment.XXXGenerateTestOCRSecrets(), diff --git a/deployment/ccip/changeset/add_chain.go b/deployment/ccip/changeset/add_chain.go index d97915c4022..958fdd4d095 100644 --- a/deployment/ccip/changeset/add_chain.go +++ b/deployment/ccip/changeset/add_chain.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" @@ -119,6 +120,8 @@ func AddDonAndSetCandidateChangeset( ccipOCRParams := DefaultOCRParams( feedChainSel, tokenConfig.GetTokenInfo(e.Logger, state.Chains[newChainSel].LinkToken, state.Chains[newChainSel].Weth9), + // TODO: Need USDC support. + nil, ) newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( ocrSecrets, diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 39ae27f9444..40fc678a4d4 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -61,12 +62,20 @@ func TestAddChainInbound(t *testing.T) { newAddresses = deployment.NewMemoryAddressBook() tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + chainConfig := make(map[uint64]CCIPOCRParams) + for _, chain := range initialDeploy { + ocrParams := DefaultOCRParams(e.FeedChainSel, nil, nil) + chainConfig[chain] = CCIPOCRParams{ + OCRParameters: ocrParams.OCRParameters, + CommitOffChainConfig: ocrParams.CommitOffChainConfig, + ExecuteOffChainConfig: ocrParams.ExecuteOffChainConfig, + } + } err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ - HomeChainSel: e.HomeChainSel, - FeedChainSel: e.FeedChainSel, - ChainsToDeploy: initialDeploy, - TokenConfig: tokenConfig, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + HomeChainSel: e.HomeChainSel, + FeedChainSel: e.FeedChainSel, + ChainConfigByChain: chainConfig, + OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), }) require.NoError(t, err) diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 3aa654862dc..7761e72526a 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -7,7 +7,7 @@ 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/deployment/ccip/changeset/internal" @@ -371,16 +371,12 @@ func configureChain( return fmt.Errorf("rmn home not found") } - for _, chainSel := range c.ChainsToDeploy { + for chainSel, chainConfig := range c.ChainConfigByChain { chain, _ := e.Chains[chainSel] chainState, ok := existingState.Chains[chain.Selector] if !ok { return fmt.Errorf("chain state not found for chain %d", chain.Selector) } - ocrParams, ok := c.OCRParams[chain.Selector] - if !ok { - return fmt.Errorf("OCR params not found for chain %d", chain.Selector) - } if chainState.OffRamp == nil { return fmt.Errorf("off ramp not found for chain %d", chain.Selector) } @@ -393,10 +389,6 @@ func configureChain( if err != nil { return err } - if enabled, ok := c.USDCConfig.EnabledChainMap()[chainSel]; ok && enabled { - ocrParams.ExecuteOffChainConfig.TokenDataObservers = c.USDCConfig.ToTokenDataObserverConfig() - } - ocrParams.CommitOffChainConfig.PriceFeedChainSelector = cciptypes.ChainSelector(c.FeedChainSel) // For each chain, we create a DON on the home chain (2 OCR instances) if err := addDON( e.Logger, @@ -408,7 +400,11 @@ func configureChain( chain, e.Chains[c.HomeChainSel], nodes.NonBootstraps(), - ocrParams, + CCIPOCRParams{ + OCRParameters: chainConfig.OCRParameters, + CommitOffChainConfig: chainConfig.CommitOffChainConfig, + ExecuteOffChainConfig: chainConfig.ExecuteOffChainConfig, + }, ); err != nil { e.Logger.Errorw("Failed to add DON", "err", err) return err @@ -431,7 +427,7 @@ 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.Chains()) if err != nil { e.Logger.Errorw("Failed to deploy chain contracts", "err", err) return err @@ -441,18 +437,6 @@ func deployCCIPContracts( e.Logger.Errorw("Failed to merge address book", "err", err) return err } - state, err := LoadOnchainState(e) - if err != nil { - e.Logger.Errorw("Failed to load existing onchain state", "err", err) - return err - } - - ocrParams := make(map[uint64]CCIPOCRParams) - for _, chain := range c.ChainsToDeploy { - tokenInfo := c.TokenConfig.GetTokenInfo(e.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) - ocrParams[chain] = DefaultOCRParams(c.FeedChainSel, tokenInfo) - } - c.OCRParams = ocrParams err = configureChain(e, c) if err != nil { e.Logger.Errorw("Failed to add chain", "err", err) diff --git a/deployment/ccip/changeset/deploy_home_chain.go b/deployment/ccip/changeset/deploy_home_chain.go index 881f7c386c3..73fd0c8b98c 100644 --- a/deployment/ccip/changeset/deploy_home_chain.go +++ b/deployment/ccip/changeset/deploy_home_chain.go @@ -288,7 +288,7 @@ func AddChainConfig( chainSelector uint64, p2pIDs [][32]byte, ) (ccip_home.CCIPHomeChainConfigArgs, error) { - // First Add ChainConfig that includes all p2pIDs as readers + // First Add CCIPOCRParams that includes all p2pIDs as readers encodedExtraChainConfig, err := chainconfig.EncodeChainConfig(chainconfig.ChainConfig{ GasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(1000), DAGasPriceDeviationPPB: ccipocr3.NewBigIntFromInt64(0), diff --git a/deployment/ccip/changeset/initial_add_chain.go b/deployment/ccip/changeset/initial_add_chain.go index 841f2014204..cc39e2b06e2 100644 --- a/deployment/ccip/changeset/initial_add_chain.go +++ b/deployment/ccip/changeset/initial_add_chain.go @@ -3,16 +3,14 @@ package changeset import ( "fmt" "os" - "slices" - "sort" "time" "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-common/pkg/merklemulti" - "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -20,8 +18,8 @@ import ( var _ deployment.ChangeSet[NewChainsConfig] = ConfigureNewChains -// ConfigureNewChains enables new chains as destination for CCIP -// It performs the following steps: +// ConfigureNewChains enables new chains as destination(s) for CCIP +// It performs the following steps per chain: // - 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. @@ -41,6 +39,7 @@ func ConfigureNewChains(env deployment.Environment, c NewChainsConfig) (deployme }, nil } +/* type USDCConfig struct { EnabledChains []uint64 USDCAttestationConfig @@ -67,6 +66,7 @@ func (cfg USDCConfig) ToTokenDataObserverConfig() []pluginconfig.TokenDataObserv }, }} } +*/ type USDCAttestationConfig struct { API string @@ -75,33 +75,41 @@ type USDCAttestationConfig struct { } type CCIPOCRParams struct { - OCRParameters types.OCRParameters - CommitOffChainConfig pluginconfig.CommitOffchainConfig + OCRParameters types.OCRParameters + // Note contains pointers to Arb feeds for prices + CommitOffChainConfig pluginconfig.CommitOffchainConfig + // Note ontains USDC config ExecuteOffChainConfig pluginconfig.ExecuteOffchainConfig } -func (p CCIPOCRParams) Validate() error { - if err := p.OCRParameters.Validate(); err != nil { +func (c CCIPOCRParams) Validate() error { + if err := c.OCRParameters.Validate(); err != nil { return fmt.Errorf("invalid OCR parameters: %w", err) } - if err := p.CommitOffChainConfig.Validate(); err != nil { + if err := c.CommitOffChainConfig.Validate(); err != nil { return fmt.Errorf("invalid commit off-chain config: %w", err) } - if err := p.ExecuteOffChainConfig.Validate(); err != nil { + if err := c.ExecuteOffChainConfig.Validate(); err != nil { return fmt.Errorf("invalid execute off-chain config: %w", err) } return nil } type NewChainsConfig struct { - HomeChainSel uint64 - FeedChainSel uint64 - ChainsToDeploy []uint64 - TokenConfig TokenConfig - USDCConfig USDCConfig - // For setting OCR configuration - OCRSecrets deployment.OCRSecrets - OCRParams map[uint64]CCIPOCRParams + // Common to all chains + HomeChainSel uint64 + FeedChainSel uint64 + OCRSecrets deployment.OCRSecrets + // Per chain config + ChainConfigByChain map[uint64]CCIPOCRParams +} + +func (c NewChainsConfig) Chains() []uint64 { + chains := make([]uint64, 0, len(c.ChainConfigByChain)) + for chain := range c.ChainConfigByChain { + chains = append(chains, chain) + } + return chains } func (c NewChainsConfig) Validate() error { @@ -111,63 +119,27 @@ func (c NewChainsConfig) Validate() error { 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) - } - } - // Validate OCR params - var ocrChains []uint64 - for chain, ocrParams := range c.OCRParams { - ocrChains = append(ocrChains, chain) - if _, exists := mapChainsToDeploy[chain]; !exists { - return fmt.Errorf("chain %d is not in chains to deploy", chain) - } - if err := ocrParams.Validate(); err != nil { + // Validate chain config + for chain, cfg := range c.ChainConfigByChain { + if err := cfg.Validate(); err != nil { return fmt.Errorf("invalid OCR params for chain %d: %w", chain, err) } - } - sort.Slice(ocrChains, func(i, j int) bool { return ocrChains[i] < ocrChains[j] }) - sort.Slice(c.ChainsToDeploy, func(i, j int) bool { return c.ChainsToDeploy[i] < c.ChainsToDeploy[j] }) - if !slices.Equal(ocrChains, c.ChainsToDeploy) { - return fmt.Errorf("mismatch in given OCR params and chains to deploy") + if cfg.CommitOffChainConfig.PriceFeedChainSelector != ccipocr3.ChainSelector(c.FeedChainSel) { + return fmt.Errorf("chain %d has invalid feed chain selector", chain) + } } return nil } +// DefaultOCRParams returns the default OCR parameters for a chain, +// except for a few values which must be parameterized (passed as arguments). func DefaultOCRParams( feedChainSel uint64, tokenInfo map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo, + tokenDataObservers []pluginconfig.TokenDataObserverConfig, ) CCIPOCRParams { return CCIPOCRParams{ OCRParameters: types.OCRParameters{ @@ -191,6 +163,7 @@ func DefaultOCRParams( RootSnoozeTime: *config.MustNewDuration(internal.RootSnoozeTime), MessageVisibilityInterval: *config.MustNewDuration(internal.FirstBlockAge), BatchingStrategyID: internal.BatchingStrategyID, + TokenDataObservers: tokenDataObservers, }, CommitOffChainConfig: pluginconfig.CommitOffchainConfig{ RemoteGasPriceBatchWriteFrequency: *config.MustNewDuration(internal.RemoteGasPriceBatchWriteFrequency), diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index ea1cea2c790..587f2b9136d 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -268,16 +268,15 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, var err error e := NewMemoryEnvironment(t, lggr, numChains, numNodes, MockLinkPrice, MockWethPrice) allChains := e.Env.AllChainSelectors() - cfg := commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.Env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) for _, c := range e.Env.AllChainSelectors() { - mcmsCfg[c] = cfg + mcmsCfg[c] = commontypes.MCMSWithTimelockConfig{ + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockExecutors: e.Env.AllDeployerKeys(), + TimelockMinDelay: big.NewInt(0), + } } var usdcChains []uint64 if tCfg != nil && tCfg.IsUSDC { @@ -311,21 +310,17 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, state, err := LoadOnchainState(e.Env) require.NoError(t, err) - tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - ocrParams := make(map[uint64]CCIPOCRParams) - usdcCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) - timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) + // Assert USDC set up as expected. 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(), - } } + // Assert link present require.NotNil(t, state.Chains[e.FeedChainSel].LinkToken) require.NotNil(t, state.Chains[e.FeedChainSel].Weth9) + + tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) var usdcCfg USDCAttestationConfig if len(usdcChains) > 0 { server := mockAttestationResponse() @@ -339,28 +334,45 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, server.Close() }) } - + // Build the per chain config. + chainConfigs := make(map[uint64]CCIPOCRParams) + timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) for _, chain := range allChains { timelocksPerChain[chain] = state.Chains[chain].Timelock tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) - ocrParams[chain] = DefaultOCRParams(e.FeedChainSel, tokenInfo) + var tokenDataProviders []pluginconfig.TokenDataObserverConfig + if len(usdcChains) > 0 { + tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ + Type: pluginconfig.USDCCCTPHandlerType, + Version: "1.0", + USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ + Tokens: map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig{ + cciptypes.ChainSelector(chain): { + SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), + SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), + }, + }, + AttestationAPI: usdcCfg.API, + AttestationAPITimeout: usdcCfg.APITimeout, + AttestationAPIInterval: usdcCfg.APIInterval, + }}) + } + ocrParams := DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) + chainConfigs[chain] = CCIPOCRParams{ + OCRParameters: ocrParams.OCRParameters, + CommitOffChainConfig: ocrParams.CommitOffChainConfig, + ExecuteOffChainConfig: ocrParams.ExecuteOffChainConfig, + } } // Deploy second set of changesets to deploy and configure the CCIP contracts. e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), Config: NewChainsConfig{ - HomeChainSel: e.HomeChainSel, - FeedChainSel: e.FeedChainSel, - ChainsToDeploy: allChains, - TokenConfig: tokenConfig, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - USDCConfig: USDCConfig{ - EnabledChains: usdcChains, - USDCAttestationConfig: usdcCfg, - CCTPTokenConfig: usdcCCTPConfig, - }, - OCRParams: ocrParams, + HomeChainSel: e.HomeChainSel, + FeedChainSel: e.FeedChainSel, + OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + ChainConfigByChain: chainConfigs, }, }, { diff --git a/integration-tests/testsetups/ccip/test_helpers.go b/integration-tests/testsetups/ccip/test_helpers.go index a2c680ee814..068827e6715 100644 --- a/integration-tests/testsetups/ccip/test_helpers.go +++ b/integration-tests/testsetups/ccip/test_helpers.go @@ -140,16 +140,15 @@ func NewLocalDevEnvironment( if tCfg.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 _, c := range env.AllChainSelectors() { - mcmsCfg[c] = mcmsCfgPerChain + mcmsCfg[c] = commontypes.MCMSWithTimelockConfig{ + Canceller: commonchangeset.SingleGroupMCMS(t), + Bypasser: commonchangeset.SingleGroupMCMS(t), + Proposer: commonchangeset.SingleGroupMCMS(t), + TimelockExecutors: env.AllDeployerKeys(), + TimelockMinDelay: big.NewInt(0), + } } // 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 @@ -189,64 +188,66 @@ func NewLocalDevEnvironment( }, }) 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) - timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) - ocrParams := make(map[uint64]changeset.CCIPOCRParams) - 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(), - } - } - var usdcAttestationCfg changeset.USDCAttestationConfig + + var usdcCfg 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{ + usdcCfg = changeset.USDCAttestationConfig{ API: endpoint, APITimeout: commonconfig.MustNewDuration(time.Second), APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), } } - require.NotNil(t, state.Chains[feedSel].LinkToken) - require.NotNil(t, state.Chains[feedSel].Weth9) + // Build the per chain config. + tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) + chainConfigs := make(map[uint64]changeset.CCIPOCRParams) + timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) for _, chain := range allChains { timelocksPerChain[chain] = state.Chains[chain].Timelock - tokenInfo := tokenConfig.GetTokenInfo(env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) - - params := changeset.DefaultOCRParams(feedSel, tokenInfo) + tokenInfo := tokenConfig.GetTokenInfo(e.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) + var tokenDataProviders []pluginconfig.TokenDataObserverConfig + if len(usdcChains) > 0 { + tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ + Type: pluginconfig.USDCCCTPHandlerType, + Version: "1.0", + USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ + Tokens: map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig{ + cciptypes.ChainSelector(chain): { + SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), + SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), + }, + }, + AttestationAPI: usdcCfg.API, + AttestationAPITimeout: usdcCfg.APITimeout, + AttestationAPIInterval: usdcCfg.APIInterval, + }}) + } + ocrParams := changeset.DefaultOCRParams(feedSel, tokenInfo, tokenDataProviders) if tCfg.OCRConfigOverride != nil { - params = tCfg.OCRConfigOverride(params) + ocrParams = tCfg.OCRConfigOverride(ocrParams) + } + chainConfigs[chain] = changeset.CCIPOCRParams{ + OCRParameters: ocrParams.OCRParameters, + CommitOffChainConfig: ocrParams.CommitOffChainConfig, + ExecuteOffChainConfig: ocrParams.ExecuteOffChainConfig, } - - ocrParams[chain] = params } + // Deploy second set of changesets to deploy and configure the CCIP contracts. env, err = commonchangeset.ApplyChangesets(t, env, timelocksPerChain, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureNewChains), Config: changeset.NewChainsConfig{ - HomeChainSel: homeChainSel, - FeedChainSel: feedSel, - ChainsToDeploy: allChains, - TokenConfig: tokenConfig, - OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), - OCRParams: ocrParams, - USDCConfig: changeset.USDCConfig{ - EnabledChains: usdcChains, - USDCAttestationConfig: usdcAttestationCfg, - CCTPTokenConfig: usdcCCTPConfig, - }, + HomeChainSel: homeChainSel, + FeedChainSel: feedSel, + OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + ChainConfigByChain: chainConfigs, }, }, { @@ -656,7 +657,7 @@ func FundNodes(t *testing.T, lggr zerolog.Logger, env *test_env.CLClusterTestEnv require.NoError(t, fundGrp.Wait(), "Error funding chainlink nodes") } -// CreateChainConfigFromNetworks creates a list of ChainConfig from the network config provided in test config. +// CreateChainConfigFromNetworks creates a list of CCIPOCRParams from the network config provided in test config. // It either creates it from the private ethereum networks created by the test environment or from the // network URLs provided in the network config ( if the network is a live testnet). // It uses the private keys from the network config to create the deployer key for each chain. From 4f6ccfb126cf8cca4a2aaa9bbf82f516b6745481 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Mon, 2 Dec 2024 15:32:27 -0500 Subject: [PATCH 2/3] Remove more --- deployment/ccip/changeset/add_chain_test.go | 7 +---- deployment/ccip/changeset/deploy.go | 6 +--- .../ccip/changeset/initial_add_chain.go | 29 ------------------- deployment/ccip/changeset/test_helpers.go | 7 +---- .../testsetups/ccip/test_helpers.go | 6 +--- 5 files changed, 4 insertions(+), 51 deletions(-) diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 40fc678a4d4..96727d0e4f8 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -64,12 +64,7 @@ func TestAddChainInbound(t *testing.T) { chainConfig := make(map[uint64]CCIPOCRParams) for _, chain := range initialDeploy { - ocrParams := DefaultOCRParams(e.FeedChainSel, nil, nil) - chainConfig[chain] = CCIPOCRParams{ - OCRParameters: ocrParams.OCRParameters, - CommitOffChainConfig: ocrParams.CommitOffChainConfig, - ExecuteOffChainConfig: ocrParams.ExecuteOffChainConfig, - } + chainConfig[chain] = DefaultOCRParams(e.FeedChainSel, nil, nil) } err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ HomeChainSel: e.HomeChainSel, diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index 7761e72526a..a07d291733a 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -400,11 +400,7 @@ func configureChain( chain, e.Chains[c.HomeChainSel], nodes.NonBootstraps(), - CCIPOCRParams{ - OCRParameters: chainConfig.OCRParameters, - CommitOffChainConfig: chainConfig.CommitOffChainConfig, - ExecuteOffChainConfig: chainConfig.ExecuteOffChainConfig, - }, + chainConfig, ); err != nil { e.Logger.Errorw("Failed to add DON", "err", err) return err diff --git a/deployment/ccip/changeset/initial_add_chain.go b/deployment/ccip/changeset/initial_add_chain.go index cc39e2b06e2..6e539c59637 100644 --- a/deployment/ccip/changeset/initial_add_chain.go +++ b/deployment/ccip/changeset/initial_add_chain.go @@ -39,35 +39,6 @@ func ConfigureNewChains(env deployment.Environment, c NewChainsConfig) (deployme }, 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 -} - -func (cfg USDCConfig) ToTokenDataObserverConfig() []pluginconfig.TokenDataObserverConfig { - return []pluginconfig.TokenDataObserverConfig{{ - Type: pluginconfig.USDCCCTPHandlerType, - Version: "1.0", - USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ - Tokens: cfg.CCTPTokenConfig, - AttestationAPI: cfg.API, - AttestationAPITimeout: cfg.APITimeout, - AttestationAPIInterval: cfg.APIInterval, - }, - }} -} -*/ - type USDCAttestationConfig struct { API string APITimeout *config.Duration diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 587f2b9136d..fa363e35a8a 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -357,12 +357,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, AttestationAPIInterval: usdcCfg.APIInterval, }}) } - ocrParams := DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) - chainConfigs[chain] = CCIPOCRParams{ - OCRParameters: ocrParams.OCRParameters, - CommitOffChainConfig: ocrParams.CommitOffChainConfig, - ExecuteOffChainConfig: ocrParams.ExecuteOffChainConfig, - } + chainConfigs[chain] = DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) } // Deploy second set of changesets to deploy and configure the CCIP contracts. e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ diff --git a/integration-tests/testsetups/ccip/test_helpers.go b/integration-tests/testsetups/ccip/test_helpers.go index 068827e6715..51ac6c6f743 100644 --- a/integration-tests/testsetups/ccip/test_helpers.go +++ b/integration-tests/testsetups/ccip/test_helpers.go @@ -232,11 +232,7 @@ func NewLocalDevEnvironment( if tCfg.OCRConfigOverride != nil { ocrParams = tCfg.OCRConfigOverride(ocrParams) } - chainConfigs[chain] = changeset.CCIPOCRParams{ - OCRParameters: ocrParams.OCRParameters, - CommitOffChainConfig: ocrParams.CommitOffChainConfig, - ExecuteOffChainConfig: ocrParams.ExecuteOffChainConfig, - } + chainConfigs[chain] = ocrParams } // Deploy second set of changesets to deploy and configure the CCIP contracts. From 95fbe8fa2e241247c518b9b4d32699a16ff08dc7 Mon Sep 17 00:00:00 2001 From: connorwstein Date: Mon, 2 Dec 2024 16:21:19 -0500 Subject: [PATCH 3/3] Further simplify and fix test --- .../ccip/changeset/initial_add_chain.go | 6 --- deployment/ccip/changeset/test_helpers.go | 40 ++++++++----------- .../testsetups/ccip/test_helpers.go | 38 ++++++++---------- 3 files changed, 33 insertions(+), 51 deletions(-) diff --git a/deployment/ccip/changeset/initial_add_chain.go b/deployment/ccip/changeset/initial_add_chain.go index 6e539c59637..d4aaa3ee859 100644 --- a/deployment/ccip/changeset/initial_add_chain.go +++ b/deployment/ccip/changeset/initial_add_chain.go @@ -39,12 +39,6 @@ func ConfigureNewChains(env deployment.Environment, c NewChainsConfig) (deployme }, nil } -type USDCAttestationConfig struct { - API string - APITimeout *config.Duration - APIInterval *config.Duration -} - type CCIPOCRParams struct { OCRParameters types.OCRParameters // Note contains pointers to Arb feeds for prices diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index fa363e35a8a..062af4e0117 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -321,18 +321,29 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, require.NotNil(t, state.Chains[e.FeedChainSel].Weth9) tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - var usdcCfg USDCAttestationConfig + var tokenDataProviders []pluginconfig.TokenDataObserverConfig if len(usdcChains) > 0 { server := mockAttestationResponse() endpoint := server.URL - usdcCfg = USDCAttestationConfig{ - API: endpoint, - APITimeout: commonconfig.MustNewDuration(time.Second), - APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), - } t.Cleanup(func() { server.Close() }) + cctpContracts := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) + for _, usdcChain := range usdcChains { + cctpContracts[cciptypes.ChainSelector(usdcChain)] = pluginconfig.USDCCCTPTokenConfig{ + SourcePoolAddress: state.Chains[usdcChain].USDCTokenPool.Address().String(), + SourceMessageTransmitterAddr: state.Chains[usdcChain].MockUSDCTransmitter.Address().String(), + } + } + tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ + Type: pluginconfig.USDCCCTPHandlerType, + Version: "1.0", + USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ + Tokens: cctpContracts, + AttestationAPI: endpoint, + AttestationAPITimeout: commonconfig.MustNewDuration(time.Second), + AttestationAPIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + }}) } // Build the per chain config. chainConfigs := make(map[uint64]CCIPOCRParams) @@ -340,23 +351,6 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, for _, chain := range allChains { timelocksPerChain[chain] = state.Chains[chain].Timelock tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) - var tokenDataProviders []pluginconfig.TokenDataObserverConfig - if len(usdcChains) > 0 { - tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ - Type: pluginconfig.USDCCCTPHandlerType, - Version: "1.0", - USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ - Tokens: map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig{ - cciptypes.ChainSelector(chain): { - SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), - SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), - }, - }, - AttestationAPI: usdcCfg.API, - AttestationAPITimeout: usdcCfg.APITimeout, - AttestationAPIInterval: usdcCfg.APIInterval, - }}) - } chainConfigs[chain] = DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) } // Deploy second set of changesets to deploy and configure the CCIP contracts. diff --git a/integration-tests/testsetups/ccip/test_helpers.go b/integration-tests/testsetups/ccip/test_helpers.go index 51ac6c6f743..8ffce77cc6b 100644 --- a/integration-tests/testsetups/ccip/test_helpers.go +++ b/integration-tests/testsetups/ccip/test_helpers.go @@ -191,17 +191,28 @@ func NewLocalDevEnvironment( state, err := changeset.LoadOnchainState(env) require.NoError(t, err) - var usdcCfg changeset.USDCAttestationConfig + var tokenDataProviders []pluginconfig.TokenDataObserverConfig if len(usdcChains) > 0 { var endpoint string err = ccipactions.SetMockServerWithUSDCAttestation(testEnv.MockAdapter, nil) require.NoError(t, err) endpoint = testEnv.MockAdapter.InternalEndpoint - usdcCfg = changeset.USDCAttestationConfig{ - API: endpoint, - APITimeout: commonconfig.MustNewDuration(time.Second), - APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + cctpContracts := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) + for _, usdcChain := range usdcChains { + cctpContracts[cciptypes.ChainSelector(usdcChain)] = pluginconfig.USDCCCTPTokenConfig{ + SourcePoolAddress: state.Chains[usdcChain].USDCTokenPool.Address().String(), + SourceMessageTransmitterAddr: state.Chains[usdcChain].MockUSDCTransmitter.Address().String(), + } } + tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ + Type: pluginconfig.USDCCCTPHandlerType, + Version: "1.0", + USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ + Tokens: cctpContracts, + AttestationAPI: endpoint, + AttestationAPITimeout: commonconfig.MustNewDuration(time.Second), + AttestationAPIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + }}) } // Build the per chain config. @@ -211,23 +222,6 @@ func NewLocalDevEnvironment( for _, chain := range allChains { timelocksPerChain[chain] = state.Chains[chain].Timelock tokenInfo := tokenConfig.GetTokenInfo(e.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) - var tokenDataProviders []pluginconfig.TokenDataObserverConfig - if len(usdcChains) > 0 { - tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ - Type: pluginconfig.USDCCCTPHandlerType, - Version: "1.0", - USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ - Tokens: map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig{ - cciptypes.ChainSelector(chain): { - SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), - SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), - }, - }, - AttestationAPI: usdcCfg.API, - AttestationAPITimeout: usdcCfg.APITimeout, - AttestationAPIInterval: usdcCfg.APIInterval, - }}) - } ocrParams := changeset.DefaultOCRParams(feedSel, tokenInfo, tokenDataProviders) if tCfg.OCRConfigOverride != nil { ocrParams = tCfg.OCRConfigOverride(ocrParams)