diff --git a/deployment/ccip/changeset/cs_ccip_home_test.go b/deployment/ccip/changeset/cs_ccip_home_test.go index dae32557f8b..64c00172ffa 100644 --- a/deployment/ccip/changeset/cs_ccip_home_test.go +++ b/deployment/ccip/changeset/cs_ccip_home_test.go @@ -170,7 +170,9 @@ func Test_SetCandidate(t *testing.T) { MinDelay: 0, } } - tokenConfig := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) + tokenConfig := NewTestTokenConfig( + state.Chains[tenv.FeedChainSel].USDFeeds[LinkSymbol].Address().String(), + state.Chains[tenv.FeedChainSel].USDFeeds[WethSymbol].Address().String()) _, err = commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ tenv.HomeChainSel: { Timelock: state.Chains[tenv.HomeChainSel].Timelock, @@ -186,7 +188,7 @@ func Test_SetCandidate(t *testing.T) { OCRConfigPerRemoteChainSelector: map[uint64]CCIPOCRParams{ dest: DefaultOCRParams( tenv.FeedChainSel, - tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken, state.Chains[dest].Weth9), + tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken.Address().String(), state.Chains[dest].Weth9.Address().String()), nil, ), }, @@ -204,7 +206,7 @@ func Test_SetCandidate(t *testing.T) { OCRConfigPerRemoteChainSelector: map[uint64]CCIPOCRParams{ dest: DefaultOCRParams( tenv.FeedChainSel, - tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken, state.Chains[dest].Weth9), + tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken.Address().String(), state.Chains[dest].Weth9.Address().String()), nil, ), }, @@ -291,7 +293,9 @@ func Test_RevokeCandidate(t *testing.T) { MinDelay: 0, } } - tokenConfig := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) + tokenConfig := NewTestTokenConfig( + state.Chains[tenv.FeedChainSel].USDFeeds[LinkSymbol].Address().String(), + state.Chains[tenv.FeedChainSel].USDFeeds[WethSymbol].Address().String()) _, err = commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ tenv.HomeChainSel: { Timelock: state.Chains[tenv.HomeChainSel].Timelock, @@ -307,7 +311,7 @@ func Test_RevokeCandidate(t *testing.T) { OCRConfigPerRemoteChainSelector: map[uint64]CCIPOCRParams{ dest: DefaultOCRParams( tenv.FeedChainSel, - tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken, state.Chains[dest].Weth9), + tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken.Address().String(), state.Chains[dest].Weth9.Address().String()), nil, ), }, @@ -325,7 +329,7 @@ func Test_RevokeCandidate(t *testing.T) { OCRConfigPerRemoteChainSelector: map[uint64]CCIPOCRParams{ dest: DefaultOCRParams( tenv.FeedChainSel, - tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken, state.Chains[dest].Weth9), + tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken.Address().String(), state.Chains[dest].Weth9.Address().String()), nil, ), }, diff --git a/deployment/ccip/changeset/cs_chain_contracts.go b/deployment/ccip/changeset/cs_chain_contracts.go index f85814f1768..c264791627f 100644 --- a/deployment/ccip/changeset/cs_chain_contracts.go +++ b/deployment/ccip/changeset/cs_chain_contracts.go @@ -17,6 +17,8 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" + chain_selectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commoncs "github.com/smartcontractkit/chainlink/deployment/common/changeset" @@ -238,6 +240,48 @@ func (cfg UpdateOnRampDestsConfig) Validate(e deployment.Environment) error { } supportedChains := state.SupportedChains() for chainSel, updates := range cfg.UpdatesByChain { + if err := cfg.validateRemoteChain(&e, &state, supportedChains, chainSel, updates); err != nil { + return err + } + } + return nil +} + +func (cfg UpdateOnRampDestsConfig) validateRemoteChain(e *deployment.Environment, state *CCIPOnChainState, supportedChains map[uint64]struct{}, chainSel uint64, updates map[uint64]OnRampDestinationUpdate) error { + family, err := chain_selectors.GetSelectorFamily(chainSel) + if err != nil { + return err + } + switch family { + case chain_selectors.FamilySolana: + chainState, ok := state.SolChains[chainSel] + if !ok { + return fmt.Errorf("chain %d not found in onchain state", chainSel) + } + if chainState.CcipRouter.IsZero() { + return fmt.Errorf("missing router for chain %d", chainSel) + } + if err := commoncs.ValidateOwnershipSolana(e.GetContext(), cfg.MCMS != nil, e.SolChains[chainSel].DeployerKey.PublicKey(), chainState.Timelock, chainState.CcipRouter); err != nil { + return err + } + for destination := range updates { + // Destination cannot be an unknown destination. + if _, ok := supportedChains[destination]; !ok { + return fmt.Errorf("destination chain %d is not a supported %s", destination, chainState.CcipRouter) + } + // TODO SOLANA_CCIP + // sc, err := chainState.OnRamp.GetStaticConfig(&bind.CallOpts{Context: e.GetContext()}) + // if err != nil { + // return fmt.Errorf("failed to get onramp static config %s: %w", chainState.CcipRouter, err) + // } + // if destination == sc.ChainSelector { + // return fmt.Errorf("cannot update onramp destination to the same chain") + // } + } + case chain_selectors.FamilyEVM: + // EVM is the default case + fallthrough + default: chainState, ok := state.Chains[chainSel] if !ok { return fmt.Errorf("chain %d not found in onchain state", chainSel) @@ -254,7 +298,6 @@ func (cfg UpdateOnRampDestsConfig) Validate(e deployment.Environment) error { if err := commoncs.ValidateOwnership(e.GetContext(), cfg.MCMS != nil, e.Chains[chainSel].DeployerKey.From, chainState.Timelock.Address(), chainState.OnRamp); err != nil { return err } - for destination := range updates { // Destination cannot be an unknown destination. if _, ok := supportedChains[destination]; !ok { @@ -269,6 +312,7 @@ func (cfg UpdateOnRampDestsConfig) Validate(e deployment.Environment) error { } } } + return nil } @@ -948,11 +992,37 @@ func (c SetOCR3OffRampConfig) Validate(e deployment.Environment) error { return fmt.Errorf("home chain %d not found in onchain state", c.HomeChainSel) } for _, remote := range c.RemoteChainSels { - chainState, ok := state.Chains[remote] + if err := c.validateRemoteChain(&e, &state, remote); err != nil { + return err + } + } + return nil +} + +func (c SetOCR3OffRampConfig) validateRemoteChain(e *deployment.Environment, state *CCIPOnChainState, chainSelector uint64) error { + family, err := chain_selectors.GetSelectorFamily(chainSelector) + if err != nil { + return err + } + switch family { + case chain_selectors.FamilySolana: + chainState, ok := state.SolChains[chainSelector] + if !ok { + return fmt.Errorf("remote chain %d not found in onchain state", chainSelector) + } + + if err := commoncs.ValidateOwnershipSolana(e.GetContext(), c.MCMS != nil, e.SolChains[chainSelector].DeployerKey.PublicKey(), chainState.Timelock, chainState.CcipRouter); err != nil { + return err + } + case chain_selectors.FamilyEVM: + // EVM is the default case + fallthrough + default: + chainState, ok := state.Chains[chainSelector] if !ok { - return fmt.Errorf("remote chain %d not found in onchain state", remote) + return fmt.Errorf("remote chain %d not found in onchain state", chainSelector) } - if err := commoncs.ValidateOwnership(e.GetContext(), c.MCMS != nil, e.Chains[remote].DeployerKey.From, chainState.Timelock.Address(), chainState.OffRamp); err != nil { + if err := commoncs.ValidateOwnership(e.GetContext(), c.MCMS != nil, e.Chains[chainSelector].DeployerKey.From, chainState.Timelock.Address(), chainState.OffRamp); err != nil { return err } } diff --git a/deployment/ccip/changeset/cs_chain_contracts_solana.go b/deployment/ccip/changeset/cs_chain_contracts_solana.go index 62bcde8ea9d..ec2292f563a 100644 --- a/deployment/ccip/changeset/cs_chain_contracts_solana.go +++ b/deployment/ccip/changeset/cs_chain_contracts_solana.go @@ -55,7 +55,9 @@ import ( // in the chains specified. Multichain support is important - consider when we add a new chain // and need to update the onramp destinations for all chains to support the new chain. func UpdateOnRampsDestsSolana(e deployment.Environment, cfg UpdateOnRampDestsConfig) (deployment.ChangesetOutput, error) { - + if err := cfg.Validate(e); err != nil { + return deployment.ChangesetOutput{}, err + } s, err := LoadOnchainStateSolana(e) if err != nil { return deployment.ChangesetOutput{}, err @@ -130,18 +132,15 @@ func btoi(b bool) uint8 { // Multichain is especially helpful for NOP rotations where we have // to touch all the chain to change signers. func SetOCR3ConfigSolana(e deployment.Environment, cfg SetOCR3OffRampConfig) (deployment.ChangesetOutput, error) { - // if err := cfg.Validate(e); err != nil { - // return deployment.ChangesetOutput{}, err - // } - - solState, err := LoadOnchainStateSolana(e) - if err != nil { + if err := cfg.Validate(e); err != nil { return deployment.ChangesetOutput{}, err } + state, err := LoadOnchainState(e) if err != nil { return deployment.ChangesetOutput{}, err } + solChains := state.SolChains // cfg.RemoteChainSels will be a bunch of solana chains // can add this in validate @@ -166,7 +165,7 @@ func SetOCR3ConfigSolana(e deployment.Environment, cfg SetOCR3OffRampConfig) (de // continue // } var instructions []solana.Instruction - ccipRouterId := solState.SolChains[remote].CcipRouter + ccipRouterId := solChains[remote].CcipRouter for _, arg := range args { instruction, err := ccip_router.NewSetOcrConfigInstruction( uint8(arg.OcrPluginType), diff --git a/deployment/ccip/changeset/cs_deploy_chain_test.go b/deployment/ccip/changeset/cs_deploy_chain_test.go index 13125a90f9a..21bf3296f7f 100644 --- a/deployment/ccip/changeset/cs_deploy_chain_test.go +++ b/deployment/ccip/changeset/cs_deploy_chain_test.go @@ -3,21 +3,27 @@ package changeset import ( "encoding/json" "fmt" + "math/big" "testing" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink-ccip/chainconfig" solConfig "github.com/smartcontractkit/chainlink-ccip/chains/solana/contracts/tests/config" "github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings/ccip_router" solCommomUtil "github.com/smartcontractkit/chainlink-ccip/chains/solana/utils/common" + cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" ) // TODO: Solana re-write @@ -108,20 +114,16 @@ func TestDeployChainContractsChangeset(t *testing.T) { func TestDeployChainContractsChangesetSolana(t *testing.T) { t.Parallel() - lggr := logger.TestLogger(t) - e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ - Bootstraps: 1, - Chains: 2, - Nodes: 4, - }) + e := NewMemoryEnvironment(t) fmt.Println("Created Env") - selectors := e.AllChainSelectors() + selectors := e.Env.AllChainSelectors() homeChainSel := selectors[0] - nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + allChains := []uint64{deployment.SolanaChainSelector} + nodes, err := deployment.NodeInfo(e.Env.NodeIDs, e.Env.Offchain) require.NoError(t, err) - p2pIds := nodes.NonBootstraps().PeerIDs() + // p2pIds := nodes.NonBootstraps().PeerIDs() cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) - for _, chain := range e.AllChainSelectors() { + for _, chain := range e.Env.AllChainSelectors() { cfg[chain] = proposalutils.SingleGroupTimelockConfig(t) } // var prereqCfg []DeployPrerequisiteConfigPerChain @@ -130,20 +132,20 @@ func TestDeployChainContractsChangesetSolana(t *testing.T) { // ChainSelector: chain, // }) // } - fmt.Println(e.SolChains) - e, err = commonchangeset.ApplyChangesets(t, e, nil, []commonchangeset.ChangesetApplication{ - { - Changeset: commonchangeset.WrapChangeSet(DeployHomeChain), - Config: DeployHomeChainConfig{ - HomeChainSel: homeChainSel, - RMNStaticConfig: NewTestRMNStaticConfig(), - RMNDynamicConfig: NewTestRMNDynamicConfig(), - NodeOperators: NewTestNodeOperator(e.Chains[homeChainSel].DeployerKey.From), - NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ - "NodeOperator": p2pIds, - }, - }, - }, + fmt.Println(e.Env.SolChains) + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ + // { + // Changeset: commonchangeset.WrapChangeSet(DeployHomeChain), + // Config: DeployHomeChainConfig{ + // HomeChainSel: homeChainSel, + // RMNStaticConfig: NewTestRMNStaticConfig(), + // RMNDynamicConfig: NewTestRMNDynamicConfig(), + // NodeOperators: NewTestNodeOperator(e.Env.Chains[homeChainSel].DeployerKey.From), + // NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ + // "NodeOperator": p2pIds, + // }, + // }, + // }, // { // Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployLinkToken), // Config: selectors, @@ -178,9 +180,101 @@ func TestDeployChainContractsChangesetSolana(t *testing.T) { }, }) require.NoError(t, err) + state, err := LoadOnchainStateSolana(e.Env) + require.NoError(t, err) + // Assert link present + require.NotNil(t, state.SolChains[deployment.SolanaChainSelector].LinkToken) + require.NotNil(t, state.SolChains[deployment.SolanaChainSelector].Weth9) + + tokenConfig := NewTestTokenConfig( + state.SolChains[deployment.SolanaChainSelector].LinkToken.String(), + state.SolChains[deployment.SolanaChainSelector].Weth9.String()) + var tokenDataProviders []pluginconfig.TokenDataObserverConfig + // Build the per chain config. + ocrConfigs := make(map[uint64]CCIPOCRParams) + chainConfigs := make(map[uint64]ChainConfig) + for _, chain := range allChains { + tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.SolChains[chain].LinkToken.String(), state.SolChains[chain].Weth9.String()) + ocrParams := DefaultOCRParams(deployment.SolanaChainSelector, tokenInfo, tokenDataProviders) + ocrConfigs[chain] = ocrParams + chainConfigs[chain] = ChainConfig{ + Readers: nodes.NonBootstraps().PeerIDs(), + FChain: uint8(len(nodes.NonBootstraps().PeerIDs()) / 3), + EncodableChainConfig: chainconfig.ChainConfig{ + GasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(internal.GasPriceDeviationPPB)}, + DAGasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(internal.DAGasPriceDeviationPPB)}, + OptimisticConfirmations: internal.OptimisticConfirmations, + }, + } + } + // Deploy second set of changesets to deploy and configure the CCIP contracts. + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ + { + // Add the chain configs for the new chains. + Changeset: commonchangeset.WrapChangeSet(UpdateChainConfig), + Config: UpdateChainConfigConfig{ + HomeChainSelector: homeChainSel, + RemoteChainAdds: chainConfigs, + }, + }, + { + // Add the DONs and candidate commit OCR instances for the chain. + Changeset: commonchangeset.WrapChangeSet(AddDonAndSetCandidateChangeset), + Config: AddDonAndSetCandidateChangesetConfig{ + SetCandidateConfigBase{ + HomeChainSelector: homeChainSel, + FeedChainSelector: deployment.SolanaChainSelector, + OCRConfigPerRemoteChainSelector: ocrConfigs, + PluginType: types.PluginTypeCCIPCommit, + }, + }, + }, + { + // Add the exec OCR instances for the new chains. + Changeset: commonchangeset.WrapChangeSet(SetCandidateChangeset), + Config: SetCandidateChangesetConfig{ + SetCandidateConfigBase{ + HomeChainSelector: homeChainSel, + FeedChainSelector: deployment.SolanaChainSelector, + OCRConfigPerRemoteChainSelector: ocrConfigs, + PluginType: types.PluginTypeCCIPExec, + }, + }, + }, + { + // Promote everything + Changeset: commonchangeset.WrapChangeSet(PromoteAllCandidatesChangeset), + Config: PromoteCandidatesChangesetConfig{ + HomeChainSelector: homeChainSel, + RemoteChainSelectors: allChains, + PluginType: types.PluginTypeCCIPCommit, + }, + }, + { + // Promote everything + Changeset: commonchangeset.WrapChangeSet(PromoteAllCandidatesChangeset), + Config: PromoteCandidatesChangesetConfig{ + HomeChainSelector: homeChainSel, + RemoteChainSelectors: allChains, + PluginType: types.PluginTypeCCIPExec, + }, + }, + { + // Enable the OCR config on the remote chains. + Changeset: commonchangeset.WrapChangeSet(SetOCR3ConfigSolana), + Config: SetOCR3OffRampConfig{ + HomeChainSel: homeChainSel, + RemoteChainSels: allChains, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(CCIPCapabilityJobspec), + }, + }) + require.NoError(t, err) // load onchain state - state, err := LoadOnchainStateSolana(e) + state, err = LoadOnchainStateSolana(e.Env) require.NoError(t, err) // // verify all contracts populated @@ -202,7 +296,7 @@ func TestDeployChainContractsChangesetSolana(t *testing.T) { // } var configAccount ccip_router.Config - err = solCommomUtil.GetAccountDataBorshInto(e.GetContext(), e.SolChains[deployment.SolanaChainSelector].Client, GetRouterConfigPDA(state.SolChains[deployment.SolanaChainSelector].CcipRouter), solConfig.DefaultCommitment, &configAccount) + err = solCommomUtil.GetAccountDataBorshInto(e.Env.GetContext(), e.Env.SolChains[deployment.SolanaChainSelector].Client, GetRouterConfigPDA(state.SolChains[deployment.SolanaChainSelector].CcipRouter), solConfig.DefaultCommitment, &configAccount) require.NoError(t, err) require.Equal(t, deployment.SolanaChainSelector, configAccount.SolanaChainSelector) diff --git a/deployment/ccip/changeset/solana_state.go b/deployment/ccip/changeset/solana_state.go index 21627b283af..fb504d94570 100644 --- a/deployment/ccip/changeset/solana_state.go +++ b/deployment/ccip/changeset/solana_state.go @@ -46,6 +46,7 @@ type SolCCIPChainState struct { TokenPool ag_solanago.PublicKey LinkToken ag_solanago.PublicKey Weth9 ag_solanago.PublicKey + Timelock ag_solanago.PublicKey } // TODO: Solana re-write diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 256256ca505..498be95dd30 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -41,7 +41,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry_1_1_0" + capabilities_registry "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry_1_1_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" @@ -383,8 +383,13 @@ func (s CCIPOnChainState) View(chains []uint64) (map[string]view.ChainView, erro // the state will need to be defined separately for solana // and LoadChainState() is completely different func LoadOnchainState(e deployment.Environment) (CCIPOnChainState, error) { + solState, err := LoadOnchainStateSolana(e) + if err != nil { + return CCIPOnChainState{}, err + } state := CCIPOnChainState{ - Chains: make(map[uint64]CCIPChainState), + Chains: make(map[uint64]CCIPChainState), + SolChains: solState.SolChains, } for chainSelector, chain := range e.Chains { addresses, err := e.ExistingAddresses.AddressesForChain(chainSelector) diff --git a/deployment/ccip/changeset/test_environment.go b/deployment/ccip/changeset/test_environment.go index f723efbf619..c2a806c25c2 100644 --- a/deployment/ccip/changeset/test_environment.go +++ b/deployment/ccip/changeset/test_environment.go @@ -244,6 +244,7 @@ func (m *MemoryEnvironment) StartChains(t *testing.T, tc *TestConfigs) { ctx := testcontext.Get(t) var chains map[uint64]deployment.Chain var users map[uint64][]*bind.TransactOpts + solChains := memory.NewMemoryChainsSol(t) if len(tc.ChainIDs) > 0 { chains, users = memory.NewMemoryChainsWithChainIDs(t, tc.ChainIDs, tc.NumOfUsersPerChain) if tc.Chains > len(tc.ChainIDs) { @@ -264,7 +265,8 @@ func (m *MemoryEnvironment) StartChains(t *testing.T, tc *TestConfigs) { require.NoError(t, err) m.DeployedEnv = DeployedEnv{ Env: deployment.Environment{ - Chains: m.Chains, + Chains: m.Chains, + SolChains: solChains, }, HomeChainSel: homeChainSel, FeedChainSel: feedSel, @@ -285,7 +287,8 @@ func (m *MemoryEnvironment) StartNodes(t *testing.T, tc *TestConfigs, crConfig d require.NoError(t, node.App.Stop()) }) } - m.DeployedEnv.Env = memory.NewMemoryEnvironmentFromChainsNodes(func() context.Context { return ctx }, lggr, m.Chains, nodes) + solChains := memory.NewMemoryChainsSol(t) + m.DeployedEnv.Env = memory.NewMemoryEnvironmentFromChainsNodes(func() context.Context { return ctx }, lggr, m.Chains, solChains, nodes) } func (m *MemoryEnvironment) MockUSDCAttestationServer(t *testing.T, isUSDCAttestationMissing bool) string { @@ -463,7 +466,9 @@ func NewEnvironmentWithJobsAndContracts(t *testing.T, tc *TestConfigs, tEnv Test require.NotNil(t, state.Chains[e.FeedChainSel].LinkToken) require.NotNil(t, state.Chains[e.FeedChainSel].Weth9) - tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + tokenConfig := NewTestTokenConfig( + state.Chains[e.FeedChainSel].USDFeeds[LinkSymbol].Address().String(), + state.Chains[e.FeedChainSel].USDFeeds[WethSymbol].Address().String()) var tokenDataProviders []pluginconfig.TokenDataObserverConfig if tc.IsUSDC { endpoint := tEnv.MockUSDCAttestationServer(t, tc.IsUSDCAttestationMissing) @@ -498,7 +503,7 @@ func NewEnvironmentWithJobsAndContracts(t *testing.T, tc *TestConfigs, tEnv Test Timelock: state.Chains[chain].Timelock, CallProxy: state.Chains[chain].CallProxy, } - tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) + tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken.Address().String(), state.Chains[chain].Weth9.Address().String()) ocrParams := DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) if tc.OCRConfigOverride != nil { ocrParams = tc.OCRConfigOverride(ocrParams) diff --git a/deployment/ccip/changeset/token_info.go b/deployment/ccip/changeset/token_info.go index 7c008a8a884..79598f6f917 100644 --- a/deployment/ccip/changeset/token_info.go +++ b/deployment/ccip/changeset/token_info.go @@ -3,11 +3,8 @@ package changeset import ( "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/link_token" "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface" ) type TokenSymbol string @@ -38,18 +35,18 @@ func NewTokenConfig() TokenConfig { } } -func NewTestTokenConfig(feeds map[TokenSymbol]*aggregator_v3_interface.AggregatorV3Interface) TokenConfig { +func NewTestTokenConfig(linkSymbolAddress, wethSymbolAddress string) TokenConfig { tc := NewTokenConfig() tc.UpsertTokenInfo(LinkSymbol, pluginconfig.TokenInfo{ - AggregatorAddress: ccipocr3.UnknownEncodedAddress(feeds[LinkSymbol].Address().String()), + AggregatorAddress: ccipocr3.UnknownEncodedAddress(linkSymbolAddress), Decimals: LinkDecimals, DeviationPPB: TestDeviationPPB, }, ) tc.UpsertTokenInfo(WethSymbol, pluginconfig.TokenInfo{ - AggregatorAddress: ccipocr3.UnknownEncodedAddress(feeds[WethSymbol].Address().String()), + AggregatorAddress: ccipocr3.UnknownEncodedAddress(wethSymbolAddress), Decimals: WethDecimals, DeviationPPB: TestDeviationPPB, }, @@ -67,15 +64,15 @@ func (tc *TokenConfig) UpsertTokenInfo( // GetTokenInfo Adds mapping between dest chain tokens and their respective aggregators on feed chain. func (tc *TokenConfig) GetTokenInfo( lggr logger.Logger, - linkToken *link_token.LinkToken, - wethToken *weth9.WETH9, + linkTokenAddress string, + wethTokenAddress string, ) map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo { tokenToAggregate := make(map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo) if _, ok := tc.TokenSymbolToInfo[LinkSymbol]; !ok { lggr.Debugw("Link aggregator not found, deploy without mapping link token") } else { lggr.Debugw("Mapping LinkToken to Link aggregator") - acc := ccipocr3.UnknownEncodedAddress(linkToken.Address().String()) + acc := ccipocr3.UnknownEncodedAddress(linkTokenAddress) tokenToAggregate[acc] = tc.TokenSymbolToInfo[LinkSymbol] } @@ -83,7 +80,7 @@ func (tc *TokenConfig) GetTokenInfo( lggr.Debugw("Weth aggregator not found, deploy without mapping link token") } else { lggr.Debugw("Mapping WethToken to Weth aggregator") - acc := ccipocr3.UnknownEncodedAddress(wethToken.Address().String()) + acc := ccipocr3.UnknownEncodedAddress(wethTokenAddress) tokenToAggregate[acc] = tc.TokenSymbolToInfo[WethSymbol] } diff --git a/deployment/common/changeset/deploy_mcms_with_timelock.go b/deployment/common/changeset/deploy_mcms_with_timelock.go index 315b63373ef..3067b9c860f 100644 --- a/deployment/common/changeset/deploy_mcms_with_timelock.go +++ b/deployment/common/changeset/deploy_mcms_with_timelock.go @@ -7,6 +7,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + ag_solanago "github.com/gagliardetto/solana-go" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/changeset/internal" "github.com/smartcontractkit/chainlink/deployment/common/types" @@ -39,3 +41,8 @@ func ValidateOwnership(ctx context.Context, mcms bool, deployerKey, timelock com } return nil } + +// TODO: SOLANA_CCIP +func ValidateOwnershipSolana(ctx context.Context, mcms bool, deployerKey, timelock, ccipRouter ag_solanago.PublicKey) error { + return nil +} diff --git a/deployment/environment/crib/types.go b/deployment/environment/crib/types.go index d19c8424443..741aed3956d 100644 --- a/deployment/environment/crib/types.go +++ b/deployment/environment/crib/types.go @@ -32,6 +32,7 @@ func NewDeployEnvironmentFromCribOutput(lggr logger.Logger, output DeployOutput) lggr, output.AddressBook, chains, + nil, output.NodeIDs, nil, // todo: populate the offchain client using output.DON func() context.Context { return context.Background() }, deployment.XXXGenerateTestOCRSecrets(), diff --git a/deployment/environment/memory/environment.go b/deployment/environment/memory/environment.go index 049a7ed9a23..0eef9065aaa 100644 --- a/deployment/environment/memory/environment.go +++ b/deployment/environment/memory/environment.go @@ -143,6 +143,7 @@ func NewMemoryEnvironmentFromChainsNodes( ctx func() context.Context, lggr logger.Logger, chains map[uint64]deployment.Chain, + solChains map[uint64]deployment.SolChain, nodes map[string]Node, ) deployment.Environment { var nodeIDs []string @@ -154,7 +155,7 @@ func NewMemoryEnvironmentFromChainsNodes( lggr, deployment.NewMemoryAddressBook(), chains, - nil, + solChains, nodeIDs, // Note these have the p2p_ prefix. NewMemoryJobClient(nodes), ctx, diff --git a/deployment/keystone/changeset/test/helpers.go b/deployment/keystone/changeset/test/helpers.go index 5ddaeda524e..0db018f3845 100644 --- a/deployment/keystone/changeset/test/helpers.go +++ b/deployment/keystone/changeset/test/helpers.go @@ -190,7 +190,7 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { maps.Copy(allNodes, wfNodes) maps.Copy(allNodes, cwNodes) maps.Copy(allNodes, assetNodes) - env := memory.NewMemoryEnvironmentFromChainsNodes(func() context.Context { return ctx }, lggr, allChains, allNodes) + env := memory.NewMemoryEnvironmentFromChainsNodes(func() context.Context { return ctx }, lggr, allChains, nil, allNodes) // set the env addresses to the deployed addresses that were created prior to configuring the nodes err = env.ExistingAddresses.Merge(e.ExistingAddresses) require.NoError(t, err)