diff --git a/deployment/ccip/changeset/solana_v0_1_1/cs_deploy_chain_test.go b/deployment/ccip/changeset/solana_v0_1_1/cs_deploy_chain_test.go index c3b0ed4323d..db838bcccc5 100644 --- a/deployment/ccip/changeset/solana_v0_1_1/cs_deploy_chain_test.go +++ b/deployment/ccip/changeset/solana_v0_1_1/cs_deploy_chain_test.go @@ -5,33 +5,30 @@ import ( "testing" "time" + solBinary "github.com/gagliardetto/binary" "github.com/gagliardetto/solana-go" chain_selectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/quarantine" "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain" - - solBinary "github.com/gagliardetto/binary" - cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/environment" - "github.com/smartcontractkit/chainlink/deployment/ccip/shared" - "github.com/smartcontractkit/chainlink/deployment/ccip/shared/stateview" - "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" - "github.com/smartcontractkit/chainlink/deployment/common/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/globals" ccipChangesetSolana "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/solana_v0_1_1" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/testhelpers" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/v1_6" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" - "github.com/smartcontractkit/chainlink/v2/core/logger" - - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/globals" + "github.com/smartcontractkit/chainlink/deployment/ccip/shared" + "github.com/smartcontractkit/chainlink/deployment/ccip/shared/stateview" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" csState "github.com/smartcontractkit/chainlink/deployment/common/changeset/state" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/deployment/common/types" + "github.com/smartcontractkit/chainlink/deployment/internal/soltestutils" ) func initialDeployCS(t *testing.T, e cldf.Environment, buildConfig *ccipChangesetSolana.BuildSolanaConfig) []commonchangeset.ConfiguredChangeSet { @@ -109,21 +106,29 @@ func initialDeployCS(t *testing.T, e cldf.Environment, buildConfig *ccipChangese func TestDeployChainContractsChangesetPreload(t *testing.T) { quarantine.Flaky(t, "DX-1729") t.Parallel() - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 1, - SolChains: 1, - Nodes: 4, - }) - solChainSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilySolana)) - err := testhelpers.SavePreloadedSolAddresses(e, solChainSelectors[0]) + + homeChainSel := chain_selectors.TEST_90000001.Selector + solSelector := chain_selectors.TEST_22222222222222222222222222222222222222222222.Selector + programsPath := t.TempDir() + progIDs := soltestutils.LoadCCIPPrograms(t, programsPath) + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{homeChainSel}), + environment.WithSolanaContainer(t, []uint64{solSelector}, programsPath, progIDs), + environment.WithLogger(logger.Test(t)), + ) require.NoError(t, err) + testhelpers.RegisterNodes(t, env, 4, homeChainSel) + + err = testhelpers.SavePreloadedSolAddresses(*env, solSelector) + require.NoError(t, err) + + e := *env + // empty build config means, if artifacts are not present, resolve the artifact from github based on go.mod version // for a simple local in memory test, they will always be present, because we need them to spin up the in memory chain e, _, err = commonchangeset.ApplyChangesets(t, e, initialDeployCS(t, e, nil)) require.NoError(t, err) - err = testhelpers.ValidateSolanaState(e, solChainSelectors) + err = testhelpers.ValidateSolanaState(e, []uint64{solSelector}) require.NoError(t, err) } @@ -144,20 +149,24 @@ func TestUpgrade(t *testing.T) { t.Parallel() skipInCI(t) - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 1, - SolChains: 1, - Nodes: 4, - }) - evmSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilyEVM)) - homeChainSel := evmSelectors[0] - solChainSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilySolana)) - e, _, err := commonchangeset.ApplyChangesets(t, e, initialDeployCS(t, e, + homeChainSel := chain_selectors.TEST_90000001.Selector + solSelector := chain_selectors.TEST_22222222222222222222222222222222222222222222.Selector + programsPath := t.TempDir() + progIDs := soltestutils.LoadCCIPPrograms(t, programsPath) + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{homeChainSel}), + environment.WithSolanaContainer(t, []uint64{solSelector}, programsPath, progIDs), + environment.WithLogger(logger.Test(t)), + ) + require.NoError(t, err) + testhelpers.RegisterNodes(t, env, 4, homeChainSel) + + e := *env + + e, _, err = commonchangeset.ApplyChangesets(t, e, initialDeployCS(t, e, &ccipChangesetSolana.BuildSolanaConfig{ SolanaContractVersion: ccipChangesetSolana.VersionSolanaV0_1_1, - DestinationDir: e.BlockChains.SolanaChains()[solChainSelectors[0]].ProgramsPath, + DestinationDir: e.BlockChains.SolanaChains()[solSelector].ProgramsPath, LocalBuild: ccipChangesetSolana.LocalBuildConfig{ BuildLocally: true, CleanDestinationDir: true, @@ -166,7 +175,7 @@ func TestUpgrade(t *testing.T) { }, )) require.NoError(t, err) - err = testhelpers.ValidateSolanaState(e, solChainSelectors) + err = testhelpers.ValidateSolanaState(e, []uint64{solSelector}) require.NoError(t, err) feeAggregatorPrivKey2, _ := solana.NewRandomPrivateKey() @@ -181,7 +190,7 @@ func TestUpgrade(t *testing.T) { }, } - timelockSignerPDA, _ := testhelpers.TransferOwnershipSolanaV0_1_1(t, &e, solChainSelectors[0], true, + timelockSignerPDA, _ := testhelpers.TransferOwnershipSolanaV0_1_1(t, &e, solSelector, true, ccipChangesetSolana.CCIPContractsToTransfer{ Router: true, FeeQuoter: true, @@ -191,9 +200,9 @@ func TestUpgrade(t *testing.T) { // upgradeAuthority := e.BlockChains.SolanaChains()[solChainSelectors[0]].DeployerKey.PublicKey() state, err := stateview.LoadOnchainStateSolana(e) require.NoError(t, err) - addresses, err := e.ExistingAddresses.AddressesForChain(solChainSelectors[0]) + addresses, err := e.ExistingAddresses.AddressesForChain(solSelector) require.NoError(t, err) - chainState, err := csState.MaybeLoadMCMSWithTimelockChainStateSolana(e.BlockChains.SolanaChains()[solChainSelectors[0]], addresses) + chainState, err := csState.MaybeLoadMCMSWithTimelockChainStateSolana(e.BlockChains.SolanaChains()[solSelector], addresses) require.NoError(t, err) // deploy the contracts @@ -202,13 +211,13 @@ func TestUpgrade(t *testing.T) { commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.SetUpgradeAuthorityChangeset), ccipChangesetSolana.SetUpgradeAuthorityConfig{ - ChainSelector: solChainSelectors[0], + ChainSelector: solSelector, NewUpgradeAuthority: upgradeAuthority, SetAfterInitialDeploy: true, SetOffRamp: true, SetMCMSPrograms: true, TransferKeys: []solana.PublicKey{ - state.SolChains[solChainSelectors[0]].CCTPTokenPool, + state.SolChains[solSelector].CCTPTokenPool, }, }, ), @@ -217,7 +226,7 @@ func TestUpgrade(t *testing.T) { cldf.CreateLegacyChangeSet(ccipChangesetSolana.DeployChainContractsChangeset), ccipChangesetSolana.DeployChainContractsConfig{ HomeChainSelector: homeChainSel, - ChainSelector: solChainSelectors[0], + ChainSelector: solSelector, ContractParamsPerChain: contractParamsPerChain, UpgradeConfig: ccipChangesetSolana.UpgradeConfig{ NewFeeQuoterVersion: &deployment.Version1_1_0, @@ -239,22 +248,22 @@ func TestUpgrade(t *testing.T) { // build the contracts for upgrades BuildConfig: &ccipChangesetSolana.BuildSolanaConfig{ SolanaContractVersion: ccipChangesetSolana.VersionSolanaV0_1_1, - DestinationDir: e.BlockChains.SolanaChains()[solChainSelectors[0]].ProgramsPath, + DestinationDir: e.BlockChains.SolanaChains()[solSelector].ProgramsPath, LocalBuild: ccipChangesetSolana.LocalBuildConfig{ BuildLocally: true, CleanDestinationDir: true, CleanGitDir: true, UpgradeKeys: map[cldf.ContractType]string{ - shared.Router: state.SolChains[solChainSelectors[0]].Router.String(), - shared.FeeQuoter: state.SolChains[solChainSelectors[0]].FeeQuoter.String(), - shared.BurnMintTokenPool: state.SolChains[solChainSelectors[0]].BurnMintTokenPools[shared.CLLMetadata].String(), - shared.LockReleaseTokenPool: state.SolChains[solChainSelectors[0]].LockReleaseTokenPools[shared.CLLMetadata].String(), - shared.OffRamp: state.SolChains[solChainSelectors[0]].OffRamp.String(), + shared.Router: state.SolChains[solSelector].Router.String(), + shared.FeeQuoter: state.SolChains[solSelector].FeeQuoter.String(), + shared.BurnMintTokenPool: state.SolChains[solSelector].BurnMintTokenPools[shared.CLLMetadata].String(), + shared.LockReleaseTokenPool: state.SolChains[solSelector].LockReleaseTokenPools[shared.CLLMetadata].String(), + shared.OffRamp: state.SolChains[solSelector].OffRamp.String(), types.AccessControllerProgram: chainState.AccessControllerProgram.String(), types.RBACTimelockProgram: chainState.TimelockProgram.String(), types.ManyChainMultisigProgram: chainState.McmProgram.String(), - shared.RMNRemote: state.SolChains[solChainSelectors[0]].RMNRemote.String(), - shared.CCTPTokenPool: state.SolChains[solChainSelectors[0]].CCTPTokenPool.String(), + shared.RMNRemote: state.SolChains[solSelector].RMNRemote.String(), + shared.CCTPTokenPool: state.SolChains[solSelector].CCTPTokenPool.String(), }, }, }, @@ -263,7 +272,7 @@ func TestUpgrade(t *testing.T) { commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.SetFeeAggregator), ccipChangesetSolana.SetFeeAggregatorConfig{ - ChainSelector: solChainSelectors[0], + ChainSelector: solSelector, FeeAggregator: feeAggregatorPubKey2.String(), MCMS: &proposalutils.TimelockConfig{ MinDelay: 1 * time.Second, @@ -272,18 +281,18 @@ func TestUpgrade(t *testing.T) { ), }) require.NoError(t, err) - err = testhelpers.ValidateSolanaState(e, solChainSelectors) + err = testhelpers.ValidateSolanaState(e, []uint64{solSelector}) require.NoError(t, err) state, err = stateview.LoadOnchainStateSolana(e) require.NoError(t, err) - oldOffRampAddress := state.SolChains[solChainSelectors[0]].OffRamp + oldOffRampAddress := state.SolChains[solSelector].OffRamp // add a second offramp address e, _, err = commonchangeset.ApplyChangesets(t, e, []commonchangeset.ConfiguredChangeSet{ commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.DeployChainContractsChangeset), ccipChangesetSolana.DeployChainContractsConfig{ HomeChainSelector: homeChainSel, - ChainSelector: solChainSelectors[0], + ChainSelector: solSelector, ContractParamsPerChain: contractParamsPerChain, UpgradeConfig: ccipChangesetSolana.UpgradeConfig{ NewOffRampVersion: &deployment.Version1_1_0, @@ -294,7 +303,7 @@ func TestUpgrade(t *testing.T) { }, BuildConfig: &ccipChangesetSolana.BuildSolanaConfig{ SolanaContractVersion: ccipChangesetSolana.VersionSolanaV1_6_0, - DestinationDir: e.BlockChains.SolanaChains()[solChainSelectors[0]].ProgramsPath, + DestinationDir: e.BlockChains.SolanaChains()[solSelector].ProgramsPath, LocalBuild: ccipChangesetSolana.LocalBuildConfig{ BuildLocally: true, }, @@ -306,12 +315,12 @@ func TestUpgrade(t *testing.T) { // verify the offramp address is different state, err = stateview.LoadOnchainStateSolana(e) require.NoError(t, err) - newOffRampAddress := state.SolChains[solChainSelectors[0]].OffRamp + newOffRampAddress := state.SolChains[solSelector].OffRamp require.NotEqual(t, oldOffRampAddress, newOffRampAddress) // Verify router and fee quoter upgraded in place // and offramp had 2nd address added - addresses, err = e.ExistingAddresses.AddressesForChain(solChainSelectors[0]) + addresses, err = e.ExistingAddresses.AddressesForChain(solSelector) require.NoError(t, err) numRouters := 0 numFeeQuoters := 0 @@ -332,7 +341,7 @@ func TestUpgrade(t *testing.T) { require.Equal(t, 2, numOffRamps) require.NoError(t, err) // solana verification - err = testhelpers.ValidateSolanaState(e, solChainSelectors) + err = testhelpers.ValidateSolanaState(e, []uint64{solSelector}) require.NoError(t, err) } @@ -340,18 +349,24 @@ func TestClose(t *testing.T) { t.Parallel() skipInCI(t) - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 1, - SolChains: 1, - Nodes: 4, - }) - solChainSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilySolana)) - e, _, err := commonchangeset.ApplyChangesets(t, e, initialDeployCS(t, e, + homeChainSel := chain_selectors.TEST_90000001.Selector + solSelector := chain_selectors.TEST_22222222222222222222222222222222222222222222.Selector + programsPath := t.TempDir() + progIDs := soltestutils.LoadCCIPPrograms(t, programsPath) + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{homeChainSel}), + environment.WithSolanaContainer(t, []uint64{solSelector}, programsPath, progIDs), + environment.WithLogger(logger.Test(t)), + ) + require.NoError(t, err) + testhelpers.RegisterNodes(t, env, 4, homeChainSel) + + e := *env + + e, _, err = commonchangeset.ApplyChangesets(t, e, initialDeployCS(t, e, &ccipChangesetSolana.BuildSolanaConfig{ SolanaContractVersion: ccipChangesetSolana.VersionSolanaV1_6_0, - DestinationDir: e.BlockChains.SolanaChains()[solChainSelectors[0]].ProgramsPath, + DestinationDir: e.BlockChains.SolanaChains()[solSelector].ProgramsPath, LocalBuild: ccipChangesetSolana.LocalBuildConfig{ BuildLocally: true, CleanDestinationDir: true, @@ -360,9 +375,9 @@ func TestClose(t *testing.T) { }, )) require.NoError(t, err) - err = testhelpers.ValidateSolanaState(e, solChainSelectors) + err = testhelpers.ValidateSolanaState(e, []uint64{solSelector}) require.NoError(t, err) - timelockSignerPDA, _ := testhelpers.TransferOwnershipSolanaV0_1_1(t, &e, solChainSelectors[0], true, + timelockSignerPDA, _ := testhelpers.TransferOwnershipSolanaV0_1_1(t, &e, solSelector, true, ccipChangesetSolana.CCIPContractsToTransfer{ OffRamp: true, }) @@ -375,10 +390,10 @@ func TestClose(t *testing.T) { commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.CloseBuffersChangeset), ccipChangesetSolana.CloseBuffersConfig{ - ChainSelector: solChainSelectors[0], + ChainSelector: solSelector, Programs: []string{ - state.SolChains[solChainSelectors[0]].BurnMintTokenPools[shared.CLLMetadata].String(), - state.SolChains[solChainSelectors[0]].Router.String(), + state.SolChains[solSelector].BurnMintTokenPools[shared.CLLMetadata].String(), + state.SolChains[solSelector].Router.String(), }, }, ), @@ -386,7 +401,7 @@ func TestClose(t *testing.T) { commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.SetUpgradeAuthorityChangeset), ccipChangesetSolana.SetUpgradeAuthorityConfig{ - ChainSelector: solChainSelectors[0], + ChainSelector: solSelector, NewUpgradeAuthority: timelockSignerPDA, SetOffRamp: true, }, @@ -394,12 +409,12 @@ func TestClose(t *testing.T) { commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.CloseBuffersChangeset), ccipChangesetSolana.CloseBuffersConfig{ - ChainSelector: solChainSelectors[0], + ChainSelector: solSelector, MCMS: &proposalutils.TimelockConfig{ MinDelay: 1 * time.Second, }, Programs: []string{ - state.SolChains[solChainSelectors[0]].OffRamp.String(), + state.SolChains[solSelector].OffRamp.String(), }, }, ), diff --git a/deployment/ccip/changeset/solana_v0_1_1/transfer_ccip_to_mcms_with_timelock_test.go b/deployment/ccip/changeset/solana_v0_1_1/transfer_ccip_to_mcms_with_timelock_test.go index 60b08a6f9a4..ef1c7d8af0a 100644 --- a/deployment/ccip/changeset/solana_v0_1_1/transfer_ccip_to_mcms_with_timelock_test.go +++ b/deployment/ccip/changeset/solana_v0_1_1/transfer_ccip_to_mcms_with_timelock_test.go @@ -10,7 +10,6 @@ import ( "github.com/gagliardetto/solana-go" chainselectors "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-ccip/chains/solana/contracts/tests/testutils" burnmint "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/v0_1_1/burnmint_token_pool" @@ -38,7 +37,7 @@ import ( commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/deployment/internal/soltestutils" ) func TestValidateContracts(t *testing.T) { @@ -193,26 +192,33 @@ func TestValidate(t *testing.T) { // the transfer ownership changeset. func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, stateview.CCIPOnChainState) { t.Helper() - lggr := logger.Test(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 2, - SolChains: 1, - Nodes: 4, - CCIPSolanaContractVersion: memory.SolanaContractV0_1_1, - }) - evmSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chainselectors.FamilyEVM)) - homeChainSel := evmSelectors[0] - solChainSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chainselectors.FamilySolana)) - solChain1 := solChainSelectors[0] - solChain := e.BlockChains.SolanaChains()[solChain1] - nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + + homeChainSel := chainselectors.TEST_90000001.Selector + solChainSel := chainselectors.TEST_22222222222222222222222222222222222222222222.Selector + + programsPath := t.TempDir() + progIDs := soltestutils.LoadCCIPPrograms(t, programsPath) + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{homeChainSel}), + environment.WithSolanaContainer(t, []uint64{solChainSel}, programsPath, progIDs), + environment.WithLogger(logger.Test(t)), + ) + require.NoError(t, err) + + testhelpers.RegisterNodes(t, env, 4, homeChainSel) + + solChain := env.BlockChains.SolanaChains()[solChainSel] + nodes, err := deployment.NodeInfo(env.NodeIDs, env.Offchain) require.NoError(t, err) + // Fund account for fees - testutils.FundAccounts(e.GetContext(), []solana.PrivateKey{*solChain.DeployerKey}, solChain.Client, t) - err = testhelpers.SavePreloadedSolAddresses(e, solChainSelectors[0]) + testutils.FundAccounts(env.GetContext(), []solana.PrivateKey{*solChain.DeployerKey}, solChain.Client, t) + err = testhelpers.SavePreloadedSolAddresses(*env, solChainSel) require.NoError(t, err) solLinkTokenPrivKey, _ := solana.NewRandomPrivateKey() + + e := *env + e, _, err = commonchangeset.ApplyChangesets(t, e, []commonchangeset.ConfiguredChangeSet{ commonchangeset.Configure( cldf.CreateLegacyChangeSet(v1_6.DeployHomeChainChangeset), @@ -229,7 +235,7 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta commonchangeset.Configure( cldf.CreateLegacyChangeSet(commonchangeset.DeploySolanaLinkToken), commonchangeset.DeploySolanaLinkTokenConfig{ - ChainSelector: solChain1, + ChainSelector: solChainSel, TokenPrivKey: solLinkTokenPrivKey, TokenDecimals: 9, }, @@ -238,7 +244,7 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta cldf.CreateLegacyChangeSet(ccipChangesetSolana.DeployChainContractsChangeset), ccipChangesetSolana.DeployChainContractsConfig{ HomeChainSelector: homeChainSel, - ChainSelector: solChain1, + ChainSelector: solChainSel, ContractParamsPerChain: ccipChangesetSolana.ChainContractParams{ FeeQuoterParams: ccipChangesetSolana.FeeQuoterParams{ DefaultMaxFeeJuelsPerMsg: solBinary.Uint128{Lo: 300000000, Hi: 0, Endianness: nil}, @@ -252,7 +258,7 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.DeploySolanaToken), ccipChangesetSolana.DeploySolanaTokenConfig{ - ChainSelector: solChain1, + ChainSelector: solChainSel, TokenProgramName: shared.SPL2022Tokens, TokenDecimals: 9, }, @@ -260,7 +266,7 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.DeploySolanaToken), ccipChangesetSolana.DeploySolanaTokenConfig{ - ChainSelector: solChain1, + ChainSelector: solChainSel, TokenProgramName: shared.SPLTokens, TokenDecimals: 9, }, @@ -268,7 +274,7 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta commonchangeset.Configure( cldf.CreateLegacyChangeSet(commonchangeset.DeployMCMSWithTimelockV2), map[uint64]commontypes.MCMSWithTimelockConfigV2{ - solChain1: { + solChainSel: { Canceller: proposalutils.SingleGroupMCMSV2(t), Proposer: proposalutils.SingleGroupMCMSV2(t), Bypasser: proposalutils.SingleGroupMCMSV2(t), @@ -280,18 +286,18 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta require.NoError(t, err) // solana verification - err = testhelpers.ValidateSolanaState(e, solChainSelectors) + err = testhelpers.ValidateSolanaState(e, []uint64{solChainSel}) require.NoError(t, err) state, err := stateview.LoadOnchainStateSolana(e) require.NoError(t, err) - tokenAddressLockRelease := state.SolChains[solChain1].SPL2022Tokens[0] - tokenAddressBurnMint := state.SolChains[solChain1].SPLTokens[0] + tokenAddressLockRelease := state.SolChains[solChainSel].SPL2022Tokens[0] + tokenAddressBurnMint := state.SolChains[solChainSel].SPLTokens[0] e, _, err = commonchangeset.ApplyChangesets(t, e, []commonchangeset.ConfiguredChangeSet{ commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.InitGlobalConfigTokenPoolProgram), ccipChangesetSolana.TokenPoolConfigWithMCM{ - ChainSelector: solChain1, + ChainSelector: solChainSel, TokenPoolConfigs: []ccipChangesetSolana.TokenPoolConfig{ { TokenPubKey: tokenAddressLockRelease, @@ -309,7 +315,7 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.AddTokenPoolAndLookupTable), ccipChangesetSolana.AddTokenPoolAndLookupTableConfig{ - ChainSelector: solChain1, + ChainSelector: solChainSel, TokenPoolConfigs: []ccipChangesetSolana.TokenPoolConfig{ { TokenPubKey: tokenAddressLockRelease, @@ -322,7 +328,7 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta commonchangeset.Configure( cldf.CreateLegacyChangeSet(ccipChangesetSolana.AddTokenPoolAndLookupTable), ccipChangesetSolana.AddTokenPoolAndLookupTableConfig{ - ChainSelector: solChain1, + ChainSelector: solChainSel, TokenPoolConfigs: []ccipChangesetSolana.TokenPoolConfig{ { TokenPubKey: tokenAddressBurnMint, @@ -340,19 +346,21 @@ func prepareEnvironmentForOwnershipTransfer(t *testing.T) (cldf.Environment, sta func TestTransferCCIPToMCMSWithTimelockSolana(t *testing.T) { t.Parallel() skipInCI(t) + e, state := prepareEnvironmentForOwnershipTransfer(t) - solChain1 := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chainselectors.FamilySolana))[0] - solChain := e.BlockChains.SolanaChains()[solChain1] + solSelector := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chainselectors.FamilySolana))[0] + solChain := e.BlockChains.SolanaChains()[solSelector] + solState := state.SolChains[solSelector] - tokenAddressLockRelease := state.SolChains[solChain1].SPL2022Tokens[0] - tokenAddressBurnMint := state.SolChains[solChain1].SPLTokens[0] + tokenAddressLockRelease := solState.SPL2022Tokens[0] + tokenAddressBurnMint := solState.SPLTokens[0] - burnMintPoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressBurnMint, state.SolChains[solChain1].BurnMintTokenPools[shared.CLLMetadata]) - lockReleasePoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressLockRelease, state.SolChains[solChain1].LockReleaseTokenPools[shared.CLLMetadata]) + burnMintPoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressBurnMint, solState.BurnMintTokenPools[shared.CLLMetadata]) + lockReleasePoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressLockRelease, solState.LockReleaseTokenPools[shared.CLLMetadata]) timelockSignerPDA, _ := testhelpers.TransferOwnershipSolanaV0_1_1( t, &e, - solChain1, + solSelector, false, ccipChangesetSolana.CCIPContractsToTransfer{ Router: true, @@ -370,7 +378,7 @@ func TestTransferCCIPToMCMSWithTimelockSolana(t *testing.T) { // (A) Check Router ownership - we need to add retries as the ownership transfer commitment is confirmed and not finalized. require.Eventually(t, func() bool { - routerConfigPDA := state.SolChains[solChain1].RouterConfigPDA + routerConfigPDA := solState.RouterConfigPDA t.Logf("Checking Router Config PDA ownership data configPDA: %s", routerConfigPDA.String()) programData := ccip_router.Config{} err := solChain.GetAccountDataBorshInto(ctx, routerConfigPDA, &programData) @@ -380,7 +388,7 @@ func TestTransferCCIPToMCMSWithTimelockSolana(t *testing.T) { // (B) Check FeeQuoter ownership require.Eventually(t, func() bool { - feeQuoterConfigPDA := state.SolChains[solChain1].FeeQuoterConfigPDA + feeQuoterConfigPDA := solState.FeeQuoterConfigPDA t.Logf("Checking Fee Quoter PDA ownership data configPDA: %s", feeQuoterConfigPDA.String()) programData := fee_quoter.Config{} err := solChain.GetAccountDataBorshInto(ctx, feeQuoterConfigPDA, &programData) @@ -390,7 +398,7 @@ func TestTransferCCIPToMCMSWithTimelockSolana(t *testing.T) { // (C) Check OffRamp: require.Eventually(t, func() bool { - offRampConfigPDA := state.SolChains[solChain1].OffRampConfigPDA + offRampConfigPDA := solState.OffRampConfigPDA programData := ccip_offramp.Config{} t.Logf("Checking Off Ramp PDA ownership data configPDA: %s", offRampConfigPDA.String()) err := solChain.GetAccountDataBorshInto(ctx, offRampConfigPDA, &programData) @@ -418,7 +426,7 @@ func TestTransferCCIPToMCMSWithTimelockSolana(t *testing.T) { // (F) Check RMNRemote ownership require.Eventually(t, func() bool { - rmnRemoteConfigPDA := state.SolChains[solChain1].RMNRemoteConfigPDA + rmnRemoteConfigPDA := solState.RMNRemoteConfigPDA t.Logf("Checking RMNRemote PDA ownership data configPDA: %s", rmnRemoteConfigPDA.String()) programData := rmn_remote.Config{} err := solChain.GetAccountDataBorshInto(ctx, rmnRemoteConfigPDA, &programData) @@ -430,19 +438,21 @@ func TestTransferCCIPToMCMSWithTimelockSolana(t *testing.T) { func TestTransferCCIPFromMCMSWithTimelockSolana(t *testing.T) { t.Parallel() skipInCI(t) + e, state := prepareEnvironmentForOwnershipTransfer(t) - solChain1 := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chainselectors.FamilySolana))[0] - solChain := e.BlockChains.SolanaChains()[solChain1] + solSelector := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chainselectors.FamilySolana))[0] + solChain := e.BlockChains.SolanaChains()[solSelector] + solState := state.SolChains[solSelector] - tokenAddressLockRelease := state.SolChains[solChain1].SPL2022Tokens[0] - tokenAddressBurnMint := state.SolChains[solChain1].SPLTokens[0] + tokenAddressLockRelease := solState.SPL2022Tokens[0] + tokenAddressBurnMint := solState.SPLTokens[0] - burnMintPoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressBurnMint, state.SolChains[solChain1].BurnMintTokenPools[shared.CLLMetadata]) - lockReleasePoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressLockRelease, state.SolChains[solChain1].LockReleaseTokenPools[shared.CLLMetadata]) + burnMintPoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressBurnMint, solState.BurnMintTokenPools[shared.CLLMetadata]) + lockReleasePoolConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenAddressLockRelease, solState.LockReleaseTokenPools[shared.CLLMetadata]) timelockSignerPDA, _ := testhelpers.TransferOwnershipSolanaV0_1_1( t, &e, - solChain1, + solSelector, false, ccipChangesetSolana.CCIPContractsToTransfer{ Router: true, @@ -461,7 +471,7 @@ func TestTransferCCIPFromMCMSWithTimelockSolana(t *testing.T) { CurrentOwner: timelockSignerPDA, ProposedOwner: solChain.DeployerKey.PublicKey(), ContractsByChain: map[uint64]ccipChangesetSolana.CCIPContractsToTransfer{ - solChain1: { + solSelector: { Router: true, FeeQuoter: true, OffRamp: true, @@ -476,7 +486,7 @@ func TestTransferCCIPFromMCMSWithTimelockSolana(t *testing.T) { require.NoError(t, err) // we have to accept separate from the changeset because the proposal needs to execute // just spot check that the ownership transfer happened - config := state.SolChains[solChain1].RouterConfigPDA + config := state.SolChains[solSelector].RouterConfigPDA ix, err := ccip_router.NewAcceptOwnershipInstruction( config, solChain.DeployerKey.PublicKey(), ).ValidateAndBuild() diff --git a/deployment/ccip/changeset/testhelpers/test_environment.go b/deployment/ccip/changeset/testhelpers/test_environment.go index 734d3c65e83..5c24dcd5b94 100644 --- a/deployment/ccip/changeset/testhelpers/test_environment.go +++ b/deployment/ccip/changeset/testhelpers/test_environment.go @@ -5,7 +5,6 @@ import ( "encoding/json" "errors" "fmt" - "maps" "math/big" "math/rand" "net/http" @@ -18,32 +17,35 @@ import ( "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/gagliardetto/solana-go" + solBinary "github.com/gagliardetto/binary" solanago "github.com/gagliardetto/solana-go" + chain_selectors "github.com/smartcontractkit/chain-selectors" + mcmstypes "github.com/smartcontractkit/mcms/types" + "github.com/stretchr/testify/require" + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/tlb" + "go.uber.org/zap/zapcore" ops "github.com/smartcontractkit/chainlink-ton/deployment/ccip" tonOperation "github.com/smartcontractkit/chainlink-ton/deployment/ccip/operation" + "github.com/smartcontractkit/chainlink-ton/deployment/utils" - chain_selectors "github.com/smartcontractkit/chain-selectors" - mcmstypes "github.com/smartcontractkit/mcms/types" - + cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain" cldf_aptos "github.com/smartcontractkit/chainlink-deployments-framework/chain/aptos" + cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" cldf_evm_provider "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm/provider" cldf_solana "github.com/smartcontractkit/chainlink-deployments-framework/chain/solana" + cldf_sui "github.com/smartcontractkit/chainlink-deployments-framework/chain/sui" cldf_ton "github.com/smartcontractkit/chainlink-deployments-framework/chain/ton" - - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" + cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/environment" + "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/onchain" + simjd "github.com/smartcontractkit/chainlink-deployments-framework/offchain/jd/memory" "github.com/smartcontractkit/chainlink-common/pkg/logger" + nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain" - - cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" - cldf_sui "github.com/smartcontractkit/chainlink-deployments-framework/chain/sui" - cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" - sui_cs "github.com/smartcontractkit/chainlink-sui/deployment/changesets" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" aptoscs "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/aptos" @@ -54,19 +56,18 @@ import ( ccipseq "github.com/smartcontractkit/chainlink/deployment/ccip/sequence/evm/v1_6" "github.com/smartcontractkit/chainlink/deployment/ccip/shared" "github.com/smartcontractkit/chainlink/deployment/ccip/shared/stateview" + "github.com/smartcontractkit/chainlink/deployment/internal/jdtestutils" + "github.com/smartcontractkit/chainlink/deployment/internal/soltestutils" + "github.com/smartcontractkit/chainlink/deployment/internal/tontestutils" "github.com/smartcontractkit/chainlink/deployment/utils/nodetestutils" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" ccipocr3common "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" - solBinary "github.com/gagliardetto/binary" - + "github.com/smartcontractkit/chainlink-ccip/chainconfig" + fee_quoterV1_6_3 "github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_6_3/fee_quoter" solFeeQuoterV0_1_0 "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/v0_1_0/fee_quoter" solFeeQuoterV0_1_1 "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/v0_1_1/fee_quoter" - - fee_quoterV1_6_3 "github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_6_3/fee_quoter" - - "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/execute/tokendata/lbtc" cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" @@ -80,8 +81,8 @@ import ( opsutil "github.com/smartcontractkit/chainlink/deployment/common/opsutils" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) const ( @@ -90,6 +91,10 @@ const ( DefaultDAGasPriceDeviationPPB = 1000 ) +var ( + tonDeployerFundAmount = tlb.MustFromTON("1000") +) + type EnvType string const ( @@ -116,8 +121,8 @@ type TestConfigs struct { AptosChains int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input SuiChains int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input TonChains int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input - ChainIDs []uint64 // only used in memory mode, for docker mode, this is determined by the integration-test config toml input - NumOfUsersPerChain int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input + EVMChainsBySelectors []uint64 // only used in memory mode, for docker mode, this is determined by the integration-test config toml input + NumOfUsersPerChain uint // only used in memory mode, for docker mode, this is determined by the integration-test config toml input Nodes int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input Bootstraps int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input IsUSDC bool @@ -267,9 +272,9 @@ func WithPrerequisiteDeploymentOnly(v1_5Cfg *changeset.V1_5DeploymentConfig) Tes } } -func WithChainIDs(chainIDs []uint64) TestOps { +func WithEVMChainsBySelectors(selectors []uint64) TestOps { return func(testCfg *TestConfigs) { - testCfg.ChainIDs = chainIDs + testCfg.EVMChainsBySelectors = selectors } } @@ -354,7 +359,7 @@ func WithTonChains(numChains int) TestOps { } } -func WithNumOfUsersPerChain(numUsers int) TestOps { +func WithNumOfUsersPerChain(numUsers uint) TestOps { return func(testCfg *TestConfigs) { testCfg.NumOfUsersPerChain = numUsers } @@ -432,89 +437,65 @@ func (m *MemoryEnvironment) UpdateDeployedEnvironment(env DeployedEnv) { func (m *MemoryEnvironment) StartChains(t *testing.T) { ctx := testcontext.Get(t) tc := m.TestConfig - var chains map[uint64]cldf_evm.Chain - var users map[uint64][]*bind.TransactOpts - if len(tc.ChainIDs) > 0 { - chains = cldf_chain.NewBlockChainsFromSlice( - memory.NewMemoryChainsEVMWithChainIDs(t, tc.ChainIDs, tc.NumOfUsersPerChain), - ).EVMChains() - users = usersMap(t, chains) - - if tc.Chains > len(tc.ChainIDs) { - additionalChains := cldf_chain.NewBlockChainsFromSlice( - memory.NewMemoryChainsEVM(t, tc.Chains-len(tc.ChainIDs), tc.NumOfUsersPerChain), - ) - - maps.Copy(chains, additionalChains.EVMChains()) - - additionalUsers := usersMap(t, chains) - maps.Copy(users, additionalUsers) - } - } else { - chains = cldf_chain.NewBlockChainsFromSlice( - memory.NewMemoryChainsEVM(t, tc.Chains, tc.NumOfUsersPerChain), - ).EVMChains() - users = usersMap(t, chains) - } - - m.Chains = chains - var commitSha string - - ccipContractVersion := m.TestConfig.CCIPSolanaContractVersion - if ccipContractVersion == ccipChangeSetSolanaV0_1_1.SolanaContractV0_1_1 { - commitSha = ccipChangeSetSolanaV0_1_1.ContractVersionShortSha[ccipContractVersion] - } else { - commitSha = "" + loadOpts := []environment.LoadOpt{ + environment.WithAptosContainerN(t, tc.AptosChains), + environment.WithSuiContainerN(t, tc.SuiChains), + environment.WithTonContainerN(t, tc.TonChains), + environment.WithLogger(logger.Test(t)), } - solChains := memory.NewMemoryChainsSol(t, tc.SolChains, commitSha) - - aptosChains := memory.NewMemoryChainsAptos(t, tc.AptosChains) - suiChains := memory.NewMemoryChainsSui(t, tc.SuiChains) - tonChains := memory.NewMemoryChainsTon(t, tc.TonChains) - // if we have Aptos and Solana chains, we need to set their chain selectors on the wrapper - // environment, so we have to convert it back to the concrete type. This needs to be refactored - m.AptosChains = cldf_chain.NewBlockChainsFromSlice(aptosChains).AptosChains() - m.SolChains = cldf_chain.NewBlockChainsFromSlice(solChains).SolanaChains() - m.TonChains = cldf_chain.NewBlockChainsFromSlice(tonChains).TonChains() - m.SuiChains = cldf_chain.NewBlockChainsFromSlice(suiChains).SuiChains() - - blockChains := map[uint64]cldf_chain.BlockChain{} - for selector, ch := range m.Chains { - blockChains[selector] = ch + // We have to handle EVM a bit differently because there are two different ways to load EVM chains: + // 1. With chain IDs + // 2. With number of chains + evmLoadConfig := onchain.EVMSimLoaderConfig{ + NumAdditionalAccounts: tc.NumOfUsersPerChain, } - for selector, ch := range m.SolChains { - blockChains[selector] = ch - } - for _, ch := range aptosChains { - blockChains[ch.ChainSelector()] = ch - } - for selector, ch := range m.TonChains { - blockChains[selector] = ch + if len(tc.EVMChainsBySelectors) > 0 { + loadOpts = append(loadOpts, environment.WithEVMSimulatedWithConfig(t, tc.EVMChainsBySelectors, evmLoadConfig)) + } else { + loadOpts = append(loadOpts, environment.WithEVMSimulatedWithConfigN(t, tc.Chains, evmLoadConfig)) } - for selector, ch := range m.SuiChains { - blockChains[selector] = ch + // We handle Solana differently as well since we need to download programs from their repositories + if tc.SolChains > 0 { + programsPath := t.TempDir() + progIDs := soltestutils.LoadCCIPPrograms(t, programsPath) + loadOpts = append(loadOpts, environment.WithSolanaContainerN(t, tc.SolChains, programsPath, progIDs)) } - env := cldf.Environment{ - BlockChains: cldf_chain.NewBlockChains(blockChains), - } - homeChainSel, feedSel := allocateCCIPChainSelectors(chains) - replayBlocks, err := LatestBlocksByChain(ctx, env) + env, err := environment.New(t.Context(), loadOpts...) + require.NoError(t, err) + + // We need to set the concrete chains on the wrapper environment + m.Chains = env.BlockChains.EVMChains() + m.AptosChains = env.BlockChains.AptosChains() + m.SolChains = env.BlockChains.SolanaChains() + m.TonChains = env.BlockChains.TonChains() + m.SuiChains = env.BlockChains.SuiChains() + + homeChainSel, feedSel := allocateCCIPChainSelectors(m.Chains) + replayBlocks, err := LatestBlocksByChain(ctx, *env) require.NoError(t, err) // Aptos doesn't support replaying blocks for selector := range env.BlockChains.AptosChains() { delete(replayBlocks, selector) } + + // Ton chains must be funded if they exist + if len(env.BlockChains.TonChains()) > 0 { + for _, tonChain := range env.BlockChains.TonChains() { + utils.FundWallets(t, tonChain.Client, []*address.Address{tonChain.WalletAddress}, []tlb.Coins{tonDeployerFundAmount}) + } + } + m.DeployedEnv = DeployedEnv{ - Env: env, + Env: *env, HomeChainSel: homeChainSel, FeedChainSel: feedSel, ReplayBlocks: replayBlocks, - Users: users, + Users: usersMap(t, m.Chains), // Extract the additional users from the EVM chains } } @@ -533,19 +514,28 @@ func (m *MemoryEnvironment) StartNodes(t *testing.T, crConfig deployment.Capabil nodes := nodetestutils.NewNodes(t, c, tc.CLNodeConfigOpts...) ctx := testcontext.Get(t) lggr := logger.Test(t) - for _, node := range nodes { + + nodeIDs := make([]string, 0, len(nodes)) + for id, node := range nodes { require.NoError(t, node.App.Start(ctx)) t.Cleanup(func() { require.NoError(t, node.App.Stop()) }) + nodeIDs = append(nodeIDs, id) } m.nodes = nodes - m.Env = memory.NewMemoryEnvironmentFromChainsNodes( - func() context.Context { return ctx }, - lggr, - m.Env.BlockChains, - nodes, + + e, err := environment.New(ctx, + environment.WithNodeIDs(nodeIDs), + environment.WithOffchainClient(jdtestutils.NewMemoryJobClient(nodes)), + environment.WithLogger(lggr), ) + require.NoError(t, err) + + // Manually set the block chains on the environment + e.BlockChains = m.Env.BlockChains + + m.Env = *e } func (m *MemoryEnvironment) DeleteJobs(ctx context.Context, jobIDs map[string][]string) error { @@ -730,7 +720,7 @@ func NewEnvironmentWithPrerequisitesContracts(t *testing.T, tEnv TestEnvironment )) require.NoError(t, err) if len(solChains) > 0 { - solLinkTokenPrivKey, _ := solana.NewRandomPrivateKey() + solLinkTokenPrivKey, _ := solanago.NewRandomPrivateKey() deploySolanaLinkApp := commonchangeset.Configure( cldf.CreateLegacyChangeSet(commonchangeset.DeploySolanaLinkToken), commonchangeset.DeploySolanaLinkTokenConfig{ @@ -1108,10 +1098,13 @@ func AddCCIPContractsToEnvironment(t *testing.T, allChains []uint64, tEnv TestEn ), }...) if len(solChains) != 0 { + // We take the path of the programs from the first solana chain since we always use the same path in all tests. + programsPath := e.Env.BlockChains.SolanaChains()[solChains[0]].ProgramsPath + if tEnv.TestConfigs().CCIPSolanaContractVersion == ccipChangeSetSolanaV0_1_1.SolanaContractV0_1_1 { var buildSolConfig = &ccipChangeSetSolanaV0_1_1.BuildSolanaConfig{ SolanaContractVersion: ccipChangeSetSolanaV0_1_1.VersionSolanaV0_1_1, - DestinationDir: memory.ProgramsPath, + DestinationDir: programsPath, } solCs, err := DeployChainContractsToSolChainCSV0_1_1(e, solChains[0], true, buildSolConfig) @@ -1161,7 +1154,7 @@ func AddCCIPContractsToEnvironment(t *testing.T, allChains []uint64, tEnv TestEn if len(tonChains) != 0 { // Currently only one ton chain is supported in test environment - _, err := memory.GetTONSha() + _, err := tontestutils.GetTONSha() require.NoError(t, err, "failed to get TON commit sha") // TODO replace the hardcoded commit sha with the one fetched from memory.GetTONSha() contractVersion := "bd37af74a93e" // https://github.com/smartcontractkit/chainlink-ton/releases/tag/ton-contracts-build-bd37af74a93e @@ -1645,3 +1638,58 @@ func usersMap(t *testing.T, chains map[uint64]cldf_evm.Chain) map[uint64][]*bind return users } + +// RegisterNodes registers a number of nodes against an in-memory job distributor and sets the +// chain configuration for the given chain. +// +// This only supports EVM chains. +func RegisterNodes(t *testing.T, env *cldf.Environment, numNodes int, selector uint64) []string { + client, ok := env.Offchain.(*simjd.MemoryJobDistributor) + require.True(t, ok) + + family, err := chain_selectors.GetSelectorFamily(selector) + require.NoError(t, err) + require.Equal(t, chain_selectors.FamilyEVM, family, "only EVM chains are supported") + + chainID, err := chain_selectors.GetChainIDFromSelector(selector) + require.NoError(t, err) + + nodeIDs := make([]string, numNodes) + for i := range numNodes { + res, err := client.RegisterNode(t.Context(), &nodev1.RegisterNodeRequest{ + Name: fmt.Sprintf("oracle-%d", i), + PublicKey: fmt.Sprintf("0x%d", i), + }) + require.NoError(t, err) + require.NotNil(t, res.Node) + require.NotEmpty(t, res.Node.Id) + + nodeID := res.Node.GetId() + nodeIDs[i] = nodeID + + p2pKey, err := p2pkey.NewV2() + require.NoError(t, err) + + err = client.AddChainConfig(nodeID, &nodev1.ChainConfig{ + Chain: &nodev1.Chain{ + Id: chainID, + Type: nodev1.ChainType_CHAIN_TYPE_EVM, + }, + NodeId: nodeID, + Ocr2Config: &nodev1.OCR2Config{ + Enabled: true, + OcrKeyBundle: &nodev1.OCR2Config_OCRKeyBundle{ + BundleId: fmt.Sprintf("ocr-key-bundle-%d", i), + }, + P2PKeyBundle: &nodev1.OCR2Config_P2PKeyBundle{ + PeerId: p2pKey.PeerID().String(), + }, + }, + }) + require.NoError(t, err) + } + + env.NodeIDs = nodeIDs + + return nodeIDs +} diff --git a/deployment/ccip/changeset/v1_5/e2e_test.go b/deployment/ccip/changeset/v1_5/e2e_test.go index 431ef17560d..dfb00bbe268 100644 --- a/deployment/ccip/changeset/v1_5/e2e_test.go +++ b/deployment/ccip/changeset/v1_5/e2e_test.go @@ -48,8 +48,13 @@ func TestE2ELegacy(t *testing.T) { }, }, }), - testhelpers.WithNumOfChains(3), - testhelpers.WithChainIDs([]uint64{chainselectors.GETH_TESTNET.EvmChainID})) + // testhelpers.WithNumOfChains(3), + testhelpers.WithEVMChainsBySelectors([]uint64{ + chainselectors.GETH_TESTNET.Selector, + chainselectors.TEST_90000001.Selector, + chainselectors.TEST_90000002.Selector, + }), + ) state, err := stateview.LoadOnchainState(e.Env, stateview.WithLoadLegacyContracts(true)) require.NoError(t, err) allChains := e.Env.BlockChains.ListChainSelectors( diff --git a/deployment/ccip/changeset/v1_6/accept_ownership_test.go b/deployment/ccip/changeset/v1_6/accept_ownership_test.go index c276477bd54..b75a3fa19d7 100644 --- a/deployment/ccip/changeset/v1_6/accept_ownership_test.go +++ b/deployment/ccip/changeset/v1_6/accept_ownership_test.go @@ -16,14 +16,14 @@ import ( func Test_NewAcceptOwnershipChangeset(t *testing.T) { t.Parallel() e, _ := testhelpers.NewMemoryEnvironment(t) - state, err := stateview.LoadOnchainState(e.Env) + _, err := stateview.LoadOnchainState(e.Env) require.NoError(t, err) allChains := maps.Keys(e.Env.BlockChains.EVMChains()) // at this point we have the initial deploys done, now we need to transfer ownership // to the timelock contract - state, err = stateview.LoadOnchainState(e.Env) + state, err := stateview.LoadOnchainState(e.Env) require.NoError(t, err) // compose the transfer ownership and accept ownership changesets diff --git a/deployment/ccip/changeset/v1_6/cs_add_new_chain_e2e_test.go b/deployment/ccip/changeset/v1_6/cs_add_new_chain_e2e_test.go index bf1ded8c572..da9a068932e 100644 --- a/deployment/ccip/changeset/v1_6/cs_add_new_chain_e2e_test.go +++ b/deployment/ccip/changeset/v1_6/cs_add_new_chain_e2e_test.go @@ -273,14 +273,14 @@ func TestAddAndPromoteCandidatesForNewChain(t *testing.T) { for _, test := range tests { t.Run(test.Msg, func(t *testing.T) { - chainIDs := []uint64{ - chain_selectors.ETHEREUM_MAINNET.EvmChainID, - chain_selectors.ETHEREUM_MAINNET_ARBITRUM_1.EvmChainID, - chain_selectors.ETHEREUM_MAINNET_OPTIMISM_1.EvmChainID, + selectors := []uint64{ + chain_selectors.ETHEREUM_MAINNET.Selector, + chain_selectors.ETHEREUM_MAINNET_ARBITRUM_1.Selector, + chain_selectors.ETHEREUM_MAINNET_OPTIMISM_1.Selector, } deployedEnvironment, _ := testhelpers.NewMemoryEnvironment(t, func(testCfg *testhelpers.TestConfigs) { - testCfg.ChainIDs = chainIDs + testCfg.EVMChainsBySelectors = selectors }) e := deployedEnvironment.Env state, err := stateview.LoadOnchainState(e) @@ -289,8 +289,8 @@ func TestAddAndPromoteCandidatesForNewChain(t *testing.T) { // Identify and delete addresses from the new chain var newChainSelector uint64 var linkAddress common.Address - remoteChainSelectors := make([]uint64, 0, len(chainIDs)-1) - addressesByChain := make(map[uint64]map[string]cldf.TypeAndVersion, len(chainIDs)-1) + remoteChainSelectors := make([]uint64, 0, len(selectors)-1) + addressesByChain := make(map[uint64]map[string]cldf.TypeAndVersion, len(selectors)-1) ds := datastore.NewMemoryDataStore() for _, selector := range e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilyEVM)) { if selector != deployedEnvironment.HomeChainSel && newChainSelector == 0 { @@ -608,13 +608,13 @@ func TestValidateTransmitterAddresses(t *testing.T) { // Test the core validation logic from ValidateTransmitters method // fChain := uint8(1) // requiredTransmitters := 3*int(fChain) + 1 - chainIDs := []uint64{ - chain_selectors.ETHEREUM_TESTNET_SEPOLIA.EvmChainID, - chain_selectors.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.EvmChainID, - chain_selectors.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.EvmChainID, + selectors := []uint64{ + chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector, + chain_selectors.ETHEREUM_TESTNET_SEPOLIA_ARBITRUM_1.Selector, + chain_selectors.ETHEREUM_TESTNET_SEPOLIA_OPTIMISM_1.Selector, } deployedEnvironment, _ := testhelpers.NewMemoryEnvironment(t, func(testCfg *testhelpers.TestConfigs) { - testCfg.ChainIDs = chainIDs + testCfg.EVMChainsBySelectors = selectors testCfg.Nodes = 4 }) e := deployedEnvironment.Env diff --git a/deployment/ccip/changeset/v1_6/cs_chain_contracts_test.go b/deployment/ccip/changeset/v1_6/cs_chain_contracts_test.go index 18159ce4c06..6d8af23e446 100644 --- a/deployment/ccip/changeset/v1_6/cs_chain_contracts_test.go +++ b/deployment/ccip/changeset/v1_6/cs_chain_contracts_test.go @@ -859,8 +859,12 @@ func TestUpdateNonceManagersCSApplyPreviousRampsUpdates(t *testing.T) { }, }, }), - testhelpers.WithNumOfChains(3), - testhelpers.WithChainIDs([]uint64{chainselectors.GETH_TESTNET.EvmChainID})) + testhelpers.WithEVMChainsBySelectors([]uint64{ + chainselectors.GETH_TESTNET.Selector, + chainselectors.TEST_90000001.Selector, + chainselectors.TEST_90000002.Selector, + }), + ) state, err := stateview.LoadOnchainState(e.Env, stateview.WithLoadLegacyContracts(true)) require.NoError(t, err) allChains := e.Env.BlockChains.ListChainSelectors( diff --git a/deployment/ccip/changeset/v1_6/cs_deploy_chain_test.go b/deployment/ccip/changeset/v1_6/cs_deploy_chain_test.go index 56561cf01cb..04f8162ac5c 100644 --- a/deployment/ccip/changeset/v1_6/cs_deploy_chain_test.go +++ b/deployment/ccip/changeset/v1_6/cs_deploy_chain_test.go @@ -5,17 +5,16 @@ import ( "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" - chain_selectors "github.com/smartcontractkit/chain-selectors" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/stretchr/testify/require" cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain" - cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/environment" "github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_6_3/fee_quoter" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" @@ -24,26 +23,25 @@ import ( ccipops "github.com/smartcontractkit/chainlink/deployment/ccip/operation/evm/v1_6" ccipseq "github.com/smartcontractkit/chainlink/deployment/ccip/sequence/evm/v1_6" "github.com/smartcontractkit/chainlink/deployment/ccip/shared/stateview" - commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/common/opsutils" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestDeployChainContractsChangeset(t *testing.T) { t.Parallel() - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 2, - Nodes: 4, - }) - evmSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilyEVM)) - homeChainSel := evmSelectors[0] - testDeployChainContractsChangesetWithEnv(t, e, homeChainSel) + + homeChainSel := chain_selectors.TEST_90000001.Selector + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{homeChainSel}), + environment.WithLogger(logger.Test(t)), + ) + require.NoError(t, err) + + testhelpers.RegisterNodes(t, env, 4, homeChainSel) + + testDeployChainContractsChangesetWithEnv(t, *env, homeChainSel) } func TestDeployChainContractsChangesetZk(t *testing.T) { @@ -51,23 +49,19 @@ func TestDeployChainContractsChangesetZk(t *testing.T) { tests.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/CCIP-6427") t.Parallel() - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 1, - ZkChains: 1, - Nodes: 4, - }) - evmSelectors := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilyEVM)) - var homeChainSel uint64 - for _, selector := range evmSelectors { - chain := e.BlockChains.EVMChains()[selector] - if !chain.IsZkSyncVM { - homeChainSel = chain.Selector - break - } - } - testDeployChainContractsChangesetWithEnv(t, e, homeChainSel) + + homeChainSel := chain_selectors.TEST_90000001.Selector + zkChainSel := chain_selectors.TEST_90000050.Selector + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{homeChainSel}), + environment.WithZKSyncContainer(t, []uint64{zkChainSel}), + environment.WithLogger(logger.Test(t)), + ) + require.NoError(t, err) + + testhelpers.RegisterNodes(t, env, 4, homeChainSel) + + testDeployChainContractsChangesetWithEnv(t, *env, homeChainSel) } func testDeployChainContractsChangesetWithEnv(t *testing.T, e cldf.Environment, homeChainSel uint64) { diff --git a/deployment/ccip/changeset/v1_6/cs_home_chain_test.go b/deployment/ccip/changeset/v1_6/cs_home_chain_test.go index ead8b91abdc..f6363f65cf5 100644 --- a/deployment/ccip/changeset/v1_6/cs_home_chain_test.go +++ b/deployment/ccip/changeset/v1_6/cs_home_chain_test.go @@ -7,40 +7,40 @@ import ( "github.com/ethereum/go-ethereum/common" chain_selectors "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain" + cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/environment" + "github.com/smartcontractkit/chainlink-common/pkg/logger" capabilities_registry "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - "github.com/smartcontractkit/chainlink-evm/pkg/utils" - - cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/testhelpers" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/v1_6" "github.com/smartcontractkit/chainlink/deployment/ccip/shared/stateview" - commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" commoncs "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestDeployHomeChain(t *testing.T) { t.Parallel() - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 2, - Nodes: 4, - }) - homeChainSel := e.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilyEVM))[0] + + homeChainSel := chain_selectors.TEST_90000001.Selector + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{homeChainSel}), + environment.WithLogger(logger.Test(t)), + ) + require.NoError(t, err) + + testhelpers.RegisterNodes(t, env, 4, homeChainSel) + + e := *env + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) require.NoError(t, err) p2pIds := nodes.NonBootstraps().PeerIDs() @@ -119,8 +119,8 @@ func TestDeployDonIDClaimerAndOffSet(t *testing.T) { } // apply the changeset once again to ensure idempotency - e, err = commonchangeset.Apply(t, e, - commonchangeset.Configure( + e, err = commoncs.Apply(t, e, + commoncs.Configure( cldf.CreateLegacyChangeSet(v1_6.DeployHomeChainChangeset), homeChainCfg, )) @@ -134,8 +134,8 @@ func TestDeployDonIDClaimerAndOffSet(t *testing.T) { require.NoError(t, err) // deploy donIDClaimer - e, err = commonchangeset.Apply(t, e, - commonchangeset.Configure( + e, err = commoncs.Apply(t, e, + commoncs.Configure( v1_6.DeployDonIDClaimerChangeset, v1_6.DeployDonIDClaimerConfig{}, )) @@ -145,8 +145,8 @@ func TestDeployDonIDClaimerAndOffSet(t *testing.T) { state, err = stateview.LoadOnchainState(e) require.NoError(t, err) - e, err = commonchangeset.Apply(t, e, - commonchangeset.Configure( + e, err = commoncs.Apply(t, e, + commoncs.Configure( v1_6.DonIDClaimerOffSetChangeset, v1_6.DonIDClaimerOffSetConfig{ OffSet: 1, diff --git a/deployment/ccip/changeset/v1_6/cs_translate_onramp_to_feequoter_test.go b/deployment/ccip/changeset/v1_6/cs_translate_onramp_to_feequoter_test.go index 3660a4c7a66..331ced603b6 100644 --- a/deployment/ccip/changeset/v1_6/cs_translate_onramp_to_feequoter_test.go +++ b/deployment/ccip/changeset/v1_6/cs_translate_onramp_to_feequoter_test.go @@ -67,12 +67,7 @@ func TestTranslateEVM2EVMOnRampsToFeeQuoterChangeset(t *testing.T) { state, err := stateview.LoadOnchainState(tenv, stateview.WithLoadLegacyContracts(true)) require.NoError(t, err, "Failed to load initial onchain state") - allChains := tenv.BlockChains.ListChainSelectors( - cldf_chain.WithFamily(chain_selectors.FamilyEVM), - cldf_chain.WithChainSelectorsExclusion([]uint64{chain_selectors.GETH_TESTNET.Selector}), - ) - - selectorA, selectorB := allChains[0], allChains[1] + selectorA, selectorB := allChainSelectors[0], allChainSelectors[1] pairs := []testhelpers.SourceDestPair{ {SourceChainSelector: selectorA, DestChainSelector: selectorB}, {SourceChainSelector: selectorB, DestChainSelector: selectorA}, @@ -80,7 +75,7 @@ func TestTranslateEVM2EVMOnRampsToFeeQuoterChangeset(t *testing.T) { // 3. Remove link token as it will be deployed by 1.6 contracts again ab := cldf.NewMemoryAddressBook() - for _, sel := range allChains { + for _, sel := range allChainSelectors { require.NoError(t, ab.Save(sel, state.Chains[sel].LinkToken.Address().Hex(), cldf.NewTypeAndVersion("LinkToken", deployment.Version1_0_0))) } @@ -88,7 +83,7 @@ func TestTranslateEVM2EVMOnRampsToFeeQuoterChangeset(t *testing.T) { // 4. Set the test router as the source chain's router ab = cldf.NewMemoryAddressBook() - for _, sel := range allChains { + for _, sel := range allChainSelectors { require.NoError(t, ab.Save(sel, utils.RandomAddress().Hex(), cldf.NewTypeAndVersion(shared.TestRouter, deployment.Version1_2_0))) } diff --git a/deployment/common/changeset/solana/mcms/mcms.go b/deployment/common/changeset/solana/mcms/mcms.go index 5233f7a5002..edf5684171b 100644 --- a/deployment/common/changeset/solana/mcms/mcms.go +++ b/deployment/common/changeset/solana/mcms/mcms.go @@ -42,12 +42,12 @@ func DeployMCMSWithTimelockProgramsSolana( // access controller err = deployAccessControllerProgram(e, chainState, chain, addressBook) - err = waitForProgramDeployment(e.GetContext(), chain.Client, chainState.AccessControllerProgram, 30*time.Second) if err != nil { - return nil, fmt.Errorf("access controller program not ready: %w", err) + return nil, fmt.Errorf("failed to deploy access controller program: %w", err) } + err = waitForProgramDeployment(e.GetContext(), chain.Client, chainState.AccessControllerProgram, 30*time.Second) if err != nil { - return nil, fmt.Errorf("failed to deploy access controller program: %w", err) + return nil, fmt.Errorf("access controller program not ready: %w", err) } err = initAccessController(e, chainState, commontypes.ProposerAccessControllerAccount, chain, addressBook) if err != nil { @@ -68,12 +68,12 @@ func DeployMCMSWithTimelockProgramsSolana( // mcm err = deployMCMProgram(e, chainState, chain, addressBook) - err = waitForProgramDeployment(e.GetContext(), chain.Client, chainState.AccessControllerProgram, 30*time.Second) if err != nil { - return nil, fmt.Errorf("access controller program not ready: %w", err) + return nil, fmt.Errorf("failed to deploy mcm program: %w", err) } + err = waitForProgramDeployment(e.GetContext(), chain.Client, chainState.McmProgram, 30*time.Second) if err != nil { - return nil, fmt.Errorf("failed to deploy mcm program: %w", err) + return nil, fmt.Errorf("mcm program not ready: %w", err) } err = initMCM(e, chainState, commontypes.BypasserManyChainMultisig, chain, addressBook, &config.Bypasser) if err != nil { @@ -90,12 +90,12 @@ func DeployMCMSWithTimelockProgramsSolana( // timelock err = deployTimelockProgram(e, chainState, chain, addressBook) - err = waitForProgramDeployment(e.GetContext(), chain.Client, chainState.AccessControllerProgram, 30*time.Second) if err != nil { - return nil, fmt.Errorf("access controller program not ready: %w", err) + return nil, fmt.Errorf("failed to deploy timelock program: %w", err) } + err = waitForProgramDeployment(e.GetContext(), chain.Client, chainState.TimelockProgram, 30*time.Second) if err != nil { - return nil, fmt.Errorf("failed to deploy timelock program: %w", err) + return nil, fmt.Errorf("timelock program not ready: %w", err) } err = initTimelock(e, chainState, chain, addressBook, config.TimelockMinDelay) if err != nil { diff --git a/deployment/internal/soltestutils/preload.go b/deployment/internal/soltestutils/preload.go index 8ebd0a3f7dc..f4c4239584c 100644 --- a/deployment/internal/soltestutils/preload.go +++ b/deployment/internal/soltestutils/preload.go @@ -58,6 +58,20 @@ func LoadDataFeedsPrograms(t *testing.T, dir string) map[string]string { return progIDs } +// LoadCCIPPrograms loads the CCIP program artifacts into the given directory. +func LoadCCIPPrograms(t *testing.T, dir string) map[string]string { + t.Helper() + + ccipProgIDs := loadProgramArtifacts(t, solutils.CCIPProgramNames, downloadChainlinkCCIPProgramArtifacts, dir) + _, mcmsProgIDs := LoadMCMSPrograms(t, dir) + + progIDs := make(map[string]string, len(ccipProgIDs)+len(mcmsProgIDs)) + maps.Copy(progIDs, ccipProgIDs) + maps.Copy(progIDs, mcmsProgIDs) + + return progIDs +} + // PreloadMCMS provides a convenience function to preload the MCMS program artifacts and address // book for a given selector. // diff --git a/deployment/internal/tontestutils/sha.go b/deployment/internal/tontestutils/sha.go new file mode 100644 index 00000000000..891fdcaffb0 --- /dev/null +++ b/deployment/internal/tontestutils/sha.go @@ -0,0 +1,74 @@ +package tontestutils + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + + "golang.org/x/mod/modfile" +) + +func GetTONSha() (version string, err error) { + modFilePath, err := getModFilePath() + if err != nil { + return "", err + } + depVersion, err := getTONCcipDependencyVersion(modFilePath) + if err != nil { + return "", err + } + tokens := strings.Split(depVersion, "-") + if len(tokens) == 3 { + version := tokens[len(tokens)-1] + + return version, nil + } + + return "", fmt.Errorf("invalid go.mod version: %s", depVersion) +} + +func getTONCcipDependencyVersion(gomodPath string) (string, error) { + const dependency = "github.com/smartcontractkit/chainlink-ton" + + gomod, err := os.ReadFile(gomodPath) + if err != nil { + return "", err + } + + modFile, err := modfile.ParseLax("go.mod", gomod, nil) + if err != nil { + return "", err + } + + for _, dep := range modFile.Require { + if dep.Mod.Path == dependency { + return dep.Mod.Version, nil + } + } + + return "", fmt.Errorf("dependency %s not found", dependency) +} + +func getModFilePath() (string, error) { + _, currentFile, _, ok := runtime.Caller(0) + if !ok { + return "", errors.New("runtime.Caller failed to retrieve current file") + } + + // Get the root directory by walking up from current file until we find go.mod + rootDir := filepath.Dir(currentFile) + for { + if _, err := os.Stat(filepath.Join(rootDir, "go.mod")); err == nil { + break + } + parent := filepath.Dir(rootDir) + if parent == rootDir { + return "", errors.New("could not find project root directory containing go.mod") + } + rootDir = parent + } + return filepath.Join(rootDir, "go.mod"), nil +} diff --git a/integration-tests/smoke/ccip/ccip_messaging_test.go b/integration-tests/smoke/ccip/ccip_messaging_test.go index 4d41e885703..b41871da6be 100644 --- a/integration-tests/smoke/ccip/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip/ccip_messaging_test.go @@ -46,14 +46,14 @@ func Test_CCIPMessaging_EVM2EVM(t *testing.T) { chainsel.TEST_90000001, // dest } var chainIDs = []uint64{ - chains[0].EvmChainID, - chains[1].EvmChainID, + chains[0].Selector, + chains[1].Selector, } // Setup 2 chains and a single lane. ctx := testhelpers.Context(t) e, _, _ := testsetups.NewIntegrationEnvironment( t, - testhelpers.WithChainIDs(chainIDs), + testhelpers.WithEVMChainsBySelectors(chainIDs), testhelpers.WithCLNodeConfigOpts(nodetestutils.WithFinalityDepths(map[uint64]uint32{ chains[1].EvmChainID: 30, // make dest chain finality depth 30 so we can observe exec behavior })), diff --git a/integration-tests/smoke/ccip/ccip_migration_to_v_1_6_test.go b/integration-tests/smoke/ccip/ccip_migration_to_v_1_6_test.go index 1821c653456..e8973818c2a 100644 --- a/integration-tests/smoke/ccip/ccip_migration_to_v_1_6_test.go +++ b/integration-tests/smoke/ccip/ccip_migration_to_v_1_6_test.go @@ -509,7 +509,7 @@ func TestMigrateFromV1_5ToV1_6(t *testing.T) { testhelpers.WithNumOfUsersPerChain(2), // for in-memory test it is important to set the dest chain id as 1337 otherwise the config digest will not match // between nodes' calculated digest and the digest set on the contract - testhelpers.WithChainIDs([]uint64{chainselectors.GETH_TESTNET.EvmChainID}), + testhelpers.WithEVMChainsBySelectors([]uint64{chainselectors.GETH_TESTNET.Selector}), ) state, err := stateview.LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip/ccip_topologies_test.go b/integration-tests/smoke/ccip/ccip_topologies_test.go index c9da48fe73c..266c6b2a2e6 100644 --- a/integration-tests/smoke/ccip/ccip_topologies_test.go +++ b/integration-tests/smoke/ccip/ccip_topologies_test.go @@ -1,7 +1,6 @@ package ccip import ( - "sort" "testing" "github.com/ethereum/go-ethereum/common" @@ -26,15 +25,11 @@ func Test_CCIPTopologies_EVM2EVM_RoleDON_AllSupportDest_SomeSupportSource(t *tes func runCCIPTopologiesTest(t *testing.T, fChainSource, fChainDest int) { // fix the chain ids for the test so we can appropriately set finality depth numbers on the destination chain. - chains := []chainsel.Chain{ - chainsel.TEST_90000001, - chainsel.TEST_90000002, - chainsel.TEST_90000003, - } - sort.Slice(chains, func(i, j int) bool { return chains[i].Selector < chains[j].Selector }) - homeChainSel := chains[0].Selector - sourceChainSel := chains[1].Selector - destChainSel := chains[2].Selector + homeChainSel := chainsel.TEST_90000001.Selector + sourceChainSel := chainsel.TEST_90000002.Selector + destChainSel := chainsel.TEST_90000003.Selector + + selectors := []uint64{homeChainSel, sourceChainSel, destChainSel} const ( fRoleDON = 2 @@ -44,7 +39,7 @@ func runCCIPTopologiesTest(t *testing.T, fChainSource, fChainDest int) { // Setup 3 chains and a single lane. e, _, _ := testsetups.NewIntegrationEnvironment( t, - testhelpers.WithNumOfChains(len(chains)), + testhelpers.WithEVMChainsBySelectors(selectors), testhelpers.WithNumOfNodes(nRoleDON), testhelpers.WithRoleDONTopology(cciptesthelpertypes.NewRandomTopology( cciptesthelpertypes.RandomTopologyArgs{