From aaab52e01412ea4f1de4f748cadf0c127682418c Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 3 Jan 2025 15:18:33 +0000 Subject: [PATCH 01/31] Adding solchains in NewEnv --- deployment/environment.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/deployment/environment.go b/deployment/environment.go index bfbeac2f0c4..def161ae521 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -110,6 +110,7 @@ func NewEnvironment( logger logger.Logger, existingAddrs AddressBook, chains map[uint64]Chain, + solChains map[uint64]SolChain, nodeIDs []string, offchain OffchainClient, ctx func() context.Context, @@ -120,6 +121,7 @@ func NewEnvironment( Logger: logger, ExistingAddresses: existingAddrs, Chains: chains, + SolChains: solChains, NodeIDs: nodeIDs, Offchain: offchain, GetContext: ctx, @@ -158,6 +160,17 @@ func (e Environment) AllChainSelectorsExcluding(excluding []uint64) []uint64 { return selectors } +func (e Environment) AllChainSelectorsSolana() []uint64 { + var selectors []uint64 + for sel := range e.SolChains { + selectors = append(selectors, sel) + } + sort.Slice(selectors, func(i, j int) bool { + return selectors[i] < selectors[j] + }) + return selectors +} + func (e Environment) AllDeployerKeys() []common.Address { var deployerKeys []common.Address for sel := range e.Chains { From f19598ea17d5fe2d3751d99c61746ef1f20029d9 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 3 Jan 2025 15:19:15 +0000 Subject: [PATCH 02/31] Revert "Adding solchains in NewEnv" This reverts commit aaab52e01412ea4f1de4f748cadf0c127682418c. --- deployment/environment.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/deployment/environment.go b/deployment/environment.go index def161ae521..bfbeac2f0c4 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -110,7 +110,6 @@ func NewEnvironment( logger logger.Logger, existingAddrs AddressBook, chains map[uint64]Chain, - solChains map[uint64]SolChain, nodeIDs []string, offchain OffchainClient, ctx func() context.Context, @@ -121,7 +120,6 @@ func NewEnvironment( Logger: logger, ExistingAddresses: existingAddrs, Chains: chains, - SolChains: solChains, NodeIDs: nodeIDs, Offchain: offchain, GetContext: ctx, @@ -160,17 +158,6 @@ func (e Environment) AllChainSelectorsExcluding(excluding []uint64) []uint64 { return selectors } -func (e Environment) AllChainSelectorsSolana() []uint64 { - var selectors []uint64 - for sel := range e.SolChains { - selectors = append(selectors, sel) - } - sort.Slice(selectors, func(i, j int) bool { - return selectors[i] < selectors[j] - }) - return selectors -} - func (e Environment) AllDeployerKeys() []common.Address { var deployerKeys []common.Address for sel := range e.Chains { From dfe582d843540c5830ca659a37b49a139f6e8950 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 16:34:54 +0000 Subject: [PATCH 03/31] remove todo --- deployment/ccip/changeset/solana/cs_billing.go | 1 - 1 file changed, 1 deletion(-) diff --git a/deployment/ccip/changeset/solana/cs_billing.go b/deployment/ccip/changeset/solana/cs_billing.go index af1518ddd44..c57e04b4bca 100644 --- a/deployment/ccip/changeset/solana/cs_billing.go +++ b/deployment/ccip/changeset/solana/cs_billing.go @@ -68,7 +68,6 @@ func AddBillingToken(e deployment.Environment, cfg BillingTokenConfig) (deployme tokenPubKey := solana.MustPublicKeyFromBase58(cfg.TokenPubKey) // verified tokenprogramID, _ := GetTokenProgramID(cfg.TokenProgramName) - // TODO: add this to offramp address lookup table tokenBillingPDA, _, _ := solState.FindFqBillingTokenConfigPDA(tokenPubKey, chainState.FeeQuoter) // addressing errcheck in the next PR From 4699cc9d3735e324eff18aa332620dcecab0058d Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 16:35:12 +0000 Subject: [PATCH 04/31] remove todo --- deployment/ccip/changeset/solana/cs_chain_contracts_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go index b55bb413804..93f09cebf4e 100644 --- a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go +++ b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go @@ -345,7 +345,6 @@ func TestTokenAdminRegistry(t *testing.T) { require.Equal(t, tokenAdminRegistryAdminPrivKey.PublicKey(), tokenAdminRegistryAccount.Administrator) require.Equal(t, solana.PublicKey{}, tokenAdminRegistryAccount.PendingAdministrator) - // TODO: transfer and accept is breaking newTokenAdminRegistryAdminPrivKey, _ := solana.NewRandomPrivateKey() e, err = commonchangeset.Apply(t, e, nil, commonchangeset.Configure( From 9b53d658a4fdf24e27d210aca356aa67380ddf97 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 16:35:45 +0000 Subject: [PATCH 05/31] add cs to set fee agg --- .../ccip/changeset/solana/cs_deploy_chain.go | 56 ++++++++++++++++++- .../changeset/solana/cs_deploy_chain_test.go | 16 +++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_deploy_chain.go b/deployment/ccip/changeset/solana/cs_deploy_chain.go index 2623e69a9c5..9567757dd59 100644 --- a/deployment/ccip/changeset/solana/cs_deploy_chain.go +++ b/deployment/ccip/changeset/solana/cs_deploy_chain.go @@ -9,6 +9,7 @@ import ( "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" + cs "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" solBinary "github.com/gagliardetto/binary" solRpc "github.com/gagliardetto/solana-go/rpc" @@ -103,7 +104,7 @@ func initializeRouter( instruction, err := solRouter.NewInitializeInstruction( chain.Selector, // chain selector - solana.PublicKey{}, // fee aggregator (TODO: changeset to set the fee aggregator) + solana.PublicKey{}, // fee aggregator feeQuoterAddress, linkTokenAddress, // link token mint routerConfigPDA, @@ -428,3 +429,56 @@ func deployChainContractsSolana( return nil } + +type SetFeeAggregatorConfig struct { + ChainSelector uint64 + FeeAggregator string +} + +func (cfg SetFeeAggregatorConfig) Validate(e deployment.Environment) error { + state, _ := cs.LoadOnchainState(e) + chainState := state.SolChains[cfg.ChainSelector] + chain := e.SolChains[cfg.ChainSelector] + + if err := validateRouterConfig(chain, chainState); err != nil { + return err + } + + // Validate fee aggregator address is valid + if _, err := solana.PublicKeyFromBase58(cfg.FeeAggregator); err != nil { + return fmt.Errorf("invalid fee aggregator address: %w", err) + } + + return nil +} + +func SetFeeAggregator(e deployment.Environment, cfg SetFeeAggregatorConfig) (deployment.ChangesetOutput, error) { + if err := cfg.Validate(e); err != nil { + return deployment.ChangesetOutput{}, err + } + + state, _ := cs.LoadOnchainState(e) + chainState := state.SolChains[cfg.ChainSelector] + chain := e.SolChains[cfg.ChainSelector] + + feeAggregatorPubKey := solana.MustPublicKeyFromBase58(cfg.FeeAggregator) + routerConfigPDA, _, _ := solState.FindConfigPDA(chainState.Router) + + solRouter.SetProgramID(chainState.Router) + instruction, err := solRouter.NewUpdateFeeAggregatorInstruction( + feeAggregatorPubKey, + routerConfigPDA, + chain.DeployerKey.PublicKey(), + solana.SystemProgramID, + ).ValidateAndBuild() + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to build instruction: %w", err) + } + + if err := chain.Confirm([]solana.Instruction{instruction}); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm instructions: %w", err) + } + + e.Logger.Infow("Set new fee aggregator", "chain", chain.String(), "fee_aggregator", feeAggregatorPubKey.String()) + return deployment.ChangesetOutput{}, nil +} diff --git a/deployment/ccip/changeset/solana/cs_deploy_chain_test.go b/deployment/ccip/changeset/solana/cs_deploy_chain_test.go index 97689265be2..386d8917b9b 100644 --- a/deployment/ccip/changeset/solana/cs_deploy_chain_test.go +++ b/deployment/ccip/changeset/solana/cs_deploy_chain_test.go @@ -3,12 +3,13 @@ package solana_test import ( "testing" + "github.com/gagliardetto/solana-go" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/solana" + cs_solana "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/solana" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/testhelpers" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/environment/memory" @@ -48,6 +49,9 @@ func TestDeployChainContractsChangesetSolana(t *testing.T) { }) } + feeAggregatorPrivKey, _ := solana.NewRandomPrivateKey() + feeAggregatorPubKey := feeAggregatorPrivKey.PublicKey() + testhelpers.SavePreloadedSolAddresses(t, e, solChainSelectors[0]) e, err = commonchangeset.Apply(t, e, nil, commonchangeset.Configure( @@ -89,7 +93,7 @@ func TestDeployChainContractsChangesetSolana(t *testing.T) { }, ), commonchangeset.Configure( - deployment.CreateLegacyChangeSet(solana.DeployChainContractsChangesetSolana), + deployment.CreateLegacyChangeSet(cs_solana.DeployChainContractsChangesetSolana), changeset.DeployChainContractsConfig{ HomeChainSelector: homeChainSel, ContractParamsPerChain: map[uint64]changeset.ChainContractParams{ @@ -100,8 +104,16 @@ func TestDeployChainContractsChangesetSolana(t *testing.T) { }, }, ), + commonchangeset.Configure( + deployment.CreateLegacyChangeSet(cs_solana.SetFeeAggregator), + cs_solana.SetFeeAggregatorConfig{ + ChainSelector: solChainSelectors[0], + FeeAggregator: feeAggregatorPubKey.String(), + }, + ), ) require.NoError(t, err) // solana verification testhelpers.ValidateSolanaState(t, e, solChainSelectors) + } From 3e6ce6a494f3863f7423c01e770494c4735d4ed5 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 16:36:52 +0000 Subject: [PATCH 06/31] add cs --- deployment/ccip/changeset/solana/cs_chain_contracts.go | 1 + 1 file changed, 1 insertion(+) diff --git a/deployment/ccip/changeset/solana/cs_chain_contracts.go b/deployment/ccip/changeset/solana/cs_chain_contracts.go index a5366ff5842..cd54f7d76e0 100644 --- a/deployment/ccip/changeset/solana/cs_chain_contracts.go +++ b/deployment/ccip/changeset/solana/cs_chain_contracts.go @@ -22,6 +22,7 @@ var _ deployment.ChangeSet[BillingTokenForRemoteChainConfig] = AddBillingTokenFo var _ deployment.ChangeSet[RegisterTokenAdminRegistryConfig] = RegisterTokenAdminRegistry var _ deployment.ChangeSet[TransferAdminRoleTokenAdminRegistryConfig] = TransferAdminRoleTokenAdminRegistry var _ deployment.ChangeSet[AcceptAdminRoleTokenAdminRegistryConfig] = AcceptAdminRoleTokenAdminRegistry +var _ deployment.ChangeSet[SetFeeAggregatorConfig] = SetFeeAggregator // HELPER FUNCTIONS // GetTokenProgramID returns the program ID for the given token program name From 484898fee48c3480ac04df7c97d3e95d0a4a03e9 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 16:37:02 +0000 Subject: [PATCH 07/31] address comments --- deployment/ccip/changeset/solana/cs_token_pool.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deployment/ccip/changeset/solana/cs_token_pool.go b/deployment/ccip/changeset/solana/cs_token_pool.go index 191398d3ead..34d228f08a0 100644 --- a/deployment/ccip/changeset/solana/cs_token_pool.go +++ b/deployment/ccip/changeset/solana/cs_token_pool.go @@ -94,6 +94,8 @@ func AddTokenPool(e deployment.Environment, cfg TokenPoolConfig) (deployment.Cha return deployment.ChangesetOutput{}, fmt.Errorf("failed to generate instructions: %w", err) } // make pool mint_authority for token (required for burn/mint) + // this cannot be done for WSOL + // so if we ever need a WSOL token pool, we will have to split this out to another changeset authI, err := solTokenUtil.SetTokenMintAuthority( tokenprogramID, poolSigner, @@ -241,7 +243,6 @@ func (cfg TokenPoolLookupTableConfig) Validate(e deployment.Environment) error { return fmt.Errorf("token pool not found in existing state, deploy the token pool first for chain %d", cfg.ChainSelector) } - // TODO: do we need to validate if everything that goes into the lookup table is already created ? return nil } From d44f0fdacca36dc056438573c921e6cc901b1151 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 16:57:55 +0000 Subject: [PATCH 08/31] validation on mint --- .../ccip/changeset/solana/cs_solana_token.go | 43 ++++++++++++++++--- .../changeset/solana/cs_solana_token_test.go | 4 +- .../changeset/testhelpers/test_helpers.go | 2 +- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_solana_token.go b/deployment/ccip/changeset/solana/cs_solana_token.go index bfce1e70da5..a8ffe836cae 100644 --- a/deployment/ccip/changeset/solana/cs_solana_token.go +++ b/deployment/ccip/changeset/solana/cs_solana_token.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" "github.com/smartcontractkit/chainlink/deployment" @@ -81,25 +82,52 @@ func DeploySolanaToken(e deployment.Environment, cfg DeploySolanaTokenConfig) (d }, nil } -// TODO: there is no validation done around if the token is already deployed -// https://smartcontract-it.atlassian.net/browse/INTAUTO-439 type MintSolanaTokenConfig struct { ChainSelector uint64 TokenProgram string - TokenPubkey solana.PublicKey + TokenPubkey string AmountToAddress map[string]uint64 // address -> amount } -func MintSolanaToken(e deployment.Environment, cfg MintSolanaTokenConfig) (deployment.ChangesetOutput, error) { - // get chain +func (cfg MintSolanaTokenConfig) Validate(e deployment.Environment) error { chain := e.SolChains[cfg.ChainSelector] // get addresses - tokenAddress := cfg.TokenPubkey + tokenAddress := solana.MustPublicKeyFromBase58(cfg.TokenPubkey) // get token program id tokenprogramID, err := GetTokenProgramID(cfg.TokenProgram) + if err != nil { + return err + } + + //validation + accountInfo, err := chain.Client.GetAccountInfoWithOpts(e.GetContext(), tokenAddress, &rpc.GetAccountInfoOpts{ + Commitment: deployment.SolDefaultCommitment, + }) + if err != nil { + fmt.Println("error getting account info", err) + return err + } + if accountInfo == nil || accountInfo.Value == nil { + return fmt.Errorf("token address %s not found", tokenAddress.String()) + } + if accountInfo.Value.Owner != tokenprogramID { + return fmt.Errorf("token address %s is not owned by the SPL token program", tokenAddress.String()) + } + return nil +} + +func MintSolanaToken(e deployment.Environment, cfg MintSolanaTokenConfig) (deployment.ChangesetOutput, error) { + err := cfg.Validate(e) if err != nil { return deployment.ChangesetOutput{}, err } + // get chain + chain := e.SolChains[cfg.ChainSelector] + // get addresses + tokenAddress := solana.MustPublicKeyFromBase58(cfg.TokenPubkey) + // get token program id + tokenprogramID, _ := GetTokenProgramID(cfg.TokenProgram) + // get mint instructions instructions := []solana.Instruction{} for toAddress, amount := range cfg.AmountToAddress { @@ -119,7 +147,8 @@ func MintSolanaToken(e deployment.Environment, cfg MintSolanaTokenConfig) (deplo e.Logger.Errorw("Failed to confirm instructions for token minting", "chain", chain.String(), "err", err) return deployment.ChangesetOutput{}, err } - e.Logger.Infow("Minted tokens on", "chain", cfg.ChainSelector, "for token", cfg.TokenPubkey.String()) + e.Logger.Infow("Minted tokens on", "chain", cfg.ChainSelector, "for token", tokenAddress.String()) + return deployment.ChangesetOutput{}, nil } diff --git a/deployment/ccip/changeset/solana/cs_solana_token_test.go b/deployment/ccip/changeset/solana/cs_solana_token_test.go index 0437c868b06..c46e7eae7ad 100644 --- a/deployment/ccip/changeset/solana/cs_solana_token_test.go +++ b/deployment/ccip/changeset/solana/cs_solana_token_test.go @@ -63,7 +63,7 @@ func TestSolanaTokenOps(t *testing.T) { deployment.CreateLegacyChangeSet(changeset_solana.MintSolanaToken), changeset_solana.MintSolanaTokenConfig{ ChainSelector: solChain1, - TokenPubkey: tokenAddress, + TokenPubkey: tokenAddress.String(), TokenProgram: deployment.SPL2022Tokens, AmountToAddress: map[string]uint64{ deployerKey.String(): uint64(1000), @@ -86,13 +86,11 @@ func TestSolanaTokenOps(t *testing.T) { // test if minting was done correctly outDec, outVal, err := solTokenUtil.TokenBalance(context.Background(), e.SolChains[solChain1].Client, deployerATA, solRpc.CommitmentConfirmed) require.NoError(t, err) - t.Logf("outDec: %d, outVal: %d", outDec, outVal) require.Equal(t, int(1000), outVal) require.Equal(t, 9, int(outDec)) outDec, outVal, err = solTokenUtil.TokenBalance(context.Background(), e.SolChains[solChain1].Client, testUserATA, solRpc.CommitmentConfirmed) require.NoError(t, err) - t.Logf("outDec: %d, outVal: %d", outDec, outVal) require.Equal(t, int(1000), outVal) require.Equal(t, 9, int(outDec)) } diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index 17934465b0a..38d053540fd 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -858,7 +858,7 @@ func DeployTransferableTokenSolana( deployment.CreateLegacyChangeSet(changeset_solana.MintSolanaToken), changeset_solana.MintSolanaTokenConfig{ ChainSelector: solChainSel, - TokenPubkey: solTokenAddress, + TokenPubkey: solTokenAddress.String(), TokenProgram: deployment.SPL2022Tokens, AmountToAddress: map[string]uint64{ solDeployerKey.String(): uint64(1000), From 89569b45f9283d62ab442026577167afa5b2346a Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 16:58:09 +0000 Subject: [PATCH 09/31] bump chains/solana --- deployment/go.mod | 2 +- deployment/go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/deployment/go.mod b/deployment/go.mod index c76f91166ec..ba5aa9f73f9 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -32,7 +32,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix github.com/smartcontractkit/chain-selectors v1.0.40 github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d - github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 + github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20250211162441-3d6cea220efb github.com/smartcontractkit/chainlink-integrations/evm v0.0.0-20250211220805-23e1d9f38c6b diff --git a/deployment/go.sum b/deployment/go.sum index 2b92b0fd544..d7429b84bcf 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1130,6 +1130,8 @@ github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d h1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d/go.mod h1:Hht/OJq/PxC+gnBCIPyzHt4Otsw6mYwUVsmtOqIvlxo= github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 h1:5NagQi0BzMkxgTXO0LbGcmqr5XLhWjC6T7ZScCp86H8= github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 h1:sJGUTsyNIWsADqSDF63V3wf/tVSVM4WQSwfhQGqd2B4= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb h1:1VC/hN1ojPiEWCsjxhvcw4p1Zveo90O38VQhktvo3Ag= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb/go.mod h1:Z2e1ynSJ4pg83b4Qldbmryc5lmnrI3ojOdg1FUloa68= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20250128203428-08031923fbe5 h1:CvDfgWoLoYPapOumE/UZCplfCu5oNmy9BuH+6V6+fJ8= From 9f812a385a17ebe892d5eca59f13faf204654607 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 17:01:47 +0000 Subject: [PATCH 10/31] check for family --- .../ccip/changeset/testhelpers/test_helpers.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index 38d053540fd..e56da5e6b68 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -811,6 +811,20 @@ func DeployTransferableTokenSolana( evmTokenName string, ) (*burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, solana.PublicKey, error) { + selectorFamily, err := chainsel.GetSelectorFamily(evmChainSel) + if err != nil { + return nil, nil, solana.PublicKey{}, err + } + if selectorFamily != chainsel.FamilyEVM { + return nil, nil, solana.PublicKey{}, fmt.Errorf("evmChainSel is not an evm chain") + } + selectorFamily, err = chainsel.GetSelectorFamily(solChainSel) + if err != nil { + return nil, nil, solana.PublicKey{}, err + } + if selectorFamily != chainsel.FamilySolana { + return nil, nil, solana.PublicKey{}, fmt.Errorf("solChainSel is not a solana chain") + } state, err := changeset.LoadOnchainState(e) require.NoError(t, err) From bfb4b4dab219c55b97745f4881a1b3659bc16c17 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 17:04:33 +0000 Subject: [PATCH 11/31] remove todo --- deployment/ccip/changeset/solana/cs_solana_token.go | 1 - 1 file changed, 1 deletion(-) diff --git a/deployment/ccip/changeset/solana/cs_solana_token.go b/deployment/ccip/changeset/solana/cs_solana_token.go index a8ffe836cae..b0d016336a9 100644 --- a/deployment/ccip/changeset/solana/cs_solana_token.go +++ b/deployment/ccip/changeset/solana/cs_solana_token.go @@ -60,7 +60,6 @@ func DeploySolanaToken(e deployment.Environment, cfg DeploySolanaTokenConfig) (d if err != nil { return deployment.ChangesetOutput{}, err } - // TODO:does the mint need to be added as a signer here ? err = chain.Confirm(instructions, solCommomUtil.AddSigners(mintPrivKey)) if err != nil { e.Logger.Errorw("Failed to confirm instructions for link token deployment", "chain", chain.String(), "err", err) From d2dbd83070e7f36efe71251932dd1bb398a1d403 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 17:38:19 +0000 Subject: [PATCH 12/31] issetocr --- .../ccip/changeset/solana/cs_set_ocr3.go | 85 +++++++++++++++++-- 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_set_ocr3.go b/deployment/ccip/changeset/solana/cs_set_ocr3.go index e79c9a1239d..38a59f11170 100644 --- a/deployment/ccip/changeset/solana/cs_set_ocr3.go +++ b/deployment/ccip/changeset/solana/cs_set_ocr3.go @@ -9,11 +9,17 @@ import ( solOffRamp "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/ccip_offramp" + chain_selectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/deployment" cs "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" ) +const ( + OcrCommitPlugin uint8 = iota + OcrExecutePlugin +) + // SET OCR3 CONFIG func btoi(b bool) uint8 { if b { @@ -37,10 +43,14 @@ func SetOCR3ConfigSolana(e deployment.Environment, cfg cs.SetOCR3OffRampConfig) if err := cfg.Validate(e, state); err != nil { return deployment.ChangesetOutput{}, err } - solChains := state.SolChains - // cfg.RemoteChainSels will be a bunch of solana chains - // can add this in validate + for _, remote := range cfg.RemoteChainSels { + chainFamily, _ := chain_selectors.GetSelectorFamily(remote) + if chainFamily != chain_selectors.FamilySolana { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d is not a solana chain", remote) + } + } + for _, remote := range cfg.RemoteChainSels { donID, err := internal.DonIDForChain( state.Chains[cfg.HomeChainSel].CapabilityRegistry, @@ -53,12 +63,19 @@ func SetOCR3ConfigSolana(e deployment.Environment, cfg cs.SetOCR3OffRampConfig) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to build set ocr3 config args: %w", err) } - // TODO: check if ocr3 has already been set - // set, err := isOCR3ConfigSetSolana(e.Logger, e.Chains[remote], state.Chains[remote].OffRamp, args) + set, err := isOCR3ConfigSetOnOffRampSolana(e, e.SolChains[remote], state.SolChains[remote], args) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to check if ocr3 config is set on offramp: %w", err) + } + if set { + e.Logger.Infof("OCR3 config already set on offramp for chain %d", remote) + continue + } + var instructions []solana.Instruction - offRampConfigPDA := solChains[remote].OffRampConfigPDA - offRampStatePDA := solChains[remote].OffRampStatePDA - solOffRamp.SetProgramID(solChains[remote].OffRamp) + offRampConfigPDA := state.SolChains[remote].OffRampConfigPDA + offRampStatePDA := state.SolChains[remote].OffRampStatePDA + solOffRamp.SetProgramID(state.SolChains[remote].OffRamp) for _, arg := range args { instruction, err := solOffRamp.NewSetOcrConfigInstruction( arg.OCRPluginType, @@ -86,3 +103,55 @@ func SetOCR3ConfigSolana(e deployment.Environment, cfg cs.SetOCR3OffRampConfig) } return deployment.ChangesetOutput{}, nil } + +func isOCR3ConfigSetOnOffRampSolana( + e deployment.Environment, + chain deployment.SolChain, + chainState cs.SolCCIPChainState, + args []internal.MultiOCR3BaseOCRConfigArgsSolana, +) (bool, error) { + var configAccount solOffRamp.Config + err := chain.GetAccountDataBorshInto(e.GetContext(), chainState.OffRampConfigPDA, &configAccount) + if err != nil { + return false, fmt.Errorf("failed to get account info: %w", err) + } + for _, newState := range args { + existingState := configAccount.Ocr3[newState.OCRPluginType] + if existingState.ConfigInfo.ConfigDigest != newState.ConfigDigest { + e.Logger.Infof("OCR3 config digest mismatch") + return false, nil + } + if existingState.ConfigInfo.F != newState.F { + e.Logger.Infof("OCR3 config F mismatch") + return false, nil + } + if existingState.ConfigInfo.IsSignatureVerificationEnabled != btoi(newState.IsSignatureVerificationEnabled) { + e.Logger.Infof("OCR3 config signature verification mismatch") + return false, nil + } + if newState.OCRPluginType == uint8(OcrCommitPlugin) { + // only commit will set signers, exec doesn't need them. + if len(existingState.Signers) != len(newState.Signers) { + e.Logger.Infof("OCR3 config signers length mismatch") + return false, nil + } + for i := 0; i < len(existingState.Signers); i++ { + if existingState.Signers[i] != newState.Signers[i] { + e.Logger.Infof("OCR3 config signers mismatch") + return false, nil + } + } + } + if len(existingState.Transmitters) != len(newState.Transmitters) { + e.Logger.Infof("OCR3 config transmitters length mismatch") + return false, nil + } + for i := 0; i < len(existingState.Transmitters); i++ { + if existingState.Transmitters[i] != newState.Transmitters[i] { + e.Logger.Infof("OCR3 config transmitters mismatch") + return false, nil + } + } + } + return true, nil +} From 2bcd2bbd379a664fb49b939b70b4c933b156e8cc Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 18:29:52 +0000 Subject: [PATCH 13/31] enabling addtokenpool for wsol --- .../solana/cs_chain_contracts_test.go | 123 ++++++++++-------- .../ccip/changeset/solana/cs_token_pool.go | 27 ++-- 2 files changed, 81 insertions(+), 69 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go index 93f09cebf4e..2256e8a90eb 100644 --- a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go +++ b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go @@ -121,65 +121,74 @@ func TestAddTokenPool(t *testing.T) { state, err := ccipChangeset.LoadOnchainStateSolana(e) require.NoError(t, err) - tokenAddress := state.SolChains[solChain].SPL2022Tokens[0] - - // TODO: can test this with solana.SolMint as well (WSOL) - // https://smartcontract-it.atlassian.net/browse/INTAUTO-440 - e, err = commonchangeset.Apply(t, e, nil, - commonchangeset.Configure( - deployment.CreateLegacyChangeSet(changeset_solana.AddTokenPool), - changeset_solana.TokenPoolConfig{ - ChainSelector: solChain, - TokenPubKey: tokenAddress.String(), - TokenProgramName: deployment.SPL2022Tokens, - PoolType: solTestTokenPool.LockAndRelease_PoolType, - // this works for testing, but if we really want some other authority we need to pass in a private key for signing purposes - Authority: e.SolChains[solChain].DeployerKey.PublicKey().String(), - }, - ), - commonchangeset.Configure( - deployment.CreateLegacyChangeSet(changeset_solana.SetupTokenPoolForRemoteChain), - changeset_solana.RemoteChainTokenPoolConfig{ - SolChainSelector: solChain, - RemoteChainSelector: evmChain, - SolTokenPubKey: tokenAddress.String(), - RemoteConfig: solTestTokenPool.RemoteConfig{ - // TODO:this can be potentially read from the state if we are given the token symbol - PoolAddresses: []solTestTokenPool.RemoteAddress{{Address: []byte{1, 2, 3}}}, - TokenAddress: solTestTokenPool.RemoteAddress{Address: []byte{4, 5, 6}}, - Decimals: 9, - }, - InboundRateLimit: solTestTokenPool.RateLimitConfig{ - Enabled: true, - Capacity: uint64(1000), - Rate: 1, + newTokenAddress := state.SolChains[solChain].SPL2022Tokens[0] + + remoteConfig := solTestTokenPool.RemoteConfig{ + PoolAddresses: []solTestTokenPool.RemoteAddress{{Address: []byte{1, 2, 3}}}, + TokenAddress: solTestTokenPool.RemoteAddress{Address: []byte{4, 5, 6}}, + Decimals: 9, + } + inboundConfig := solTestTokenPool.RateLimitConfig{ + Enabled: true, + Capacity: uint64(1000), + Rate: 1, + } + outboundConfig := solTestTokenPool.RateLimitConfig{ + Enabled: false, + Capacity: 0, + Rate: 0, + } + + tokenMap := map[string]solana.PublicKey{ + deployment.SPL2022Tokens: newTokenAddress, + deployment.SPLTokens: state.SolChains[solChain].WSOL, + } + + for tokenProgramName, tokenAddress := range tokenMap { + + e, err = commonchangeset.Apply(t, e, nil, + commonchangeset.Configure( + deployment.CreateLegacyChangeSet(changeset_solana.AddTokenPool), + changeset_solana.TokenPoolConfig{ + ChainSelector: solChain, + TokenPubKey: tokenAddress.String(), + TokenProgramName: tokenProgramName, + PoolType: solTestTokenPool.LockAndRelease_PoolType, + // this works for testing, but if we really want some other authority we need to pass in a private key for signing purposes + Authority: e.SolChains[solChain].DeployerKey.PublicKey().String(), }, - OutboundRateLimit: solTestTokenPool.RateLimitConfig{ - Enabled: false, - Capacity: 0, - Rate: 0, + ), + commonchangeset.Configure( + deployment.CreateLegacyChangeSet(changeset_solana.SetupTokenPoolForRemoteChain), + changeset_solana.RemoteChainTokenPoolConfig{ + SolChainSelector: solChain, + RemoteChainSelector: evmChain, + SolTokenPubKey: tokenAddress.String(), + RemoteConfig: remoteConfig, + InboundRateLimit: inboundConfig, + OutboundRateLimit: outboundConfig, }, - }, - ), - ) - require.NoError(t, err) - - // test AddTokenPool results - poolConfigPDA, err := solTokenUtil.TokenPoolConfigAddress(tokenAddress, state.SolChains[solChain].TokenPool) - require.NoError(t, err) - var configAccount solTestTokenPool.State - err = e.SolChains[solChain].GetAccountDataBorshInto(ctx, poolConfigPDA, &configAccount) - require.NoError(t, err) - require.Equal(t, solTestTokenPool.LockAndRelease_PoolType, configAccount.PoolType) - require.Equal(t, tokenAddress, configAccount.Config.Mint) - // try minting after this and see if the pool or the deployer key is the authority - - // test SetupTokenPoolForRemoteChain results - remoteChainConfigPDA, _, _ := solTokenUtil.TokenPoolChainConfigPDA(evmChain, tokenAddress, state.SolChains[solChain].TokenPool) - var remoteChainConfigAccount solTestTokenPool.ChainConfig - err = e.SolChains[solChain].GetAccountDataBorshInto(ctx, remoteChainConfigPDA, &remoteChainConfigAccount) - require.NoError(t, err) - require.Equal(t, uint8(9), remoteChainConfigAccount.Base.Remote.Decimals) + ), + ) + require.NoError(t, err) + + // test AddTokenPool results + poolConfigPDA, err := solTokenUtil.TokenPoolConfigAddress(tokenAddress, state.SolChains[solChain].TokenPool) + require.NoError(t, err) + var configAccount solTestTokenPool.State + err = e.SolChains[solChain].GetAccountDataBorshInto(ctx, poolConfigPDA, &configAccount) + require.NoError(t, err) + require.Equal(t, solTestTokenPool.LockAndRelease_PoolType, configAccount.PoolType) + require.Equal(t, tokenAddress, configAccount.Config.Mint) + // try minting after this and see if the pool or the deployer key is the authority + + // test SetupTokenPoolForRemoteChain results + remoteChainConfigPDA, _, _ := solTokenUtil.TokenPoolChainConfigPDA(evmChain, tokenAddress, state.SolChains[solChain].TokenPool) + var remoteChainConfigAccount solTestTokenPool.ChainConfig + err = e.SolChains[solChain].GetAccountDataBorshInto(ctx, remoteChainConfigPDA, &remoteChainConfigAccount) + require.NoError(t, err) + require.Equal(t, uint8(9), remoteChainConfigAccount.Base.Remote.Decimals) + } } func TestBilling(t *testing.T) { diff --git a/deployment/ccip/changeset/solana/cs_token_pool.go b/deployment/ccip/changeset/solana/cs_token_pool.go index 34d228f08a0..5e6315eba18 100644 --- a/deployment/ccip/changeset/solana/cs_token_pool.go +++ b/deployment/ccip/changeset/solana/cs_token_pool.go @@ -93,19 +93,22 @@ func AddTokenPool(e deployment.Environment, cfg TokenPoolConfig) (deployment.Cha if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to generate instructions: %w", err) } - // make pool mint_authority for token (required for burn/mint) - // this cannot be done for WSOL - // so if we ever need a WSOL token pool, we will have to split this out to another changeset - authI, err := solTokenUtil.SetTokenMintAuthority( - tokenprogramID, - poolSigner, - tokenPubKey, - authorityPubKey, - ) - if err != nil { - return deployment.ChangesetOutput{}, fmt.Errorf("failed to generate instructions: %w", err) + + instructions := []solana.Instruction{createI, poolInitI} + + if cfg.PoolType == solTestTokenPool.BurnAndMint_PoolType && tokenPubKey != solana.SolMint { + // make pool mint_authority for token + authI, err := solTokenUtil.SetTokenMintAuthority( + tokenprogramID, + poolSigner, + tokenPubKey, + authorityPubKey, + ) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to generate instructions: %w", err) + } + instructions = append(instructions, authI) } - instructions := []solana.Instruction{createI, poolInitI, authI} // add signer here if authority is different from deployer key if err := chain.Confirm(instructions); err != nil { From 933df9498450e413d75676df698595b27e08d1ab Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 18:32:39 +0000 Subject: [PATCH 14/31] adding fee agg to state --- deployment/ccip/changeset/solana/cs_deploy_chain.go | 13 ++++++++++++- deployment/ccip/changeset/solana_state.go | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/deployment/ccip/changeset/solana/cs_deploy_chain.go b/deployment/ccip/changeset/solana/cs_deploy_chain.go index 9567757dd59..d490f5d0ae1 100644 --- a/deployment/ccip/changeset/solana/cs_deploy_chain.go +++ b/deployment/ccip/changeset/solana/cs_deploy_chain.go @@ -449,6 +449,10 @@ func (cfg SetFeeAggregatorConfig) Validate(e deployment.Environment) error { return fmt.Errorf("invalid fee aggregator address: %w", err) } + if chainState.FeeAggregator.Equals(solana.MustPublicKeyFromBase58(cfg.FeeAggregator)) { + return fmt.Errorf("fee aggregator is already set") + } + return nil } @@ -478,7 +482,14 @@ func SetFeeAggregator(e deployment.Environment, cfg SetFeeAggregatorConfig) (dep if err := chain.Confirm([]solana.Instruction{instruction}); err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm instructions: %w", err) } + newAddresses := deployment.NewMemoryAddressBook() + err = newAddresses.Save(cfg.ChainSelector, cfg.FeeAggregator, deployment.NewTypeAndVersion(changeset.FeeAggregator, deployment.Version1_0_0)) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to save address: %w", err) + } e.Logger.Infow("Set new fee aggregator", "chain", chain.String(), "fee_aggregator", feeAggregatorPubKey.String()) - return deployment.ChangesetOutput{}, nil + return deployment.ChangesetOutput{ + AddressBook: newAddresses, + }, nil } diff --git a/deployment/ccip/changeset/solana_state.go b/deployment/ccip/changeset/solana_state.go index 2bead429d46..7522d7eb4a7 100644 --- a/deployment/ccip/changeset/solana_state.go +++ b/deployment/ccip/changeset/solana_state.go @@ -19,6 +19,7 @@ var ( Receiver deployment.ContractType = "Receiver" SPL2022Tokens deployment.ContractType = "SPL2022Tokens" WSOL deployment.ContractType = "WSOL" + FeeAggregator deployment.ContractType = "FeeAggregator" // for PDAs from AddRemoteChainToSolana RemoteSource deployment.ContractType = "RemoteSource" RemoteDest deployment.ContractType = "RemoteDest" @@ -40,6 +41,8 @@ type SolCCIPChainState struct { WSOL solana.PublicKey FeeQuoter solana.PublicKey OffRamp solana.PublicKey + FeeAggregator solana.PublicKey + // PDAs to avoid redundant lookups RouterConfigPDA solana.PublicKey SourceChainStatePDAs map[uint64]solana.PublicKey // deprecated From b0c3e65c1d95470aedbad18f4a2450c4190b92dd Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Tue, 11 Feb 2025 11:54:08 +0000 Subject: [PATCH 15/31] feat: solana tooling dev --- .../workflows/build-publish-develop-pr.yml | 24 +++++++------- .../workflows/build-publish-goreleaser.yml | 8 ++--- .github/workflows/ci-core-partial.yml | 6 ++-- .github/workflows/ci-core.yml | 25 +++++++------- .github/workflows/codeql-analysis.yml | 17 +++++----- .../workflows/integration-in-memory-tests.yml | 10 +++--- .github/workflows/integration-tests.yml | 10 +++--- .github/workflows/solidity-wrappers.yml | 11 ++++--- .github/workflows/solidity.yml | 6 ++-- core/scripts/setup_testdb.sh | 2 +- shell.nix | 8 ++--- tidy.sh | 33 +++++++++++++++++++ 12 files changed, 97 insertions(+), 63 deletions(-) create mode 100755 tidy.sh diff --git a/.github/workflows/build-publish-develop-pr.yml b/.github/workflows/build-publish-develop-pr.yml index 58f5ee560a7..42cb2a2e81d 100644 --- a/.github/workflows/build-publish-develop-pr.yml +++ b/.github/workflows/build-publish-develop-pr.yml @@ -1,18 +1,18 @@ name: "Build and Publish GoReleaser" on: - pull_request: - # The default types are opened, synchronize, and reopened - # See https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request - # We add a label trigger too, since when the build-publish label is added to a PR, we want to build and publish - types: - - opened - - synchronize - - reopened - - labeled - push: - branches: - - develop + # pull_request: + # # The default types are opened, synchronize, and reopened + # # See https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request + # # We add a label trigger too, since when the build-publish label is added to a PR, we want to build and publish + # types: + # - opened + # - synchronize + # - reopened + # - labeled + # push: + # branches: + # - develop workflow_dispatch: inputs: git_ref: diff --git a/.github/workflows/build-publish-goreleaser.yml b/.github/workflows/build-publish-goreleaser.yml index 9f8f774acc0..662d84c30ac 100644 --- a/.github/workflows/build-publish-goreleaser.yml +++ b/.github/workflows/build-publish-goreleaser.yml @@ -1,10 +1,10 @@ name: "Goreleaser Chainlink" on: - push: - tags: - - "goreleaser-v*" - + # push: + # tags: + # - "goreleaser-v*" + workflow_dispatch: env: ECR_HOSTNAME: public.ecr.aws diff --git a/.github/workflows/ci-core-partial.yml b/.github/workflows/ci-core-partial.yml index 38c252bad7e..8b9788329fa 100644 --- a/.github/workflows/ci-core-partial.yml +++ b/.github/workflows/ci-core-partial.yml @@ -54,9 +54,9 @@ jobs: fail-fast: false matrix: type: - - test-suite: "core" - module-directory: "./" - build-flags: "-tags=integration" + # - test-suite: "core" + # module-directory: "./" + # build-flags: "-tags=integration" - test-suite: "ccip-deployment" module-directory: "./deployment" steps: diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 8c164840535..3a9de632b89 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -174,21 +174,20 @@ jobs: fail-fast: false matrix: type: - - cmd: go_core_tests - os: ubuntu22.04-32cores-128GB - build-solana-artifacts: 'false' - - cmd: go_core_tests_integration - os: ubuntu22.04-32cores-128GB - build-solana-artifacts: 'false' + # - cmd: go_core_tests + # os: ubuntu22.04-32cores-128GB + # printResults: true + # - cmd: go_core_tests_integration + # os: ubuntu22.04-32cores-128GB + # printResults: true - cmd: go_core_ccip_deployment_tests os: ubuntu22.04-32cores-128GB - - cmd: go_core_fuzz - os: ubuntu22.04-8cores-32GB - build-solana-artifacts: 'false' - - cmd: go_core_race_tests - # use 64cores for certain scheduled runs only - os: ${{ needs.run-frequency.outputs.two-per-day-frequency == 'true' && 'ubuntu-latest-64cores-256GB' || 'ubuntu-latest-32cores-128GB' }} - build-solana-artifacts: 'false' + printResults: true + # - cmd: go_core_fuzz + # os: ubuntu22.04-8cores-32GB + # - cmd: go_core_race_tests + # # use 64cores for certain scheduled runs only + # os: ${{ needs.run-frequency.outputs.two-per-day-frequency == 'true' && 'ubuntu-latest-64cores-256GB' || 'ubuntu-latest-32cores-128GB' }} name: Core Tests (${{ matrix.type.cmd }}) # We don't directly merge dependabot PRs, so let's not waste the resources if: ${{ github.actor != 'dependabot[bot]' }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c0294645465..ccaf2da6b1c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,14 +1,15 @@ name: 'CodeQL' on: - push: - branches: - - develop - pull_request: - # The branches below must be a subset of the branches above - branches: [develop] - schedule: - - cron: '23 19 * * 4' + # push: + # branches: + # - develop + # pull_request: + # # The branches below must be a subset of the branches above + # branches: [develop] + # schedule: + # - cron: '23 19 * * 4' + workflow_dispatch: jobs: filter: diff --git a/.github/workflows/integration-in-memory-tests.yml b/.github/workflows/integration-in-memory-tests.yml index 05337f333cd..f1ac9901e69 100644 --- a/.github/workflows/integration-in-memory-tests.yml +++ b/.github/workflows/integration-in-memory-tests.yml @@ -5,11 +5,11 @@ name: Integration In-Memory Tests run-name: Integration In-Memory Tests on: - merge_group: - pull_request: - push: - tags: - - "*" + # merge_group: + # pull_request: + # push: + # tags: + # - "*" workflow_dispatch: inputs: cl_ref: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b76fb194abe..de0aca695fe 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -3,11 +3,11 @@ name: Integration Tests run-name: Integration Tests ${{ inputs.distinct_run_name && inputs.distinct_run_name || '' }} on: - merge_group: - pull_request: - push: - tags: - - "*" + # merge_group: + # pull_request: + # push: + # tags: + # - "*" workflow_dispatch: inputs: cl_ref: diff --git a/.github/workflows/solidity-wrappers.yml b/.github/workflows/solidity-wrappers.yml index 804a6822a29..ebd4c9f45c0 100644 --- a/.github/workflows/solidity-wrappers.yml +++ b/.github/workflows/solidity-wrappers.yml @@ -3,11 +3,12 @@ name: Solidity Wrappers # used for job execution. The jobs in "solidity.yml" are configured around push events, whereas # we only want to generate gethwrappers during pull requests. on: - pull_request: - types: - - opened - - synchronize - - reopened + # pull_request: + # types: + # - opened + # - synchronize + # - reopened + workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 79afb8c1d59..3d2d3923579 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -1,9 +1,9 @@ name: Solidity on: - merge_group: - push: - + # merge_group: + # push: + workflow_dispatch: defaults: run: shell: bash diff --git a/core/scripts/setup_testdb.sh b/core/scripts/setup_testdb.sh index 85aa5812e23..f0b2a6e0647 100755 --- a/core/scripts/setup_testdb.sh +++ b/core/scripts/setup_testdb.sh @@ -6,7 +6,7 @@ function exit_error { } # Create a new user and database for development # This script is intended to be run on a local development machine -tdir=$(mktemp -d -t db-dev-user) +tdir=$(mktemp -d -t db-dev-user-XXXXXX) username="chainlink_dev" password="insecurepassword" diff --git a/shell.nix b/shell.nix index 496559b3cce..de5ac02e4e3 100644 --- a/shell.nix +++ b/shell.nix @@ -22,7 +22,7 @@ with pkgs; let autoPatchelfIgnoreMissingDeps = stdenv.isLinux; buildInputs = with pkgs; [stdenv.cc.cc.lib] ++ lib.optionals stdenv.isLinux [ stdenv.cc.cc.libgcc libudev-zero ]; - + src = pkgs.fetchzip { inherit url sha256; }; @@ -63,7 +63,7 @@ in nativeBuildInputs = [ go - postgresql + postgresql_17 python3 python3Packages.pip @@ -85,7 +85,7 @@ in gopls delve golangci-lint - github-cli + git jq # gofuzz @@ -115,4 +115,4 @@ in PGDATA = "db"; CL_DATABASE_URL = "postgresql://chainlink:chainlink@localhost:5432/chainlink_test?sslmode=disable"; - } + } \ No newline at end of file diff --git a/tidy.sh b/tidy.sh new file mode 100755 index 00000000000..1b75f4ef342 --- /dev/null +++ b/tidy.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Array of directories to process +DIRS=( + "." + "core/scripts" + "integration-tests" + "integration-tests/load" + "deployment" +) + +# Store the original directory +ORIGINAL_DIR=$(pwd) + +# Function to run go mod tidy and check for errors +run_tidy() { + local dir=$1 + echo "Running go mod tidy in $dir..." + cd "$dir" || exit 1 + if ! go mod tidy; then + echo "Error: go mod tidy failed in $dir" + cd "$ORIGINAL_DIR" + exit 1 + fi + cd "$ORIGINAL_DIR" +} + +# Process each directory +for dir in "${DIRS[@]}"; do + run_tidy "$dir" +done + +echo "All go mod tidy operations completed successfully!" \ No newline at end of file From 7815ee8000961c827359b7342344b5e896159dcf Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 18:34:00 +0000 Subject: [PATCH 16/31] tidying --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- deployment/go.sum | 2 -- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 555a6318011..014ac0d8442 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -306,7 +306,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix // indirect github.com/smartcontractkit/chain-selectors v1.0.40 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d // indirect - github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 // indirect + github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-framework/chains v0.0.0-20250207205350-420ccacab78a // indirect github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20250211162441-3d6cea220efb // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index a7817f25d0c..7f24aeafc7b 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1125,8 +1125,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d h1:XPFkOtqPtkODbFoTUP7RIb7txPAP6qjPanrRy2PD8Bc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d/go.mod h1:Hht/OJq/PxC+gnBCIPyzHt4Otsw6mYwUVsmtOqIvlxo= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 h1:5NagQi0BzMkxgTXO0LbGcmqr5XLhWjC6T7ZScCp86H8= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 h1:sJGUTsyNIWsADqSDF63V3wf/tVSVM4WQSwfhQGqd2B4= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb h1:1VC/hN1ojPiEWCsjxhvcw4p1Zveo90O38VQhktvo3Ag= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb/go.mod h1:Z2e1ynSJ4pg83b4Qldbmryc5lmnrI3ojOdg1FUloa68= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20250128203428-08031923fbe5 h1:CvDfgWoLoYPapOumE/UZCplfCu5oNmy9BuH+6V6+fJ8= diff --git a/deployment/go.sum b/deployment/go.sum index d7429b84bcf..ce04fb251bf 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1128,8 +1128,6 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d h1:XPFkOtqPtkODbFoTUP7RIb7txPAP6qjPanrRy2PD8Bc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d/go.mod h1:Hht/OJq/PxC+gnBCIPyzHt4Otsw6mYwUVsmtOqIvlxo= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 h1:5NagQi0BzMkxgTXO0LbGcmqr5XLhWjC6T7ZScCp86H8= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 h1:sJGUTsyNIWsADqSDF63V3wf/tVSVM4WQSwfhQGqd2B4= github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb h1:1VC/hN1ojPiEWCsjxhvcw4p1Zveo90O38VQhktvo3Ag= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 634f52f745f..8d5f0326838 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -427,7 +427,7 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix // indirect - github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 // indirect + github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20250128203428-08031923fbe5 // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-framework/chains v0.0.0-20250207205350-420ccacab78a // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 3f4ccc6c3fd..79f3c7090c4 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1380,8 +1380,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d h1:XPFkOtqPtkODbFoTUP7RIb7txPAP6qjPanrRy2PD8Bc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d/go.mod h1:Hht/OJq/PxC+gnBCIPyzHt4Otsw6mYwUVsmtOqIvlxo= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 h1:5NagQi0BzMkxgTXO0LbGcmqr5XLhWjC6T7ZScCp86H8= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 h1:sJGUTsyNIWsADqSDF63V3wf/tVSVM4WQSwfhQGqd2B4= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb h1:1VC/hN1ojPiEWCsjxhvcw4p1Zveo90O38VQhktvo3Ag= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb/go.mod h1:Z2e1ynSJ4pg83b4Qldbmryc5lmnrI3ojOdg1FUloa68= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20250128203428-08031923fbe5 h1:CvDfgWoLoYPapOumE/UZCplfCu5oNmy9BuH+6V6+fJ8= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 33bf319133e..34d0ea14a94 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -414,7 +414,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix // indirect github.com/smartcontractkit/chainlink-automation v0.8.1 // indirect - github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 // indirect + github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20250128203428-08031923fbe5 // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-framework/chains v0.0.0-20250207205350-420ccacab78a // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 4decd4ff1ff..cde2d1b240d 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1363,8 +1363,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d h1:XPFkOtqPtkODbFoTUP7RIb7txPAP6qjPanrRy2PD8Bc= github.com/smartcontractkit/chainlink-ccip v0.0.0-20250213125400-54af1d244d4d/go.mod h1:Hht/OJq/PxC+gnBCIPyzHt4Otsw6mYwUVsmtOqIvlxo= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7 h1:5NagQi0BzMkxgTXO0LbGcmqr5XLhWjC6T7ZScCp86H8= -github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250211204327-6aca485891a7/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1 h1:sJGUTsyNIWsADqSDF63V3wf/tVSVM4WQSwfhQGqd2B4= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20250213152537-b5aba80335b1/go.mod h1:Bmwq4lNb5tE47sydN0TKetcLEGbgl+VxHEWp4S0LI60= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb h1:1VC/hN1ojPiEWCsjxhvcw4p1Zveo90O38VQhktvo3Ag= github.com/smartcontractkit/chainlink-common v0.4.2-0.20250205141137-8f50d72601bb/go.mod h1:Z2e1ynSJ4pg83b4Qldbmryc5lmnrI3ojOdg1FUloa68= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20250128203428-08031923fbe5 h1:CvDfgWoLoYPapOumE/UZCplfCu5oNmy9BuH+6V6+fJ8= From f111442f4e38b6ea13cbfaa9b25511a0194a7fb1 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 18:45:46 +0000 Subject: [PATCH 17/31] enable src/dest solana --- .../changeset/testhelpers/test_helpers.go | 166 +++++++++--------- 1 file changed, 86 insertions(+), 80 deletions(-) diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index e56da5e6b68..f2bcbe87f16 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -428,67 +428,65 @@ func AddLane( fromFamily, _ := chainsel.GetSelectorFamily(from) toFamily, _ := chainsel.GetSelectorFamily(to) - if fromFamily != chainsel.FamilyEVM { - t.Fatalf("from family is not evm, %s", fromFamily) - } + changesets := []commoncs.ConfiguredChangeSet{} - changesets := []commoncs.ConfiguredChangeSet{ - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateOnRampsDestsChangeset), - changeset.UpdateOnRampDestsConfig{ - UpdatesByChain: map[uint64]map[uint64]changeset.OnRampDestinationUpdate{ - from: { - to: { - IsEnabled: true, - TestRouter: isTestRouter, - AllowListEnabled: false, + if fromFamily == chainsel.FamilyEVM { + evmSrcChangesets := []commoncs.ConfiguredChangeSet{ + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateOnRampsDestsChangeset), + changeset.UpdateOnRampDestsConfig{ + UpdatesByChain: map[uint64]map[uint64]changeset.OnRampDestinationUpdate{ + from: { + to: { + IsEnabled: true, + TestRouter: isTestRouter, + AllowListEnabled: false, + }, }, }, }, - }, - ), - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterPricesChangeset), - changeset.UpdateFeeQuoterPricesConfig{ - PricesByChain: map[uint64]changeset.FeeQuoterPriceUpdatePerSource{ - from: { - TokenPrices: tokenPrices, - GasPrices: gasprice, + ), + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterPricesChangeset), + changeset.UpdateFeeQuoterPricesConfig{ + PricesByChain: map[uint64]changeset.FeeQuoterPriceUpdatePerSource{ + from: { + TokenPrices: tokenPrices, + GasPrices: gasprice, + }, }, }, - }, - ), - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterDestsChangeset), - changeset.UpdateFeeQuoterDestsConfig{ - UpdatesByChain: map[uint64]map[uint64]fee_quoter.FeeQuoterDestChainConfig{ - from: { - to: fqCfg, + ), + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterDestsChangeset), + changeset.UpdateFeeQuoterDestsConfig{ + UpdatesByChain: map[uint64]map[uint64]fee_quoter.FeeQuoterDestChainConfig{ + from: { + to: fqCfg, + }, }, }, - }, - ), - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateRouterRampsChangeset), - changeset.UpdateRouterRampsConfig{ - TestRouter: isTestRouter, - UpdatesByChain: map[uint64]changeset.RouterUpdates{ - // onRamp update on source chain - from: { - OnRampUpdates: map[uint64]bool{ - to: true, + ), + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateRouterRampsChangeset), + changeset.UpdateRouterRampsConfig{ + TestRouter: isTestRouter, + UpdatesByChain: map[uint64]changeset.RouterUpdates{ + // onRamp update on source chain + from: { + OnRampUpdates: map[uint64]bool{ + to: true, + }, }, }, }, - }, - ), + ), + } + changesets = append(changesets, evmSrcChangesets...) } - require.NoError(t, err) - - switch toFamily { - case chainsel.FamilyEVM: - evmChangesets := []commoncs.ConfiguredChangeSet{ + if toFamily == chainsel.FamilyEVM { + evmDstChangesets := []commoncs.ConfiguredChangeSet{ commoncs.Configure( deployment.CreateLegacyChangeSet(changeset.UpdateOffRampSourcesChangeset), changeset.UpdateOffRampSourcesConfig{ @@ -518,44 +516,52 @@ func AddLane( }, ), } - changesets = append(changesets, evmChangesets...) - case chainsel.FamilySolana: - value := [28]uint8{} - bigNum, ok := new(big.Int).SetString("19816680000000000000", 10) - require.True(t, ok) - bigNum.FillBytes(value[:]) - solanaChangesets := []commoncs.ConfiguredChangeSet{ - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset_solana.AddRemoteChainToSolana), - changeset_solana.AddRemoteChainToSolanaConfig{ - ChainSelector: to, - UpdatesByChain: map[uint64]changeset_solana.RemoteChainConfigSolana{ - from: { - EnabledAsSource: true, - RouterDestinationConfig: solRouter.DestChainConfig{}, - FeeQuoterDestinationConfig: solFeeQuoter.DestChainConfig{ - IsEnabled: true, - DefaultTxGasLimit: 200000, - MaxPerMsgGasLimit: 3000000, - MaxDataBytes: 30000, - MaxNumberOfTokensPerMsg: 5, - DefaultTokenDestGasOverhead: 5000, - // bytes4(keccak256("CCIP ChainFamilySelector EVM")) - // TODO: do a similar test for other chain families - ChainFamilySelector: [4]uint8{40, 18, 213, 44}, - }, - }, - }, - }, - ), - } - changesets = append(changesets, solanaChangesets...) + changesets = append(changesets, evmDstChangesets...) + } + + if fromFamily == chainsel.FamilySolana { + changesets = append(changesets, addLaneSolanaChangesets(t, from, to)...) + } else if toFamily == chainsel.FamilySolana { + changesets = append(changesets, addLaneSolanaChangesets(t, to, from)...) } e.Env, err = commoncs.ApplyChangesets(t, e.Env, e.TimelockContracts(t), changesets) require.NoError(t, err) } +func addLaneSolanaChangesets(t *testing.T, solChainSelector, evmChainSelector uint64) []commoncs.ConfiguredChangeSet { + value := [28]uint8{} + bigNum, ok := new(big.Int).SetString("19816680000000000000", 10) + require.True(t, ok) + bigNum.FillBytes(value[:]) + solanaChangesets := []commoncs.ConfiguredChangeSet{ + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset_solana.AddRemoteChainToSolana), + changeset_solana.AddRemoteChainToSolanaConfig{ + ChainSelector: solChainSelector, + UpdatesByChain: map[uint64]changeset_solana.RemoteChainConfigSolana{ + evmChainSelector: { + EnabledAsSource: true, + RouterDestinationConfig: solRouter.DestChainConfig{}, + FeeQuoterDestinationConfig: solFeeQuoter.DestChainConfig{ + IsEnabled: true, + DefaultTxGasLimit: 200000, + MaxPerMsgGasLimit: 3000000, + MaxDataBytes: 30000, + MaxNumberOfTokensPerMsg: 5, + DefaultTokenDestGasOverhead: 5000, + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + // TODO: do a similar test for other chain families + ChainFamilySelector: [4]uint8{40, 18, 213, 44}, + }, + }, + }, + }, + ), + } + return solanaChangesets +} + // RemoveLane removes a lane between the source and destination chains in the deployed environment. func RemoveLane(t *testing.T, e *DeployedEnv, src, dest uint64, isTestRouter bool) { var err error From ef7b6f3aa34a62a388b6368daf9678909830b990 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 18:57:22 +0000 Subject: [PATCH 18/31] making sol addLane agnostic to fam --- .../changeset/testhelpers/test_helpers.go | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index f2bcbe87f16..f9026924247 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -520,27 +520,36 @@ func AddLane( } if fromFamily == chainsel.FamilySolana { - changesets = append(changesets, addLaneSolanaChangesets(t, from, to)...) - } else if toFamily == chainsel.FamilySolana { - changesets = append(changesets, addLaneSolanaChangesets(t, to, from)...) + changesets = append(changesets, addLaneSolanaChangesets(t, from, to, toFamily)...) + } + if toFamily == chainsel.FamilySolana { + changesets = append(changesets, addLaneSolanaChangesets(t, to, from, fromFamily)...) } e.Env, err = commoncs.ApplyChangesets(t, e.Env, e.TimelockContracts(t), changesets) require.NoError(t, err) } -func addLaneSolanaChangesets(t *testing.T, solChainSelector, evmChainSelector uint64) []commoncs.ConfiguredChangeSet { +func addLaneSolanaChangesets(t *testing.T, solChainSelector, remoteChainSelector uint64, remoteFamily string) []commoncs.ConfiguredChangeSet { value := [28]uint8{} bigNum, ok := new(big.Int).SetString("19816680000000000000", 10) require.True(t, ok) bigNum.FillBytes(value[:]) + chainFamilySelector := [4]uint8{} + if remoteFamily == chainsel.FamilyEVM { + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + chainFamilySelector = [4]uint8{40, 18, 213, 44} + } else if remoteFamily == chainsel.FamilySolana { + // bytes4(keccak256("CCIP ChainFamilySelector SVM")); + chainFamilySelector = [4]uint8{30, 16, 189, 196} + } solanaChangesets := []commoncs.ConfiguredChangeSet{ commoncs.Configure( deployment.CreateLegacyChangeSet(changeset_solana.AddRemoteChainToSolana), changeset_solana.AddRemoteChainToSolanaConfig{ ChainSelector: solChainSelector, UpdatesByChain: map[uint64]changeset_solana.RemoteChainConfigSolana{ - evmChainSelector: { + remoteChainSelector: { EnabledAsSource: true, RouterDestinationConfig: solRouter.DestChainConfig{}, FeeQuoterDestinationConfig: solFeeQuoter.DestChainConfig{ @@ -550,9 +559,7 @@ func addLaneSolanaChangesets(t *testing.T, solChainSelector, evmChainSelector ui MaxDataBytes: 30000, MaxNumberOfTokensPerMsg: 5, DefaultTokenDestGasOverhead: 5000, - // bytes4(keccak256("CCIP ChainFamilySelector EVM")) - // TODO: do a similar test for other chain families - ChainFamilySelector: [4]uint8{40, 18, 213, 44}, + ChainFamilySelector: chainFamilySelector, }, }, }, From efa54a2dd79bac1c9fdcf5c484e9a6a64e4bf73a Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 21:08:23 +0000 Subject: [PATCH 19/31] lint --- deployment/ccip/changeset/solana/cs_chain_contracts_test.go | 1 - deployment/ccip/changeset/solana/cs_deploy_chain.go | 2 +- deployment/ccip/changeset/solana/cs_set_ocr3.go | 6 ++---- deployment/ccip/changeset/solana/cs_solana_token.go | 1 - deployment/ccip/changeset/solana_state.go | 3 +++ deployment/ccip/changeset/testhelpers/test_helpers.go | 4 ++-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go index 2256e8a90eb..d4b2a841e3d 100644 --- a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go +++ b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go @@ -145,7 +145,6 @@ func TestAddTokenPool(t *testing.T) { } for tokenProgramName, tokenAddress := range tokenMap { - e, err = commonchangeset.Apply(t, e, nil, commonchangeset.Configure( deployment.CreateLegacyChangeSet(changeset_solana.AddTokenPool), diff --git a/deployment/ccip/changeset/solana/cs_deploy_chain.go b/deployment/ccip/changeset/solana/cs_deploy_chain.go index d490f5d0ae1..b69ead5d765 100644 --- a/deployment/ccip/changeset/solana/cs_deploy_chain.go +++ b/deployment/ccip/changeset/solana/cs_deploy_chain.go @@ -450,7 +450,7 @@ func (cfg SetFeeAggregatorConfig) Validate(e deployment.Environment) error { } if chainState.FeeAggregator.Equals(solana.MustPublicKeyFromBase58(cfg.FeeAggregator)) { - return fmt.Errorf("fee aggregator is already set") + return fmt.Errorf("fee aggregator %s is already set on chain %d", cfg.FeeAggregator, cfg.ChainSelector) } return nil diff --git a/deployment/ccip/changeset/solana/cs_set_ocr3.go b/deployment/ccip/changeset/solana/cs_set_ocr3.go index 38a59f11170..1dd2145b920 100644 --- a/deployment/ccip/changeset/solana/cs_set_ocr3.go +++ b/deployment/ccip/changeset/solana/cs_set_ocr3.go @@ -3,13 +3,11 @@ package solana import ( "fmt" - // "strconv" - "github.com/gagliardetto/solana-go" + chain_selectors "github.com/smartcontractkit/chain-selectors" solOffRamp "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/ccip_offramp" - chain_selectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/deployment" cs "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" @@ -129,7 +127,7 @@ func isOCR3ConfigSetOnOffRampSolana( e.Logger.Infof("OCR3 config signature verification mismatch") return false, nil } - if newState.OCRPluginType == uint8(OcrCommitPlugin) { + if newState.OCRPluginType == OcrCommitPlugin { // only commit will set signers, exec doesn't need them. if len(existingState.Signers) != len(newState.Signers) { e.Logger.Infof("OCR3 config signers length mismatch") diff --git a/deployment/ccip/changeset/solana/cs_solana_token.go b/deployment/ccip/changeset/solana/cs_solana_token.go index b0d016336a9..fb16c125944 100644 --- a/deployment/ccip/changeset/solana/cs_solana_token.go +++ b/deployment/ccip/changeset/solana/cs_solana_token.go @@ -98,7 +98,6 @@ func (cfg MintSolanaTokenConfig) Validate(e deployment.Environment) error { return err } - //validation accountInfo, err := chain.Client.GetAccountInfoWithOpts(e.GetContext(), tokenAddress, &rpc.GetAccountInfoOpts{ Commitment: deployment.SolDefaultCommitment, }) diff --git a/deployment/ccip/changeset/solana_state.go b/deployment/ccip/changeset/solana_state.go index 7522d7eb4a7..5313cd59773 100644 --- a/deployment/ccip/changeset/solana_state.go +++ b/deployment/ccip/changeset/solana_state.go @@ -156,6 +156,9 @@ func LoadChainStateSolana(chain deployment.SolChain, addresses map[string]deploy return state, err } state.OffRampStatePDA = offRampStatePDA + case FeeAggregator: + pub := solana.MustPublicKeyFromBase58(address) + state.FeeAggregator = pub default: return state, fmt.Errorf("unknown contract %s", tvStr) } diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index f9026924247..335c767e3b5 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -829,14 +829,14 @@ func DeployTransferableTokenSolana( return nil, nil, solana.PublicKey{}, err } if selectorFamily != chainsel.FamilyEVM { - return nil, nil, solana.PublicKey{}, fmt.Errorf("evmChainSel is not an evm chain") + return nil, nil, solana.PublicKey{}, fmt.Errorf("evmChainSel %d is not an evm chain", evmChainSel) } selectorFamily, err = chainsel.GetSelectorFamily(solChainSel) if err != nil { return nil, nil, solana.PublicKey{}, err } if selectorFamily != chainsel.FamilySolana { - return nil, nil, solana.PublicKey{}, fmt.Errorf("solChainSel is not a solana chain") + return nil, nil, solana.PublicKey{}, fmt.Errorf("solChainSel %d is not a solana chain", solChainSel) } state, err := changeset.LoadOnchainState(e) require.NoError(t, err) From 315659cae9479bba0a9bbc7b98206f4918047574 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Thu, 13 Feb 2025 21:26:16 +0000 Subject: [PATCH 20/31] Revert "feat: solana tooling dev" This reverts commit 6bb66ee88c31b081d1e2c740f07fc3fd61502a3a. --- .../workflows/build-publish-develop-pr.yml | 24 +++++++------- .../workflows/build-publish-goreleaser.yml | 8 ++--- .github/workflows/ci-core-partial.yml | 6 ++-- .github/workflows/ci-core.yml | 22 ++++++------- .github/workflows/codeql-analysis.yml | 17 +++++----- .../workflows/integration-in-memory-tests.yml | 10 +++--- .github/workflows/integration-tests.yml | 10 +++--- .github/workflows/solidity-wrappers.yml | 11 +++---- .github/workflows/solidity.yml | 6 ++-- core/scripts/setup_testdb.sh | 2 +- shell.nix | 8 ++--- tidy.sh | 33 ------------------- 12 files changed, 61 insertions(+), 96 deletions(-) delete mode 100755 tidy.sh diff --git a/.github/workflows/build-publish-develop-pr.yml b/.github/workflows/build-publish-develop-pr.yml index 42cb2a2e81d..58f5ee560a7 100644 --- a/.github/workflows/build-publish-develop-pr.yml +++ b/.github/workflows/build-publish-develop-pr.yml @@ -1,18 +1,18 @@ name: "Build and Publish GoReleaser" on: - # pull_request: - # # The default types are opened, synchronize, and reopened - # # See https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request - # # We add a label trigger too, since when the build-publish label is added to a PR, we want to build and publish - # types: - # - opened - # - synchronize - # - reopened - # - labeled - # push: - # branches: - # - develop + pull_request: + # The default types are opened, synchronize, and reopened + # See https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request + # We add a label trigger too, since when the build-publish label is added to a PR, we want to build and publish + types: + - opened + - synchronize + - reopened + - labeled + push: + branches: + - develop workflow_dispatch: inputs: git_ref: diff --git a/.github/workflows/build-publish-goreleaser.yml b/.github/workflows/build-publish-goreleaser.yml index 662d84c30ac..9f8f774acc0 100644 --- a/.github/workflows/build-publish-goreleaser.yml +++ b/.github/workflows/build-publish-goreleaser.yml @@ -1,10 +1,10 @@ name: "Goreleaser Chainlink" on: - # push: - # tags: - # - "goreleaser-v*" - workflow_dispatch: + push: + tags: + - "goreleaser-v*" + env: ECR_HOSTNAME: public.ecr.aws diff --git a/.github/workflows/ci-core-partial.yml b/.github/workflows/ci-core-partial.yml index 8b9788329fa..38c252bad7e 100644 --- a/.github/workflows/ci-core-partial.yml +++ b/.github/workflows/ci-core-partial.yml @@ -54,9 +54,9 @@ jobs: fail-fast: false matrix: type: - # - test-suite: "core" - # module-directory: "./" - # build-flags: "-tags=integration" + - test-suite: "core" + module-directory: "./" + build-flags: "-tags=integration" - test-suite: "ccip-deployment" module-directory: "./deployment" steps: diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 3a9de632b89..ab03b5212f5 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -174,20 +174,20 @@ jobs: fail-fast: false matrix: type: - # - cmd: go_core_tests - # os: ubuntu22.04-32cores-128GB - # printResults: true - # - cmd: go_core_tests_integration - # os: ubuntu22.04-32cores-128GB - # printResults: true + - cmd: go_core_tests + os: ubuntu22.04-32cores-128GB + printResults: true + - cmd: go_core_tests_integration + os: ubuntu22.04-32cores-128GB + printResults: true - cmd: go_core_ccip_deployment_tests os: ubuntu22.04-32cores-128GB printResults: true - # - cmd: go_core_fuzz - # os: ubuntu22.04-8cores-32GB - # - cmd: go_core_race_tests - # # use 64cores for certain scheduled runs only - # os: ${{ needs.run-frequency.outputs.two-per-day-frequency == 'true' && 'ubuntu-latest-64cores-256GB' || 'ubuntu-latest-32cores-128GB' }} + - cmd: go_core_fuzz + os: ubuntu22.04-8cores-32GB + - cmd: go_core_race_tests + # use 64cores for certain scheduled runs only + os: ${{ needs.run-frequency.outputs.two-per-day-frequency == 'true' && 'ubuntu-latest-64cores-256GB' || 'ubuntu-latest-32cores-128GB' }} name: Core Tests (${{ matrix.type.cmd }}) # We don't directly merge dependabot PRs, so let's not waste the resources if: ${{ github.actor != 'dependabot[bot]' }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ccaf2da6b1c..c0294645465 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,15 +1,14 @@ name: 'CodeQL' on: - # push: - # branches: - # - develop - # pull_request: - # # The branches below must be a subset of the branches above - # branches: [develop] - # schedule: - # - cron: '23 19 * * 4' - workflow_dispatch: + push: + branches: + - develop + pull_request: + # The branches below must be a subset of the branches above + branches: [develop] + schedule: + - cron: '23 19 * * 4' jobs: filter: diff --git a/.github/workflows/integration-in-memory-tests.yml b/.github/workflows/integration-in-memory-tests.yml index f1ac9901e69..05337f333cd 100644 --- a/.github/workflows/integration-in-memory-tests.yml +++ b/.github/workflows/integration-in-memory-tests.yml @@ -5,11 +5,11 @@ name: Integration In-Memory Tests run-name: Integration In-Memory Tests on: - # merge_group: - # pull_request: - # push: - # tags: - # - "*" + merge_group: + pull_request: + push: + tags: + - "*" workflow_dispatch: inputs: cl_ref: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index de0aca695fe..b76fb194abe 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -3,11 +3,11 @@ name: Integration Tests run-name: Integration Tests ${{ inputs.distinct_run_name && inputs.distinct_run_name || '' }} on: - # merge_group: - # pull_request: - # push: - # tags: - # - "*" + merge_group: + pull_request: + push: + tags: + - "*" workflow_dispatch: inputs: cl_ref: diff --git a/.github/workflows/solidity-wrappers.yml b/.github/workflows/solidity-wrappers.yml index ebd4c9f45c0..804a6822a29 100644 --- a/.github/workflows/solidity-wrappers.yml +++ b/.github/workflows/solidity-wrappers.yml @@ -3,12 +3,11 @@ name: Solidity Wrappers # used for job execution. The jobs in "solidity.yml" are configured around push events, whereas # we only want to generate gethwrappers during pull requests. on: - # pull_request: - # types: - # - opened - # - synchronize - # - reopened - workflow_dispatch: + pull_request: + types: + - opened + - synchronize + - reopened concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 3d2d3923579..79afb8c1d59 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -1,9 +1,9 @@ name: Solidity on: - # merge_group: - # push: - workflow_dispatch: + merge_group: + push: + defaults: run: shell: bash diff --git a/core/scripts/setup_testdb.sh b/core/scripts/setup_testdb.sh index f0b2a6e0647..85aa5812e23 100755 --- a/core/scripts/setup_testdb.sh +++ b/core/scripts/setup_testdb.sh @@ -6,7 +6,7 @@ function exit_error { } # Create a new user and database for development # This script is intended to be run on a local development machine -tdir=$(mktemp -d -t db-dev-user-XXXXXX) +tdir=$(mktemp -d -t db-dev-user) username="chainlink_dev" password="insecurepassword" diff --git a/shell.nix b/shell.nix index de5ac02e4e3..496559b3cce 100644 --- a/shell.nix +++ b/shell.nix @@ -22,7 +22,7 @@ with pkgs; let autoPatchelfIgnoreMissingDeps = stdenv.isLinux; buildInputs = with pkgs; [stdenv.cc.cc.lib] ++ lib.optionals stdenv.isLinux [ stdenv.cc.cc.libgcc libudev-zero ]; - + src = pkgs.fetchzip { inherit url sha256; }; @@ -63,7 +63,7 @@ in nativeBuildInputs = [ go - postgresql_17 + postgresql python3 python3Packages.pip @@ -85,7 +85,7 @@ in gopls delve golangci-lint - git + github-cli jq # gofuzz @@ -115,4 +115,4 @@ in PGDATA = "db"; CL_DATABASE_URL = "postgresql://chainlink:chainlink@localhost:5432/chainlink_test?sslmode=disable"; - } \ No newline at end of file + } diff --git a/tidy.sh b/tidy.sh deleted file mode 100755 index 1b75f4ef342..00000000000 --- a/tidy.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -# Array of directories to process -DIRS=( - "." - "core/scripts" - "integration-tests" - "integration-tests/load" - "deployment" -) - -# Store the original directory -ORIGINAL_DIR=$(pwd) - -# Function to run go mod tidy and check for errors -run_tidy() { - local dir=$1 - echo "Running go mod tidy in $dir..." - cd "$dir" || exit 1 - if ! go mod tidy; then - echo "Error: go mod tidy failed in $dir" - cd "$ORIGINAL_DIR" - exit 1 - fi - cd "$ORIGINAL_DIR" -} - -# Process each directory -for dir in "${DIRS[@]}"; do - run_tidy "$dir" -done - -echo "All go mod tidy operations completed successfully!" \ No newline at end of file From 9c6497b65e5c3526df2888c22bf06e19ae5ad056 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 14 Feb 2025 12:36:19 +0000 Subject: [PATCH 21/31] fixing --- .github/workflows/ci-core.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index ab03b5212f5..8c164840535 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -176,18 +176,19 @@ jobs: type: - cmd: go_core_tests os: ubuntu22.04-32cores-128GB - printResults: true + build-solana-artifacts: 'false' - cmd: go_core_tests_integration os: ubuntu22.04-32cores-128GB - printResults: true + build-solana-artifacts: 'false' - cmd: go_core_ccip_deployment_tests os: ubuntu22.04-32cores-128GB - printResults: true - cmd: go_core_fuzz os: ubuntu22.04-8cores-32GB + build-solana-artifacts: 'false' - cmd: go_core_race_tests # use 64cores for certain scheduled runs only os: ${{ needs.run-frequency.outputs.two-per-day-frequency == 'true' && 'ubuntu-latest-64cores-256GB' || 'ubuntu-latest-32cores-128GB' }} + build-solana-artifacts: 'false' name: Core Tests (${{ matrix.type.cmd }}) # We don't directly merge dependabot PRs, so let's not waste the resources if: ${{ github.actor != 'dependabot[bot]' }} From e3314a716ba592858332977b3b471546f0418d00 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 14 Feb 2025 12:50:13 +0000 Subject: [PATCH 22/31] adding todos --- deployment/ccip/changeset/cs_chain_contracts.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deployment/ccip/changeset/cs_chain_contracts.go b/deployment/ccip/changeset/cs_chain_contracts.go index 26c78f1a2fd..1b2f2a9e214 100644 --- a/deployment/ccip/changeset/cs_chain_contracts.go +++ b/deployment/ccip/changeset/cs_chain_contracts.go @@ -1083,12 +1083,14 @@ func UpdateOffRampSourcesChangeset(e deployment.Environment, cfg UpdateOffRampSo offRamp := state.Chains[chainSel].OffRamp var args []offramp.OffRampSourceChainConfigArgs for source, update := range updates { + // TODO: this needs to change for solana router := common.HexToAddress("0x0") if update.TestRouter { router = state.Chains[chainSel].TestRouter.Address() } else { router = state.Chains[chainSel].Router.Address() } + // TODO: this needs to change for solana onRamp := state.Chains[source].OnRamp args = append(args, offramp.OffRampSourceChainConfigArgs{ SourceChainSelector: source, From 659f04e4276fbced150c99acd9d1ed4f37a2afb5 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 14 Feb 2025 14:01:41 +0000 Subject: [PATCH 23/31] enabling sol -> evm --- deployment/ccip/changeset/cs_ccip_home.go | 4 +- .../ccip/changeset/cs_chain_contracts.go | 32 +++++----- .../changeset/solana/cs_add_remote_chain.go | 21 +++++-- deployment/ccip/changeset/state.go | 61 ++++++++++++++++--- .../changeset/testhelpers/test_helpers.go | 24 +++++--- 5 files changed, 105 insertions(+), 37 deletions(-) diff --git a/deployment/ccip/changeset/cs_ccip_home.go b/deployment/ccip/changeset/cs_ccip_home.go index 1303800c4e0..3e3bfc3381e 100644 --- a/deployment/ccip/changeset/cs_ccip_home.go +++ b/deployment/ccip/changeset/cs_ccip_home.go @@ -307,7 +307,7 @@ func (p PromoteCandidateChangesetConfig) Validate(e deployment.Environment) (map if err := deployment.IsValidChainSelector(chainSelector); err != nil { return nil, fmt.Errorf("don chain selector invalid: %w", err) } - if err := state.ValidateOffRamp(chainSelector); err != nil { + if err := state.ValidateRamp(chainSelector, OffRamp); err != nil { return nil, err } @@ -461,7 +461,7 @@ func (p SetCandidatePluginInfo) Validate(state CCIPOnChainState, homeChain uint6 if err := deployment.IsValidChainSelector(chainSelector); err != nil { return fmt.Errorf("don chain selector invalid: %w", err) } - if err := state.ValidateOffRamp(chainSelector); err != nil { + if err := state.ValidateRamp(chainSelector, OffRamp); err != nil { return err } if p.PluginType == types.PluginTypeCCIPCommit && params.CommitOffChainConfig == nil { diff --git a/deployment/ccip/changeset/cs_chain_contracts.go b/deployment/ccip/changeset/cs_chain_contracts.go index 6eefe81f2fb..fb33b6bfb56 100644 --- a/deployment/ccip/changeset/cs_chain_contracts.go +++ b/deployment/ccip/changeset/cs_chain_contracts.go @@ -1040,11 +1040,9 @@ func (cfg UpdateOffRampSourcesConfig) Validate(e deployment.Environment, state C if source == chainSel { return fmt.Errorf("cannot update offramp source to the same chain %d", source) } - sourceChain := state.Chains[source] - // Source chain must have the onramp deployed. - // Note this also validates the specified source selector. - if sourceChain.OnRamp == nil { - return fmt.Errorf("missing onramp for source %d", source) + + if err := state.ValidateRamp(source, OnRamp); err != nil { + return err } } } @@ -1072,21 +1070,28 @@ func UpdateOffRampSourcesChangeset(e deployment.Environment, cfg UpdateOffRampSo offRamp := state.Chains[chainSel].OffRamp var args []offramp.OffRampSourceChainConfigArgs for source, update := range updates { - // TODO: this needs to change for solana router := common.HexToAddress("0x0") if update.TestRouter { router = state.Chains[chainSel].TestRouter.Address() } else { router = state.Chains[chainSel].Router.Address() } - // TODO: this needs to change for solana - onRamp := state.Chains[source].OnRamp + sourceChainFamily, _ := chain_selectors.GetSelectorFamily(source) + + onRampBytes := []byte{} + if sourceChainFamily == chain_selectors.FamilyEVM { + onRampBytes = state.Chains[source].OnRamp.Address().Bytes() + } else if sourceChainFamily == chain_selectors.FamilySolana { + // for solana the router contract has the onramp logic + onRampBytes = state.SolChains[source].Router.Bytes() + } + args = append(args, offramp.OffRampSourceChainConfigArgs{ SourceChainSelector: source, Router: router, IsEnabled: update.IsEnabled, // TODO: how would this work when the onRamp is nonEVM? - OnRamp: common.LeftPadBytes(onRamp.Address().Bytes(), 32), + OnRamp: common.LeftPadBytes(onRampBytes, 32), IsRMNVerificationDisabled: update.IsRMNVerificationDisabled, }) } @@ -1183,11 +1188,8 @@ func (cfg UpdateRouterRampsConfig) Validate(e deployment.Environment, state CCIP if source == chainSel { return fmt.Errorf("cannot update offramp source to the same chain %d", source) } - sourceChain := state.Chains[source] - // Source chain must have the onramp deployed. - // Note this also validates the specified source selector. - if sourceChain.OnRamp == nil { - return fmt.Errorf("missing onramp for source %d", source) + if err := state.ValidateRamp(source, OnRamp); err != nil { + return err } } for destination := range update.OnRampUpdates { @@ -1198,7 +1200,7 @@ func (cfg UpdateRouterRampsConfig) Validate(e deployment.Environment, state CCIP if destination == chainSel { return fmt.Errorf("cannot update onRamp dest to the same chain %d", destination) } - if err := state.ValidateOffRamp(destination); err != nil { + if err := state.ValidateRamp(destination, OffRamp); err != nil { return err } } diff --git a/deployment/ccip/changeset/solana/cs_add_remote_chain.go b/deployment/ccip/changeset/solana/cs_add_remote_chain.go index 2053ff32c0d..8d027e91227 100644 --- a/deployment/ccip/changeset/solana/cs_add_remote_chain.go +++ b/deployment/ccip/changeset/solana/cs_add_remote_chain.go @@ -71,8 +71,20 @@ func (cfg AddRemoteChainToSolanaConfig) Validate(e deployment.Environment) error if remote == routerConfigAccount.SvmChainSelector { return fmt.Errorf("cannot add remote chain %d with same chain selector as current chain %d", remote, cfg.ChainSelector) } - } + if err := state.ValidateRamp(remote, cs.OnRamp); err != nil { + return err + } + routerDestChainPDA, err := solState.FindDestChainStatePDA(remote, chainState.Router) + if err != nil { + return fmt.Errorf("failed to find dest chain state pda for remote chain %d: %w", remote, err) + } + var destChainStateAccount solRouter.DestChain + err = chain.GetAccountDataBorshInto(context.Background(), routerDestChainPDA, &destChainStateAccount) + if err == nil { + return fmt.Errorf("remote %d is already configured on solana chain %d", remote, cfg.ChainSelector) + } + } return nil } @@ -113,12 +125,11 @@ func doAddRemoteChainToSolana( remoteChainFamily, _ := chainsel.GetSelectorFamily(remoteChainSel) switch remoteChainFamily { case chainsel.FamilySolana: - return fmt.Errorf("support for solana chain as remote chain is not implemented yet %d", remoteChainSel) + onRampAddress := s.SolChains[remoteChainSel].Router.String() + addressBytes := []byte(onRampAddress) + copy(onRampBytes[:], addressBytes) case chainsel.FamilyEVM: onRampAddress := s.Chains[remoteChainSel].OnRamp.Address().String() - if onRampAddress == "" { - return fmt.Errorf("onramp address not found for chain %d", remoteChainSel) - } addressBytes := []byte(onRampAddress) copy(onRampBytes[:], addressBytes) } diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index a38949c320a..2aa4e92604c 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -812,7 +812,37 @@ func LoadChainState(ctx context.Context, chain deployment.Chain, addresses map[s return state, nil } -func (s CCIPOnChainState) ValidateOffRamp(chainSelector uint64) error { +// func (s CCIPOnChainState) ValidateOffRamp(chainSelector uint64) error { +// family, err := chain_selectors.GetSelectorFamily(chainSelector) +// if err != nil { +// return err +// } +// switch family { +// case chain_selectors.FamilyEVM: +// chainState, exists := s.Chains[chainSelector] +// if !exists { +// return fmt.Errorf("chain %d does not exist", chainSelector) +// } +// if chainState.OffRamp == nil { +// // should not be possible, but a defensive check. +// return fmt.Errorf("OffRamp contract does not exist on chain %d", chainSelector) +// } +// case chain_selectors.FamilySolana: +// chainState, exists := s.SolChains[chainSelector] +// if !exists { +// return fmt.Errorf("chain %d does not exist", chainSelector) +// } +// if chainState.OffRamp.IsZero() { +// // should not be possible, but a defensive check. +// return fmt.Errorf("CCIP offramp contract does not exist on chain %d", chainSelector) +// } +// default: +// return fmt.Errorf("unknown chain family %s", family) +// } +// return nil +// } + +func (s CCIPOnChainState) ValidateRamp(chainSelector uint64, rampType deployment.ContractType) error { family, err := chain_selectors.GetSelectorFamily(chainSelector) if err != nil { return err @@ -823,18 +853,35 @@ func (s CCIPOnChainState) ValidateOffRamp(chainSelector uint64) error { if !exists { return fmt.Errorf("chain %d does not exist", chainSelector) } - if chainState.OffRamp == nil { - // should not be possible, but a defensive check. - return fmt.Errorf("OffRamp contract does not exist on chain %d", chainSelector) + if rampType == OffRamp { + if chainState.OffRamp == nil { + // should not be possible, but a defensive check. + return fmt.Errorf("offramp contract does not exist on evm chain %d", chainSelector) + } + } else if rampType == OnRamp { + if chainState.OnRamp == nil { + return fmt.Errorf("onramp contract does not exist on evm chain %d", chainSelector) + } + } else { + return fmt.Errorf("unknown ramp type %s", rampType) } + case chain_selectors.FamilySolana: chainState, exists := s.SolChains[chainSelector] if !exists { return fmt.Errorf("chain %d does not exist", chainSelector) } - if chainState.Router.IsZero() { - // should not be possible, but a defensive check. - return fmt.Errorf("CCIP router contract does not exist on chain %d", chainSelector) + if rampType == OffRamp { + if chainState.OffRamp.IsZero() { + // should not be possible, but a defensive check. + return fmt.Errorf("offramp contract does not exist on solana chain %d", chainSelector) + } + } else if rampType == OnRamp { + if chainState.Router.IsZero() { + return fmt.Errorf("router contract does not exist on solana chain %d", chainSelector) + } + } else { + return fmt.Errorf("unknown ramp type %s", rampType) } default: return fmt.Errorf("unknown chain family %s", family) diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index 335c767e3b5..a327eeef53a 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -424,7 +424,6 @@ func AddLane( ) { var err error - // from family fromFamily, _ := chainsel.GetSelectorFamily(from) toFamily, _ := chainsel.GetSelectorFamily(to) @@ -485,6 +484,7 @@ func AddLane( changesets = append(changesets, evmSrcChangesets...) } + fmt.Println("e.RmnEnabledSourceChains[from]", e.RmnEnabledSourceChains[from]) if toFamily == chainsel.FamilyEVM { evmDstChangesets := []commoncs.ConfiguredChangeSet{ commoncs.Configure( @@ -616,18 +616,26 @@ func RemoveLane(t *testing.T, e *DeployedEnv, src, dest uint64, isTestRouter boo } func AddLaneWithDefaultPricesAndFeeQuoterConfig(t *testing.T, e *DeployedEnv, state changeset.CCIPOnChainState, from, to uint64, isTestRouter bool) { - stateChainFrom := state.Chains[from] + + gasPrices := map[uint64]*big.Int{ + to: DefaultGasPrice, + } + fromFamily, _ := chainsel.GetSelectorFamily(from) + tokenPrices := map[common.Address]*big.Int{} + if fromFamily == chainsel.FamilyEVM { + stateChainFrom := state.Chains[from] + tokenPrices = map[common.Address]*big.Int{ + stateChainFrom.LinkToken.Address(): DefaultLinkPrice, + stateChainFrom.Weth9.Address(): DefaultWethPrice, + } + } + fqCfg := changeset.DefaultFeeQuoterDestChainConfig(true, to) AddLane( t, e, from, to, isTestRouter, - map[uint64]*big.Int{ - to: DefaultGasPrice, - }, map[common.Address]*big.Int{ - stateChainFrom.LinkToken.Address(): DefaultLinkPrice, - stateChainFrom.Weth9.Address(): DefaultWethPrice, - }, changeset.DefaultFeeQuoterDestChainConfig(true, to)) + gasPrices, tokenPrices, fqCfg) } // AddLanesForAll adds densely connected lanes for all chains in the environment so that each chain From 243089fcf3ce22571efb3500703dd3f5a2e1efc3 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 14 Feb 2025 14:11:31 +0000 Subject: [PATCH 24/31] removing commented func --- deployment/ccip/changeset/state.go | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 2aa4e92604c..5bc17360dc2 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -812,36 +812,6 @@ func LoadChainState(ctx context.Context, chain deployment.Chain, addresses map[s return state, nil } -// func (s CCIPOnChainState) ValidateOffRamp(chainSelector uint64) error { -// family, err := chain_selectors.GetSelectorFamily(chainSelector) -// if err != nil { -// return err -// } -// switch family { -// case chain_selectors.FamilyEVM: -// chainState, exists := s.Chains[chainSelector] -// if !exists { -// return fmt.Errorf("chain %d does not exist", chainSelector) -// } -// if chainState.OffRamp == nil { -// // should not be possible, but a defensive check. -// return fmt.Errorf("OffRamp contract does not exist on chain %d", chainSelector) -// } -// case chain_selectors.FamilySolana: -// chainState, exists := s.SolChains[chainSelector] -// if !exists { -// return fmt.Errorf("chain %d does not exist", chainSelector) -// } -// if chainState.OffRamp.IsZero() { -// // should not be possible, but a defensive check. -// return fmt.Errorf("CCIP offramp contract does not exist on chain %d", chainSelector) -// } -// default: -// return fmt.Errorf("unknown chain family %s", family) -// } -// return nil -// } - func (s CCIPOnChainState) ValidateRamp(chainSelector uint64, rampType deployment.ContractType) error { family, err := chain_selectors.GetSelectorFamily(chainSelector) if err != nil { From e69844ec41b334a200774a1ea19a940b0be787a8 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 14 Feb 2025 15:12:13 +0000 Subject: [PATCH 25/31] lint --- .../changeset/solana/cs_add_remote_chain.go | 1 - deployment/ccip/changeset/state.go | 28 ++++++------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_add_remote_chain.go b/deployment/ccip/changeset/solana/cs_add_remote_chain.go index 8d027e91227..34117b8fa69 100644 --- a/deployment/ccip/changeset/solana/cs_add_remote_chain.go +++ b/deployment/ccip/changeset/solana/cs_add_remote_chain.go @@ -83,7 +83,6 @@ func (cfg AddRemoteChainToSolanaConfig) Validate(e deployment.Environment) error if err == nil { return fmt.Errorf("remote %d is already configured on solana chain %d", remote, cfg.ChainSelector) } - } return nil } diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 5bc17360dc2..46ffb36f7d9 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -823,15 +823,10 @@ func (s CCIPOnChainState) ValidateRamp(chainSelector uint64, rampType deployment if !exists { return fmt.Errorf("chain %d does not exist", chainSelector) } - if rampType == OffRamp { - if chainState.OffRamp == nil { - // should not be possible, but a defensive check. - return fmt.Errorf("offramp contract does not exist on evm chain %d", chainSelector) - } - } else if rampType == OnRamp { - if chainState.OnRamp == nil { - return fmt.Errorf("onramp contract does not exist on evm chain %d", chainSelector) - } + if rampType == OffRamp && chainState.OffRamp == nil { + return fmt.Errorf("offramp contract does not exist on evm chain %d", chainSelector) + } else if rampType == OnRamp && chainState.OnRamp == nil { + return fmt.Errorf("onramp contract does not exist on evm chain %d", chainSelector) } else { return fmt.Errorf("unknown ramp type %s", rampType) } @@ -841,22 +836,17 @@ func (s CCIPOnChainState) ValidateRamp(chainSelector uint64, rampType deployment if !exists { return fmt.Errorf("chain %d does not exist", chainSelector) } - if rampType == OffRamp { - if chainState.OffRamp.IsZero() { - // should not be possible, but a defensive check. - return fmt.Errorf("offramp contract does not exist on solana chain %d", chainSelector) - } - } else if rampType == OnRamp { - if chainState.Router.IsZero() { - return fmt.Errorf("router contract does not exist on solana chain %d", chainSelector) - } + if rampType == OffRamp && chainState.OffRamp.IsZero() { + return fmt.Errorf("offramp contract does not exist on solana chain %d", chainSelector) + } else if rampType == OnRamp && chainState.Router.IsZero() { + return fmt.Errorf("router contract does not exist on solana chain %d", chainSelector) } else { return fmt.Errorf("unknown ramp type %s", rampType) } + default: return fmt.Errorf("unknown chain family %s", family) } - return nil } func ValidateChain(env deployment.Environment, state CCIPOnChainState, chainSel uint64, checkMcms bool) error { From 1f6dd174ebc192202d155b902b708af113557a55 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Fri, 14 Feb 2025 16:33:02 +0000 Subject: [PATCH 26/31] bug --- deployment/ccip/changeset/state.go | 31 ++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 46ffb36f7d9..7500c55d6ce 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -823,11 +823,16 @@ func (s CCIPOnChainState) ValidateRamp(chainSelector uint64, rampType deployment if !exists { return fmt.Errorf("chain %d does not exist", chainSelector) } - if rampType == OffRamp && chainState.OffRamp == nil { - return fmt.Errorf("offramp contract does not exist on evm chain %d", chainSelector) - } else if rampType == OnRamp && chainState.OnRamp == nil { - return fmt.Errorf("onramp contract does not exist on evm chain %d", chainSelector) - } else { + switch rampType { + case OffRamp: + if chainState.OffRamp == nil { + return fmt.Errorf("offramp contract does not exist on evm chain %d", chainSelector) + } + case OnRamp: + if chainState.OnRamp == nil { + return fmt.Errorf("onramp contract does not exist on evm chain %d", chainSelector) + } + default: return fmt.Errorf("unknown ramp type %s", rampType) } @@ -836,17 +841,23 @@ func (s CCIPOnChainState) ValidateRamp(chainSelector uint64, rampType deployment if !exists { return fmt.Errorf("chain %d does not exist", chainSelector) } - if rampType == OffRamp && chainState.OffRamp.IsZero() { - return fmt.Errorf("offramp contract does not exist on solana chain %d", chainSelector) - } else if rampType == OnRamp && chainState.Router.IsZero() { - return fmt.Errorf("router contract does not exist on solana chain %d", chainSelector) - } else { + switch rampType { + case OffRamp: + if chainState.OffRamp.IsZero() { + return fmt.Errorf("offramp contract does not exist on solana chain %d", chainSelector) + } + case OnRamp: + if chainState.Router.IsZero() { + return fmt.Errorf("router contract does not exist on solana chain %d", chainSelector) + } + default: return fmt.Errorf("unknown ramp type %s", rampType) } default: return fmt.Errorf("unknown chain family %s", family) } + return nil } func ValidateChain(env deployment.Environment, state CCIPOnChainState, chainSel uint64, checkMcms bool) error { From 565af6e566d15ef28809ed051fec546869c7828a Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Mon, 17 Feb 2025 13:20:20 +0000 Subject: [PATCH 27/31] add method to get onrampbytes --- deployment/ccip/changeset/cs_add_lane_test.go | 20 +++++++++++++++++++ .../ccip/changeset/cs_chain_contracts.go | 6 +++--- deployment/ccip/changeset/solana_state.go | 7 +++++++ deployment/ccip/changeset/state.go | 7 +++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/deployment/ccip/changeset/cs_add_lane_test.go b/deployment/ccip/changeset/cs_add_lane_test.go index 5be37122a51..8f395ea0ec9 100644 --- a/deployment/ccip/changeset/cs_add_lane_test.go +++ b/deployment/ccip/changeset/cs_add_lane_test.go @@ -44,3 +44,23 @@ func TestAddLanesWithTestRouter(t *testing.T) { }] = []uint64{msgSentEvent.SequenceNumber} testhelpers.ConfirmExecWithSeqNrsForAll(t, e.Env, state, expectedSeqNumExec, startBlocks) } + +// dev is on going for sending request between solana and evm chains +// this test is there to ensure addLane works between solana and evm chains +func TestAddLanesWithSolana(t *testing.T) { + t.Parallel() + e, _ := testhelpers.NewMemoryEnvironment(t, testhelpers.WithSolChains(1)) + // Here we have CR + nodes set up, but no CCIP contracts deployed. + state, err := changeset.LoadOnchainState(e.Env) + require.NoError(t, err) + + evmSelectors := e.Env.AllChainSelectors() + chain1, chain2 := evmSelectors[0], evmSelectors[1] + solSelectors := e.Env.AllChainSelectorsSolana() + solChain := solSelectors[0] + testhelpers.AddLaneWithDefaultPricesAndFeeQuoterConfig(t, &e, state, chain1, solChain, true) + // AddLaneWithDefaultPricesAndFeeQuoterConfig involves calling AddRemoteChainToSolana + // which adds chain1 to solana + // so we can not call AddRemoteChainToSolana again with chain1 again, hence using chain2 below + testhelpers.AddLaneWithDefaultPricesAndFeeQuoterConfig(t, &e, state, solChain, chain2, true) +} diff --git a/deployment/ccip/changeset/cs_chain_contracts.go b/deployment/ccip/changeset/cs_chain_contracts.go index f8ae4345b23..e176851088e 100644 --- a/deployment/ccip/changeset/cs_chain_contracts.go +++ b/deployment/ccip/changeset/cs_chain_contracts.go @@ -1096,11 +1096,11 @@ func UpdateOffRampSourcesChangeset(e deployment.Environment, cfg UpdateOffRampSo sourceChainFamily, _ := chain_selectors.GetSelectorFamily(source) onRampBytes := []byte{} + // can ignore err as validation checks for nil addresses if sourceChainFamily == chain_selectors.FamilyEVM { - onRampBytes = state.Chains[source].OnRamp.Address().Bytes() + onRampBytes, _ = state.Chains[source].OnRampBytes() } else if sourceChainFamily == chain_selectors.FamilySolana { - // for solana the router contract has the onramp logic - onRampBytes = state.SolChains[source].Router.Bytes() + onRampBytes, _ = state.SolChains[source].OnRampBytes() } args = append(args, offramp.OffRampSourceChainConfigArgs{ diff --git a/deployment/ccip/changeset/solana_state.go b/deployment/ccip/changeset/solana_state.go index 935e38ca9be..473a65b16b5 100644 --- a/deployment/ccip/changeset/solana_state.go +++ b/deployment/ccip/changeset/solana_state.go @@ -166,3 +166,10 @@ func LoadChainStateSolana(chain deployment.SolChain, addresses map[string]deploy state.WSOL = solana.SolMint return state, nil } + +func (c SolCCIPChainState) OnRampBytes() ([]byte, error) { + if !c.Router.IsZero() { + return c.Router.Bytes(), nil + } + return nil, errors.New("no onramp found in the state") +} diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 7500c55d6ce..a11d068bc75 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -173,6 +173,13 @@ func (c CCIPChainState) LinkTokenAddress() (common.Address, error) { return common.Address{}, errors.New("no link token found in the state") } +func (c CCIPChainState) OnRampBytes() ([]byte, error) { + if c.OnRamp != nil { + return c.OnRamp.Address().Bytes(), nil + } + return nil, errors.New("no onramp found in the state") +} + func (c CCIPChainState) GenerateView() (view.ChainView, error) { chainView := view.NewChain() if c.Router != nil { From 94a7d6985cbde98b52965ac73b7f5dc418c82060 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Mon, 17 Feb 2025 13:48:20 +0000 Subject: [PATCH 28/31] making addlane modular --- .../solana/cs_chain_contracts_test.go | 1 - .../ccip/changeset/solana/cs_deploy_chain.go | 15 +- .../changeset/testhelpers/test_helpers.go | 208 +++++++++--------- 3 files changed, 111 insertions(+), 113 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go index d4b2a841e3d..5734604e730 100644 --- a/deployment/ccip/changeset/solana/cs_chain_contracts_test.go +++ b/deployment/ccip/changeset/solana/cs_chain_contracts_test.go @@ -179,7 +179,6 @@ func TestAddTokenPool(t *testing.T) { require.NoError(t, err) require.Equal(t, solTestTokenPool.LockAndRelease_PoolType, configAccount.PoolType) require.Equal(t, tokenAddress, configAccount.Config.Mint) - // try minting after this and see if the pool or the deployer key is the authority // test SetupTokenPoolForRemoteChain results remoteChainConfigPDA, _, _ := solTokenUtil.TokenPoolChainConfigPDA(evmChain, tokenAddress, state.SolChains[solChain].TokenPool) diff --git a/deployment/ccip/changeset/solana/cs_deploy_chain.go b/deployment/ccip/changeset/solana/cs_deploy_chain.go index b69ead5d765..6badbd6aaba 100644 --- a/deployment/ccip/changeset/solana/cs_deploy_chain.go +++ b/deployment/ccip/changeset/solana/cs_deploy_chain.go @@ -103,8 +103,9 @@ func initializeRouter( externalTokenPoolsSignerPDA, _, _ := solState.FindExternalTokenPoolsSignerPDA(ccipRouterProgram) instruction, err := solRouter.NewInitializeInstruction( - chain.Selector, // chain selector - solana.PublicKey{}, // fee aggregator + chain.Selector, // chain selector + // this is where the fee aggregator address would go (but have written a separate changeset to set that) + solana.PublicKey{}, feeQuoterAddress, linkTokenAddress, // link token mint routerConfigPDA, @@ -436,8 +437,14 @@ type SetFeeAggregatorConfig struct { } func (cfg SetFeeAggregatorConfig) Validate(e deployment.Environment) error { - state, _ := cs.LoadOnchainState(e) - chainState := state.SolChains[cfg.ChainSelector] + state, err := cs.LoadOnchainState(e) + if err != nil { + return fmt.Errorf("failed to load onchain state: %w", err) + } + chainState, chainExists := state.SolChains[cfg.ChainSelector] + if !chainExists { + return fmt.Errorf("chain %d not found in existing state", cfg.ChainSelector) + } chain := e.SolChains[cfg.ChainSelector] if err := validateRouterConfig(chain, chainState); err != nil { diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index a327eeef53a..8ade2a490bd 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -416,109 +416,23 @@ func MakeEVMExtraArgsV2(gasLimit uint64, allowOOO bool) []byte { func AddLane( t *testing.T, e *DeployedEnv, + state changeset.CCIPOnChainState, from, to uint64, isTestRouter bool, - gasprice map[uint64]*big.Int, - tokenPrices map[common.Address]*big.Int, fqCfg fee_quoter.FeeQuoterDestChainConfig, ) { var err error - fromFamily, _ := chainsel.GetSelectorFamily(from) toFamily, _ := chainsel.GetSelectorFamily(to) - changesets := []commoncs.ConfiguredChangeSet{} - if fromFamily == chainsel.FamilyEVM { - evmSrcChangesets := []commoncs.ConfiguredChangeSet{ - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateOnRampsDestsChangeset), - changeset.UpdateOnRampDestsConfig{ - UpdatesByChain: map[uint64]map[uint64]changeset.OnRampDestinationUpdate{ - from: { - to: { - IsEnabled: true, - TestRouter: isTestRouter, - AllowListEnabled: false, - }, - }, - }, - }, - ), - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterPricesChangeset), - changeset.UpdateFeeQuoterPricesConfig{ - PricesByChain: map[uint64]changeset.FeeQuoterPriceUpdatePerSource{ - from: { - TokenPrices: tokenPrices, - GasPrices: gasprice, - }, - }, - }, - ), - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterDestsChangeset), - changeset.UpdateFeeQuoterDestsConfig{ - UpdatesByChain: map[uint64]map[uint64]fee_quoter.FeeQuoterDestChainConfig{ - from: { - to: fqCfg, - }, - }, - }, - ), - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateRouterRampsChangeset), - changeset.UpdateRouterRampsConfig{ - TestRouter: isTestRouter, - UpdatesByChain: map[uint64]changeset.RouterUpdates{ - // onRamp update on source chain - from: { - OnRampUpdates: map[uint64]bool{ - to: true, - }, - }, - }, - }, - ), - } + evmSrcChangesets := addEVMSrcChangesets(from, to, isTestRouter, state, fqCfg) changesets = append(changesets, evmSrcChangesets...) } - - fmt.Println("e.RmnEnabledSourceChains[from]", e.RmnEnabledSourceChains[from]) if toFamily == chainsel.FamilyEVM { - evmDstChangesets := []commoncs.ConfiguredChangeSet{ - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateOffRampSourcesChangeset), - changeset.UpdateOffRampSourcesConfig{ - UpdatesByChain: map[uint64]map[uint64]changeset.OffRampSourceUpdate{ - to: { - from: { - IsEnabled: true, - TestRouter: isTestRouter, - IsRMNVerificationDisabled: !e.RmnEnabledSourceChains[from], - }, - }, - }, - }, - ), - commoncs.Configure( - deployment.CreateLegacyChangeSet(changeset.UpdateRouterRampsChangeset), - changeset.UpdateRouterRampsConfig{ - TestRouter: isTestRouter, - UpdatesByChain: map[uint64]changeset.RouterUpdates{ - // offramp update on dest chain - to: { - OffRampUpdates: map[uint64]bool{ - from: true, - }, - }, - }, - }, - ), - } + evmDstChangesets := addEVMDestChangesets(e, to, from, isTestRouter) changesets = append(changesets, evmDstChangesets...) } - if fromFamily == chainsel.FamilySolana { changesets = append(changesets, addLaneSolanaChangesets(t, from, to, toFamily)...) } @@ -569,6 +483,102 @@ func addLaneSolanaChangesets(t *testing.T, solChainSelector, remoteChainSelector return solanaChangesets } +func addEVMSrcChangesets(from, to uint64, isTestRouter bool, state changeset.CCIPOnChainState, fqCfg fee_quoter.FeeQuoterDestChainConfig) []commoncs.ConfiguredChangeSet { + stateChainFrom := state.Chains[from] + tokenPrices := map[common.Address]*big.Int{ + stateChainFrom.LinkToken.Address(): DefaultLinkPrice, + stateChainFrom.Weth9.Address(): DefaultWethPrice, + } + evmSrcChangesets := []commoncs.ConfiguredChangeSet{ + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateOnRampsDestsChangeset), + changeset.UpdateOnRampDestsConfig{ + UpdatesByChain: map[uint64]map[uint64]changeset.OnRampDestinationUpdate{ + from: { + to: { + IsEnabled: true, + TestRouter: isTestRouter, + AllowListEnabled: false, + }, + }, + }, + }, + ), + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterPricesChangeset), + changeset.UpdateFeeQuoterPricesConfig{ + PricesByChain: map[uint64]changeset.FeeQuoterPriceUpdatePerSource{ + from: { + TokenPrices: tokenPrices, + GasPrices: map[uint64]*big.Int{ + to: DefaultGasPrice, + }, + }, + }, + }, + ), + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateFeeQuoterDestsChangeset), + changeset.UpdateFeeQuoterDestsConfig{ + UpdatesByChain: map[uint64]map[uint64]fee_quoter.FeeQuoterDestChainConfig{ + from: { + to: fqCfg, + }, + }, + }, + ), + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateRouterRampsChangeset), + changeset.UpdateRouterRampsConfig{ + TestRouter: isTestRouter, + UpdatesByChain: map[uint64]changeset.RouterUpdates{ + // onRamp update on source chain + from: { + OnRampUpdates: map[uint64]bool{ + to: true, + }, + }, + }, + }, + ), + } + return evmSrcChangesets +} + +func addEVMDestChangesets(e *DeployedEnv, to, from uint64, isTestRouter bool) []commoncs.ConfiguredChangeSet { + evmDstChangesets := []commoncs.ConfiguredChangeSet{ + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateOffRampSourcesChangeset), + changeset.UpdateOffRampSourcesConfig{ + UpdatesByChain: map[uint64]map[uint64]changeset.OffRampSourceUpdate{ + to: { + from: { + IsEnabled: true, + TestRouter: isTestRouter, + IsRMNVerificationDisabled: !e.RmnEnabledSourceChains[from], + }, + }, + }, + }, + ), + commoncs.Configure( + deployment.CreateLegacyChangeSet(changeset.UpdateRouterRampsChangeset), + changeset.UpdateRouterRampsConfig{ + TestRouter: isTestRouter, + UpdatesByChain: map[uint64]changeset.RouterUpdates{ + // offramp update on dest chain + to: { + OffRampUpdates: map[uint64]bool{ + from: true, + }, + }, + }, + }, + ), + } + return evmDstChangesets +} + // RemoveLane removes a lane between the source and destination chains in the deployed environment. func RemoveLane(t *testing.T, e *DeployedEnv, src, dest uint64, isTestRouter bool) { var err error @@ -616,26 +626,8 @@ func RemoveLane(t *testing.T, e *DeployedEnv, src, dest uint64, isTestRouter boo } func AddLaneWithDefaultPricesAndFeeQuoterConfig(t *testing.T, e *DeployedEnv, state changeset.CCIPOnChainState, from, to uint64, isTestRouter bool) { - - gasPrices := map[uint64]*big.Int{ - to: DefaultGasPrice, - } - fromFamily, _ := chainsel.GetSelectorFamily(from) - tokenPrices := map[common.Address]*big.Int{} - if fromFamily == chainsel.FamilyEVM { - stateChainFrom := state.Chains[from] - tokenPrices = map[common.Address]*big.Int{ - stateChainFrom.LinkToken.Address(): DefaultLinkPrice, - stateChainFrom.Weth9.Address(): DefaultWethPrice, - } - } fqCfg := changeset.DefaultFeeQuoterDestChainConfig(true, to) - AddLane( - t, - e, - from, to, - isTestRouter, - gasPrices, tokenPrices, fqCfg) + AddLane(t, e, state, from, to, isTestRouter, fqCfg) } // AddLanesForAll adds densely connected lanes for all chains in the environment so that each chain From a352b09476281713fd954ee2b83a86d464d45265 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Mon, 17 Feb 2025 15:12:28 +0000 Subject: [PATCH 29/31] Reverting something --- .../changeset/testhelpers/test_helpers.go | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index 8ade2a490bd..80c3af4b8be 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -416,9 +416,10 @@ func MakeEVMExtraArgsV2(gasLimit uint64, allowOOO bool) []byte { func AddLane( t *testing.T, e *DeployedEnv, - state changeset.CCIPOnChainState, from, to uint64, isTestRouter bool, + gasprice map[uint64]*big.Int, + tokenPrices map[common.Address]*big.Int, fqCfg fee_quoter.FeeQuoterDestChainConfig, ) { var err error @@ -426,7 +427,7 @@ func AddLane( toFamily, _ := chainsel.GetSelectorFamily(to) changesets := []commoncs.ConfiguredChangeSet{} if fromFamily == chainsel.FamilyEVM { - evmSrcChangesets := addEVMSrcChangesets(from, to, isTestRouter, state, fqCfg) + evmSrcChangesets := addEVMSrcChangesets(from, to, isTestRouter, gasprice, tokenPrices, fqCfg) changesets = append(changesets, evmSrcChangesets...) } if toFamily == chainsel.FamilyEVM { @@ -445,10 +446,6 @@ func AddLane( } func addLaneSolanaChangesets(t *testing.T, solChainSelector, remoteChainSelector uint64, remoteFamily string) []commoncs.ConfiguredChangeSet { - value := [28]uint8{} - bigNum, ok := new(big.Int).SetString("19816680000000000000", 10) - require.True(t, ok) - bigNum.FillBytes(value[:]) chainFamilySelector := [4]uint8{} if remoteFamily == chainsel.FamilyEVM { // bytes4(keccak256("CCIP ChainFamilySelector EVM")) @@ -483,12 +480,7 @@ func addLaneSolanaChangesets(t *testing.T, solChainSelector, remoteChainSelector return solanaChangesets } -func addEVMSrcChangesets(from, to uint64, isTestRouter bool, state changeset.CCIPOnChainState, fqCfg fee_quoter.FeeQuoterDestChainConfig) []commoncs.ConfiguredChangeSet { - stateChainFrom := state.Chains[from] - tokenPrices := map[common.Address]*big.Int{ - stateChainFrom.LinkToken.Address(): DefaultLinkPrice, - stateChainFrom.Weth9.Address(): DefaultWethPrice, - } +func addEVMSrcChangesets(from, to uint64, isTestRouter bool, gasprice map[uint64]*big.Int, tokenPrices map[common.Address]*big.Int, fqCfg fee_quoter.FeeQuoterDestChainConfig) []commoncs.ConfiguredChangeSet { evmSrcChangesets := []commoncs.ConfiguredChangeSet{ commoncs.Configure( deployment.CreateLegacyChangeSet(changeset.UpdateOnRampsDestsChangeset), @@ -510,9 +502,7 @@ func addEVMSrcChangesets(from, to uint64, isTestRouter bool, state changeset.CCI PricesByChain: map[uint64]changeset.FeeQuoterPriceUpdatePerSource{ from: { TokenPrices: tokenPrices, - GasPrices: map[uint64]*big.Int{ - to: DefaultGasPrice, - }, + GasPrices: gasprice, }, }, }, @@ -626,8 +616,18 @@ func RemoveLane(t *testing.T, e *DeployedEnv, src, dest uint64, isTestRouter boo } func AddLaneWithDefaultPricesAndFeeQuoterConfig(t *testing.T, e *DeployedEnv, state changeset.CCIPOnChainState, from, to uint64, isTestRouter bool) { - fqCfg := changeset.DefaultFeeQuoterDestChainConfig(true, to) - AddLane(t, e, state, from, to, isTestRouter, fqCfg) + stateChainFrom := state.Chains[from] + AddLane( + t, + e, + from, to, + isTestRouter, + map[uint64]*big.Int{ + to: DefaultGasPrice, + }, map[common.Address]*big.Int{ + stateChainFrom.LinkToken.Address(): DefaultLinkPrice, + stateChainFrom.Weth9.Address(): DefaultWethPrice, + }, changeset.DefaultFeeQuoterDestChainConfig(true, to)) } // AddLanesForAll adds densely connected lanes for all chains in the environment so that each chain From a9e966d6980ab203dc07212ee4e6ce27c975abf5 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Mon, 17 Feb 2025 15:55:14 +0000 Subject: [PATCH 30/31] fix --- .../changeset/testhelpers/test_helpers.go | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/deployment/ccip/changeset/testhelpers/test_helpers.go b/deployment/ccip/changeset/testhelpers/test_helpers.go index 80c3af4b8be..b9e794f7627 100644 --- a/deployment/ccip/changeset/testhelpers/test_helpers.go +++ b/deployment/ccip/changeset/testhelpers/test_helpers.go @@ -616,18 +616,28 @@ func RemoveLane(t *testing.T, e *DeployedEnv, src, dest uint64, isTestRouter boo } func AddLaneWithDefaultPricesAndFeeQuoterConfig(t *testing.T, e *DeployedEnv, state changeset.CCIPOnChainState, from, to uint64, isTestRouter bool) { - stateChainFrom := state.Chains[from] + gasPrices := map[uint64]*big.Int{ + to: DefaultGasPrice, + } + fromFamily, _ := chainsel.GetSelectorFamily(from) + tokenPrices := map[common.Address]*big.Int{} + if fromFamily == chainsel.FamilyEVM { + stateChainFrom := state.Chains[from] + tokenPrices = map[common.Address]*big.Int{ + stateChainFrom.LinkToken.Address(): DefaultLinkPrice, + stateChainFrom.Weth9.Address(): DefaultWethPrice, + } + } + fqCfg := changeset.DefaultFeeQuoterDestChainConfig(true, to) AddLane( t, e, from, to, isTestRouter, - map[uint64]*big.Int{ - to: DefaultGasPrice, - }, map[common.Address]*big.Int{ - stateChainFrom.LinkToken.Address(): DefaultLinkPrice, - stateChainFrom.Weth9.Address(): DefaultWethPrice, - }, changeset.DefaultFeeQuoterDestChainConfig(true, to)) + gasPrices, + tokenPrices, + fqCfg, + ) } // AddLanesForAll adds densely connected lanes for all chains in the environment so that each chain From 9eee32ade19ad90d575288cc39f6d8864bf6acb1 Mon Sep 17 00:00:00 2001 From: yashnevatia Date: Tue, 18 Feb 2025 13:50:21 +0000 Subject: [PATCH 31/31] onramp bytes --- .../ccip/changeset/solana/cs_add_remote_chain.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deployment/ccip/changeset/solana/cs_add_remote_chain.go b/deployment/ccip/changeset/solana/cs_add_remote_chain.go index 34117b8fa69..06b7b849eb0 100644 --- a/deployment/ccip/changeset/solana/cs_add_remote_chain.go +++ b/deployment/ccip/changeset/solana/cs_add_remote_chain.go @@ -6,6 +6,7 @@ import ( "fmt" "strconv" + "github.com/ethereum/go-ethereum/common" "github.com/gagliardetto/solana-go" solOffRamp "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/ccip_offramp" @@ -122,16 +123,15 @@ func doAddRemoteChainToSolana( var onRampBytes [64]byte // already verified, skipping errcheck remoteChainFamily, _ := chainsel.GetSelectorFamily(remoteChainSel) + var addressBytes []byte switch remoteChainFamily { case chainsel.FamilySolana: - onRampAddress := s.SolChains[remoteChainSel].Router.String() - addressBytes := []byte(onRampAddress) - copy(onRampBytes[:], addressBytes) + addressBytes, _ = s.SolChains[remoteChainSel].OnRampBytes() case chainsel.FamilyEVM: - onRampAddress := s.Chains[remoteChainSel].OnRamp.Address().String() - addressBytes := []byte(onRampAddress) - copy(onRampBytes[:], addressBytes) + addressBytes, _ = s.Chains[remoteChainSel].OnRampBytes() } + addressBytes = common.LeftPadBytes(addressBytes, 64) + copy(onRampBytes[:], addressBytes) // verified while loading state fqDestChainPDA, _, _ := solState.FindFqDestChainPDA(remoteChainSel, feeQuoterID)