diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 2ac1cd90505..a3947c61f75 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -991,6 +991,106 @@ runner-test-matrix: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.4.0 + - id: smoke/ccip_rmn_test.go:^TestRMN_TwoMessagesOnTwoLanesIncludingBatching$ + path: integration-tests/smoke/ccip_rmn_test.go + test_env_type: docker + runs_on: ubuntu-latest + triggers: + - PR E2E Core Tests + - Merge Queue E2E Core Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/smoke && go test -test.run ^TestRMN_TwoMessagesOnTwoLanesIncludingBatching$ -timeout 12m -test.parallel=1 -count=1 -json + pyroscope_env: ci-smoke-ccipv1_6-evm-simulated + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + E2E_JD_VERSION: 0.4.0 + E2E_RMN_RAGEPROXY_VERSION: master-5208d09 + E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + + - id: smoke/ccip_rmn_test.go:^TestRMN_MultipleMessagesOnOneLaneNoWaitForExec$ + path: integration-tests/smoke/ccip_rmn_test.go + test_env_type: docker + runs_on: ubuntu-latest + triggers: + - PR E2E Core Tests + - Merge Queue E2E Core Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/smoke && go test -test.run ^TestRMN_MultipleMessagesOnOneLaneNoWaitForExec$ -timeout 12m -test.parallel=1 -count=1 -json + pyroscope_env: ci-smoke-ccipv1_6-evm-simulated + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + E2E_JD_VERSION: 0.4.0 + E2E_RMN_RAGEPROXY_VERSION: master-5208d09 + E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + +# Enable after flaking issue is resolved +# - id: smoke/ccip_rmn_test.go:^TestRMN_NotEnoughObservers$ +# path: integration-tests/smoke/ccip_rmn_test.go +# test_env_type: docker +# runs_on: ubuntu-latest +# triggers: +# - PR E2E Core Tests +# - Merge Queue E2E Core Tests +# - Nightly E2E Tests +# test_cmd: cd integration-tests/smoke && go test -test.run ^TestRMN_NotEnoughObservers$ -timeout 12m -test.parallel=1 -count=1 -json +# pyroscope_env: ci-smoke-ccipv1_6-evm-simulated +# test_env_vars: +# E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 +# E2E_JD_VERSION: 0.4.0 +# E2E_RMN_RAGEPROXY_VERSION: master-5208d09 +# E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + + - id: smoke/ccip_rmn_test.go:^TestRMN_DifferentSigners$ + path: integration-tests/smoke/ccip_rmn_test.go + test_env_type: docker + runs_on: ubuntu-latest + triggers: + - PR E2E Core Tests + - Merge Queue E2E Core Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/smoke && go test -test.run ^TestRMN_DifferentSigners$ -timeout 12m -test.parallel=1 -count=1 -json + pyroscope_env: ci-smoke-ccipv1_6-evm-simulated + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + E2E_JD_VERSION: 0.4.0 + E2E_RMN_RAGEPROXY_VERSION: master-5208d09 + E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + +# Enable after flaking issue is resolved +# - id: smoke/ccip_rmn_test.go:^TestRMN_NotEnoughSigners$ +# path: integration-tests/smoke/ccip_rmn_test.go +# test_env_type: docker +# runs_on: ubuntu-latest +# triggers: +# - PR E2E Core Tests +# - Merge Queue E2E Core Tests +# - Nightly E2E Tests +# test_cmd: cd integration-tests/smoke && go test -test.run ^TestRMN_NotEnoughSigners$ -timeout 12m -test.parallel=1 -count=1 -json +# pyroscope_env: ci-smoke-ccipv1_6-evm-simulated +# test_env_vars: +# E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 +# E2E_JD_VERSION: 0.4.0 +# E2E_RMN_RAGEPROXY_VERSION: master-5208d09 +# E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + + + - id: smoke/ccip_rmn_test.go:^TestRMN_DifferentRmnNodesForDifferentChains$ + path: integration-tests/smoke/ccip_rmn_test.go + test_env_type: docker + runs_on: ubuntu-latest + triggers: + - PR E2E Core Tests + - Merge Queue E2E Core Tests + - Nightly E2E Tests + test_cmd: cd integration-tests/smoke/ && go test -test.run ^TestRMN_DifferentRmnNodesForDifferentChains$ -timeout 12m -test.parallel=1 -count=1 -json + pyroscope_env: ci-smoke-ccipv1_6-evm-simulated + test_env_vars: + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + E2E_JD_VERSION: 0.4.0 + E2E_RMN_RAGEPROXY_VERSION: master-5208d09 + E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + + # END: CCIPv1.6 tests # START: CCIP tests diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 08383aed12d..1034a8fe834 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -210,7 +210,7 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'pull_request' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@27467f0073162e0ca77d33ce26f649b3d0f4c188 #ctf-run-tests@0.2.0 with: workflow_name: Run Core E2E Tests For PR chainlink_version: ${{ inputs.evm-ref || github.sha }} @@ -251,7 +251,7 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'merge_group' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@27467f0073162e0ca77d33ce26f649b3d0f4c188 #ctf-run-tests@1.0.0 with: workflow_name: Run Core E2E Tests For Merge Queue chainlink_version: ${{ inputs.evm-ref || github.sha }} diff --git a/deployment/ccip/changeset/deploy_chain.go b/deployment/ccip/changeset/deploy_chain.go new file mode 100644 index 00000000000..633d01bbf4c --- /dev/null +++ b/deployment/ccip/changeset/deploy_chain.go @@ -0,0 +1,43 @@ +package changeset + +import ( + "fmt" + + "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) + if err != nil { + env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "newAddresses", newAddresses) + return deployment.ChangesetOutput{AddressBook: newAddresses}, deployment.MaybeDataErr(err) + } + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{}, + AddressBook: newAddresses, + JobSpecs: nil, + }, nil +} + +type DeployChainContractsConfig struct { + ChainSelectors []uint64 + HomeChainSelector uint64 +} + +func (c DeployChainContractsConfig) Validate() error { + for _, cs := range c.ChainSelectors { + if err := deployment.IsValidChainSelector(cs); err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", cs, err) + } + } + if err := deployment.IsValidChainSelector(c.HomeChainSelector); err != nil { + return fmt.Errorf("invalid home chain selector: %d - %w", c.HomeChainSelector, err) + } + return nil +} diff --git a/deployment/ccip/changeset/deploy_chain_test.go b/deployment/ccip/changeset/deploy_chain_test.go new file mode 100644 index 00000000000..b197c90eca5 --- /dev/null +++ b/deployment/ccip/changeset/deploy_chain_test.go @@ -0,0 +1,78 @@ +package changeset + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment" + ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestDeployChainContractsChangeset(t *testing.T) { + lggr := logger.TestLogger(t) + e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Bootstraps: 1, + Chains: 2, + Nodes: 4, + }) + selectors := e.AllChainSelectors() + homeChainSel := selectors[0] + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + require.NoError(t, err) + p2pIds := nodes.NonBootstraps().PeerIDs() + // deploy home chain + homeChainCfg := DeployHomeChainConfig{ + HomeChainSel: homeChainSel, + RMNStaticConfig: ccdeploy.NewTestRMNStaticConfig(), + RMNDynamicConfig: ccdeploy.NewTestRMNDynamicConfig(), + NodeOperators: ccdeploy.NewTestNodeOperator(e.Chains[homeChainSel].DeployerKey.From), + NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ + "NodeOperator": p2pIds, + }, + } + output, err := DeployHomeChain(e, homeChainCfg) + require.NoError(t, err) + require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) + + // deploy pre-requisites + prerequisites, err := DeployPrerequisites(e, DeployPrerequisiteConfig{ + ChainSelectors: selectors, + }) + require.NoError(t, err) + require.NoError(t, e.ExistingAddresses.Merge(prerequisites.AddressBook)) + + // deploy ccip chain contracts + output, err = DeployChainContracts(e, DeployChainContractsConfig{ + ChainSelectors: selectors, + HomeChainSelector: homeChainSel, + MCMSCfg: ccdeploy.NewTestMCMSConfig(t, e), + }) + require.NoError(t, err) + require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook)) + + // load onchain state + state, err := ccdeploy.LoadOnchainState(e) + require.NoError(t, err) + + // verify all contracts populated + require.NotNil(t, state.Chains[homeChainSel].CapabilityRegistry) + require.NotNil(t, state.Chains[homeChainSel].CCIPHome) + require.NotNil(t, state.Chains[homeChainSel].RMNHome) + for _, sel := range selectors { + require.NotNil(t, state.Chains[sel].LinkToken) + require.NotNil(t, state.Chains[sel].Weth9) + require.NotNil(t, state.Chains[sel].TokenAdminRegistry) + require.NotNil(t, state.Chains[sel].RegistryModule) + require.NotNil(t, state.Chains[sel].Router) + require.NotNil(t, state.Chains[sel].RMNRemote) + require.NotNil(t, state.Chains[sel].TestRouter) + require.NotNil(t, state.Chains[sel].NonceManager) + require.NotNil(t, state.Chains[sel].FeeQuoter) + require.NotNil(t, state.Chains[sel].OffRamp) + require.NotNil(t, state.Chains[sel].OnRamp) + } +} diff --git a/deployment/ccip/changeset/home_chain.go b/deployment/ccip/changeset/home_chain.go index 0fabd2efb18..92b5b09c695 100644 --- a/deployment/ccip/changeset/home_chain.go +++ b/deployment/ccip/changeset/home_chain.go @@ -26,7 +26,9 @@ func DeployHomeChain(env deployment.Environment, cfg DeployHomeChainConfig) (dep _, err = ccipdeployment.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{}, err + return deployment.ChangesetOutput{ + AddressBook: ab, + }, err } return deployment.ChangesetOutput{ diff --git a/deployment/ccip/changeset/jobspec.go b/deployment/ccip/changeset/jobspec.go new file mode 100644 index 00000000000..76352ff364f --- /dev/null +++ b/deployment/ccip/changeset/jobspec.go @@ -0,0 +1,21 @@ +package changeset + +import ( + "github.com/pkg/errors" + "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) + if err != nil { + return deployment.ChangesetOutput{}, errors.Wrapf(err, "failed to create job specs") + } + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{}, + AddressBook: deployment.NewMemoryAddressBook(), + JobSpecs: js, + }, nil +} diff --git a/deployment/ccip/changeset/jobspec_test.go b/deployment/ccip/changeset/jobspec_test.go new file mode 100644 index 00000000000..4a10bdc2436 --- /dev/null +++ b/deployment/ccip/changeset/jobspec_test.go @@ -0,0 +1,35 @@ +package changeset + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + ccip "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestJobSpecChangeset(t *testing.T) { + lggr := logger.TestLogger(t) + e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + Nodes: 4, + }) + output, err := Jobspec(e, nil) + require.NoError(t, err) + require.NotNil(t, output.JobSpecs) + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + require.NoError(t, err) + for _, node := range nodes { + jobs, exists := output.JobSpecs[node.NodeID] + require.True(t, exists) + require.NotNil(t, jobs) + for _, job := range jobs { + _, err = ccip.ValidatedCCIPSpec(job) + require.NoError(t, err) + } + } +} diff --git a/deployment/ccip/changeset/prerequisites.go b/deployment/ccip/changeset/prerequisites.go index 7bead1cc05c..20ff7f5a935 100644 --- a/deployment/ccip/changeset/prerequisites.go +++ b/deployment/ccip/changeset/prerequisites.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" - chain_selectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/deployment" ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" @@ -27,7 +26,9 @@ func DeployPrerequisites(env deployment.Environment, cfg DeployPrerequisiteConfi err = ccipdeployment.DeployPrerequisiteChainContracts(env, ab, cfg.ChainSelectors) if err != nil { env.Logger.Errorw("Failed to deploy prerequisite contracts", "err", err, "addressBook", ab) - return deployment.ChangesetOutput{}, fmt.Errorf("failed to deploy prerequisite contracts: %w", err) + return deployment.ChangesetOutput{ + AddressBook: ab, + }, fmt.Errorf("failed to deploy prerequisite contracts: %w", err) } return deployment.ChangesetOutput{ Proposals: []timelock.MCMSWithTimelockProposal{}, @@ -45,14 +46,9 @@ type DeployPrerequisiteConfig struct { func (c DeployPrerequisiteConfig) Validate() error { for _, cs := range c.ChainSelectors { - if cs == 0 { - return fmt.Errorf("chain selector must be set") - } - _, err := chain_selectors.ChainIdFromSelector(cs) - if err != nil { + 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/save_existing.go b/deployment/ccip/changeset/save_existing.go index 8995fdf7f4c..76330a3a20a 100644 --- a/deployment/ccip/changeset/save_existing.go +++ b/deployment/ccip/changeset/save_existing.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" - chain_selectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/deployment" ) @@ -27,11 +26,7 @@ type ExistingContractsConfig struct { func (cfg ExistingContractsConfig) Validate() error { for _, ec := range cfg.ExistingContracts { - if ec.ChainSelector == 0 { - return fmt.Errorf("chain selectors must be set") - } - _, err := chain_selectors.ChainIdFromSelector(ec.ChainSelector) - if err != nil { + if err := deployment.IsValidChainSelector(ec.ChainSelector); err != nil { return fmt.Errorf("invalid chain selector: %d - %w", ec.ChainSelector, err) } if ec.Address == (common.Address{}) { diff --git a/deployment/ccip/deploy.go b/deployment/ccip/deploy.go index 5789044a609..0dea0a8b1f8 100644 --- a/deployment/ccip/deploy.go +++ b/deployment/ccip/deploy.go @@ -319,29 +319,11 @@ func DeployCCIPContracts( e.Logger.Errorw("Failed to get capability registry") return fmt.Errorf("capability registry not found") } - cr, err := capReg.GetHashedCapabilityId( - &bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion) - if err != nil { - e.Logger.Errorw("Failed to get hashed capability id", "err", err) - return err + ccipHome := existingState.Chains[c.HomeChainSel].CCIPHome + if ccipHome == nil { + e.Logger.Errorw("Failed to get ccip home", "err", err) + return fmt.Errorf("ccip home not found") } - 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, CCIPCapabilityID) - if err != nil { - e.Logger.Errorw("Failed to get capability", "err", err) - return err - } - ccipHome, err := ccip_home.NewCCIPHome(capability.ConfigurationContract, e.Chains[c.HomeChainSel].Client) - if err != nil { - e.Logger.Errorw("Failed to get ccip config", "err", err) - return err - } - if ccipHome.Address() != existingState.Chains[c.HomeChainSel].CCIPHome.Address() { - return fmt.Errorf("ccip home address mismatch") - } - rmnHome := existingState.Chains[c.HomeChainSel].RMNHome if rmnHome == nil { e.Logger.Errorw("Failed to get rmn home", "err", err) @@ -350,18 +332,10 @@ func DeployCCIPContracts( usdcConfiguration := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) for _, chainSel := range c.ChainsToDeploy { - chain, ok := e.Chains[chainSel] - if !ok { + chain, exists := e.Chains[chainSel] + if !exists { return fmt.Errorf("chain %d not found", chainSel) } - 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 { - return err - } - if c.USDCConfig.Enabled { token, pool, messenger, transmitter, err1 := DeployUSDC(e.Logger, chain, ab, existingState.Chains[chainSel]) if err1 != nil { @@ -381,10 +355,13 @@ func DeployCCIPContracts( } } } - + 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) @@ -444,6 +421,66 @@ func DeployCCIPContracts( return nil } +func DeployChainContractsForChains( + e deployment.Environment, + ab deployment.AddressBook, + homeChainSel uint64, + chainsToDeploy []uint64) error { + existingState, err := LoadOnchainState(e) + if err != nil { + e.Logger.Errorw("Failed to load existing onchain state", "err") + return err + } + + capReg := existingState.Chains[homeChainSel].CapabilityRegistry + if capReg == nil { + e.Logger.Errorw("Failed to get capability registry") + return fmt.Errorf("capability registry not found") + } + cr, err := capReg.GetHashedCapabilityId( + &bind.CallOpts{}, CapabilityLabelledName, 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[:])) + } + capability, err := capReg.GetCapability(nil, CCIPCapabilityID) + if err != nil { + e.Logger.Errorw("Failed to get capability", "err", err) + return err + } + ccipHome, err := ccip_home.NewCCIPHome(capability.ConfigurationContract, e.Chains[homeChainSel].Client) + if err != nil { + e.Logger.Errorw("Failed to get ccip config", "err", err) + return err + } + if ccipHome.Address() != existingState.Chains[homeChainSel].CCIPHome.Address() { + return fmt.Errorf("ccip home address mismatch") + } + rmnHome := existingState.Chains[homeChainSel].RMNHome + if rmnHome == nil { + e.Logger.Errorw("Failed to get rmn home", "err", err) + return fmt.Errorf("rmn home not found") + } + for _, chainSel := range chainsToDeploy { + chain, ok := e.Chains[chainSel] + if !ok { + return fmt.Errorf("chain %d not found", chainSel) + } + 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) + } + } + return nil +} + func DeployChainContracts( e deployment.Environment, chain deployment.Chain, diff --git a/deployment/ccip/deploy_test.go b/deployment/ccip/deploy_test.go index 424077827b3..8fa75b373f3 100644 --- a/deployment/ccip/deploy_test.go +++ b/deployment/ccip/deploy_test.go @@ -30,17 +30,3 @@ func TestDeployCCIPContracts(t *testing.T) { require.NoError(t, err) fmt.Println(string(b)) } - -func TestJobSpecGeneration(t *testing.T) { - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Chains: 1, - Nodes: 1, - }) - js, err := NewCCIPJobSpecs(e.NodeIDs, e.Offchain) - require.NoError(t, err) - for node, jb := range js { - fmt.Println(node, jb) - } - // TODO: Add job assertions -} diff --git a/deployment/environment/devenv/.sample.env b/deployment/environment/devenv/.sample.env index ddf0b97e9a9..8ab186e3044 100644 --- a/deployment/environment/devenv/.sample.env +++ b/deployment/environment/devenv/.sample.env @@ -7,6 +7,12 @@ E2E_JD_VERSION= E2E_TEST_CHAINLINK_IMAGE=public.ecr.aws/w0i8p0z9/chainlink-ccip E2E_TEST_CHAINLINK_VERSION=2.14.0-ccip1.5.0 +E2E_RMN_RAGEPROXY_IMAGE= +E2E_RMN_RAGEPROXY_VERSION=master-5208d09 +E2E_RMN_AFN2PROXY_IMAGE= +E2E_RMN_AFN2PROXY_VERSION=master-5208d09 + + # RPC Configuration E2E_TEST_SEPOLIA_WALLET_KEY= E2E_TEST_SEPOLIA_RPC_HTTP_URL_1= diff --git a/deployment/helpers.go b/deployment/helpers.go index 1f0dc3064d6..e8d2d8c8d59 100644 --- a/deployment/helpers.go +++ b/deployment/helpers.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/pkg/errors" + chain_selectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-common/pkg/logger" ) @@ -152,3 +153,14 @@ func DeployContract[C any]( } return &contractDeploy, nil } + +func IsValidChainSelector(cs uint64) error { + if cs == 0 { + return fmt.Errorf("chain selector must be set") + } + _, err := chain_selectors.ChainIdFromSelector(cs) + if err != nil { + return fmt.Errorf("invalid chain selector: %d - %w", cs, err) + } + return nil +} diff --git a/integration-tests/ccip-tests/testsetups/test_helpers.go b/integration-tests/ccip-tests/testsetups/test_helpers.go index fd9cfdb4a94..ea57f056945 100644 --- a/integration-tests/ccip-tests/testsetups/test_helpers.go +++ b/integration-tests/ccip-tests/testsetups/test_helpers.go @@ -21,12 +21,12 @@ 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/ccip/changeset" 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" "github.com/smartcontractkit/chainlink/deployment/environment/devenv" clclient "github.com/smartcontractkit/chainlink/deployment/environment/nodeclient" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -209,17 +209,18 @@ func NewLocalDevEnvironmentWithRMN( lggr logger.Logger, numRmnNodes int, ) (ccipdeployment.DeployedEnv, devenv.RMNCluster) { - tenv, dockerenv, _ := NewLocalDevEnvironmentWithDefaultPrice(t, lggr) + tenv, dockerenv, testCfg := NewLocalDevEnvironmentWithDefaultPrice(t, lggr) l := logging.GetTestLogger(t) config := GenerateTestRMNConfig(t, numRmnNodes, tenv, MustNetworksToRPCMap(dockerenv.EVMNetworks)) + require.NotNil(t, testCfg.CCIP) rmnCluster, err := devenv.NewRMNCluster( t, l, []string{dockerenv.DockerNetwork.ID}, config, - "rageproxy", - "latest", - "afn2proxy", - "latest", + testCfg.CCIP.RMNConfig.GetProxyImage(), + testCfg.CCIP.RMNConfig.GetProxyVersion(), + testCfg.CCIP.RMNConfig.GetAFN2ProxyImage(), + testCfg.CCIP.RMNConfig.GetAFN2ProxyVersion(), dockerenv.LogStream, ) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip_rmn_test.go b/integration-tests/smoke/ccip_rmn_test.go index a37b601e9d9..e8e81688239 100644 --- a/integration-tests/smoke/ccip_rmn_test.go +++ b/integration-tests/smoke/ccip_rmn_test.go @@ -16,6 +16,7 @@ import ( jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink/deployment" ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" @@ -26,9 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" ) -// Set false to run the RMN tests -const skipRmnTest = true - func TestRMN_TwoMessagesOnTwoLanesIncludingBatching(t *testing.T) { runRmnTestCase(t, rmnTestCase{ name: "messages on two lanes including batching", @@ -177,9 +175,6 @@ const ( ) func runRmnTestCase(t *testing.T, tc rmnTestCase) { - if skipRmnTest { - t.Skip("Local only") - } require.NoError(t, os.Setenv("ENABLE_RMN", "true")) envWithRMN, rmnCluster := testsetups.NewLocalDevEnvironmentWithRMN(t, logger.TestLogger(t), len(tc.rmnNodes)) diff --git a/integration-tests/testconfig/ccip/config.go b/integration-tests/testconfig/ccip/config.go index 560c816d85f..3ef746e29e3 100644 --- a/integration-tests/testconfig/ccip/config.go +++ b/integration-tests/testconfig/ccip/config.go @@ -15,12 +15,16 @@ import ( ) const ( - E2E_JD_IMAGE = "E2E_JD_IMAGE" - E2E_JD_VERSION = "E2E_JD_VERSION" - E2E_JD_GRPC = "E2E_JD_GRPC" - E2E_JD_WSRPC = "E2E_JD_WSRPC" - DEFAULT_DB_NAME = "JD_DB" - DEFAULT_DB_VERSION = "14.1" + E2E_JD_IMAGE = "E2E_JD_IMAGE" + E2E_JD_VERSION = "E2E_JD_VERSION" + E2E_JD_GRPC = "E2E_JD_GRPC" + E2E_JD_WSRPC = "E2E_JD_WSRPC" + DEFAULT_DB_NAME = "JD_DB" + DEFAULT_DB_VERSION = "14.1" + E2E_RMN_RAGEPROXY_IMAGE = "E2E_RMN_RAGEPROXY_IMAGE" + E2E_RMN_RAGEPROXY_VERSION = "E2E_RMN_RAGEPROXY_VERSION" + E2E_RMN_AFN2PROXY_IMAGE = "E2E_RMN_AFN2PROXY_IMAGE" + E2E_RMN_AFN2PROXY_VERSION = "E2E_RMN_AFN2PROXY_VERSION" ) var ( @@ -45,6 +49,38 @@ type RMNConfig struct { AFNVersion *string `toml:",omitempty"` } +func (r *RMNConfig) GetProxyImage() string { + image := pointer.GetString(r.ProxyImage) + if image == "" { + return ctfconfig.MustReadEnvVar_String(E2E_RMN_RAGEPROXY_IMAGE) + } + return image +} + +func (r *RMNConfig) GetProxyVersion() string { + version := pointer.GetString(r.ProxyVersion) + if version == "" { + return ctfconfig.MustReadEnvVar_String(E2E_RMN_RAGEPROXY_VERSION) + } + return version +} + +func (r *RMNConfig) GetAFN2ProxyImage() string { + image := pointer.GetString(r.AFNImage) + if image == "" { + return ctfconfig.MustReadEnvVar_String(E2E_RMN_AFN2PROXY_IMAGE) + } + return image +} + +func (r *RMNConfig) GetAFN2ProxyVersion() string { + version := pointer.GetString(r.AFNVersion) + if version == "" { + return ctfconfig.MustReadEnvVar_String(E2E_RMN_AFN2PROXY_VERSION) + } + return version +} + type NodeConfig struct { NoOfPluginNodes *int `toml:",omitempty"` NoOfBootstraps *int `toml:",omitempty"`