Skip to content

Commit

Permalink
Solana changeset support for e2e testing (#15892)
Browse files Browse the repository at this point in the history
* Adding solchains in NewEnv

* Revert "Adding solchains in NewEnv"

This reverts commit aaab52e.

* adding sol chains to newenv

* newEnv needs to send nil

* adding test env setup

* adding link token deployment and test

* adding nil for crib sol chains

* using switch case

* Adding decimal const

* adding chain selectors commit

* go mod tidy

* adding initial code for solana chain contracts deploy

* linting

* adding solana state

* adding initial code for solana chain contracts deploy

* wip

* chain sel update

* update core/scripts go files

* again

* add changeset

* go imports

* go mod

* go mod

* go mod tidy

* todo

* deploy stuff

* Adding solana router deploy

* Adding

* updates

* adding stuff for tests

* linting

* linting

* changing to ctf

* bug

* Add CI Action to build Solana contracts

* testing stuff

* continue testing

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* deployment: memory: Generate more transmitter key types, expose in JD

* deployment: memory: Configure nodes with solana config too

* Use CTF to spin up the solana validator for in-memory tests

* Use autopatchelf on solana binaries to make them usable on NixOS

* memory: solana: Shut down the container when test terminates

* go mod tidy

* Use latest upstream CTF

* Add missing import

* make modgraph

* Use framework.DefaultNetwork()

* changes

* tidying

* ignoring keypair if not provided

* fix

* adding solchains to newnodes

* adding home chain changes

* delegate changes

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* test integrating with CI build step

* working tests

* bump ccip

* test fix

* save existing solana + tests

* try reading program ids

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Update chain.go

* Update action.yml

* last try

* Update action.yml

* Update action.yml

* make script executable

* reverting changes to stabilize the branch

* Create ccip_router.so

* go mod tidy

* sol chains param

* linting

* adding build here

* try without parallel

* yash fixed it!

* function signature

* Update chain.go

* parallel

* try defer

* retries

* still linting

* Revert "retries"

This reverts commit f9f5fd2.

* revert

* lint

* gomod

* remove cleanup

* fix deps

* try empty map

* Revert "yash fixed it!"

This reverts commit ff35f21.

* remove token info changes

* revert function call

* revert

* go mod tidy

* no return

* try retries

* try returning again

* use CI artifact

* try without ctf bump

* CR comments

* lint

* add global lookup table

* call utils

* adding token pool deploy

* test commit

* adding solana token stufF

* adding token pool so

* add retries

* fix token test

* setup token pool last

* match lookup table from tests

* lint

* revert token pool uncomment

* skip early return

* remove retries

* add ccip receiver to helpers

* initial token admin registry

* billing

* adding billing stuff

* cr comments

* fix home chain

* test fix

* run receiver in CI

* skip receiver again

* change set program id

* addLane for solana

* clean up supported chain checks

* using AddLane for evm to sol

* make it one operation

* adding router account check for router init (solana)

* adding default commitment to solana_chain

* Adding support for solana in validateRemoteChain

* Adding test TestUpdateOnRampsDestsSolana

* move to switch

* Revmoing solana from UpdateOnRampsDests

* adding separate solana AddRemoteChainToSolana

* moving to changeset_solana

* Reuse GetAccountDataBorshInto

* validation comment

* update test helpers based on AddRemoteChainOnSolana

* AddRemoteChainOnSolana test update

* uncommenting test but this will break

* validation comment

* remove token pools; consolidate home chain

* Revert "test commit"

This reverts commit 2f315cd.

* lint

* cleanup

* cleanup

* cr comments

* cr comments

* reverting UpdateOnRampDestsConfig

* Revert "cleanup"

This reverts commit 7388c49.

* delete artifacts again

* move solana logic

* lint

* lint

* gomodtidy

* move parallel calls

* cr comments

* lint

* cr comments

* package names

* cr comments

---------

Co-authored-by: Terry Tata <[email protected]>
Co-authored-by: jlaveracll <[email protected]>
Co-authored-by: Blaž Hrastnik <[email protected]>
Co-authored-by: tt-cll <[email protected]>
  • Loading branch information
5 people authored Jan 29, 2025
1 parent 8866591 commit f342658
Show file tree
Hide file tree
Showing 28 changed files with 1,681 additions and 309 deletions.
44 changes: 31 additions & 13 deletions core/capabilities/ccip/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/registrysyncer"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/services/telemetry"
"github.com/smartcontractkit/chainlink/v2/evm/config/toml"
"github.com/smartcontractkit/chainlink/v2/plugins"
Expand Down Expand Up @@ -265,22 +266,39 @@ func (d *Delegate) getOCRKeys(ocrKeyBundleIDs job.JSONConfig) (map[string]ocr2ke
func (d *Delegate) getTransmitterKeys(ctx context.Context, relayIDs []types.RelayID) (map[types.RelayID][]string, error) {
transmitterKeys := make(map[types.RelayID][]string)
for _, relayID := range relayIDs {
chainID, ok := new(big.Int).SetString(relayID.ChainID, 10)
if !ok {
return nil, fmt.Errorf("error parsing chain ID, expected big int: %s", relayID.ChainID)
}
switch relayID.Network {
case relay.NetworkSolana:
solKeys, err := d.keystore.Solana().GetAll()
if err != nil {
return nil, fmt.Errorf("error getting enabled addresses for chain: %s %w", relayID.ChainID, err)
}

ethKeys, err := d.keystore.Eth().EnabledAddressesForChain(ctx, chainID)
if err != nil {
return nil, fmt.Errorf("error getting enabled addresses for chain: %s %w", chainID.String(), err)
}
transmitterKeys[relayID] = func() (r []string) {
for _, key := range solKeys {
r = append(r, key.PublicKey().String())
}
return
}()
case relay.NetworkEVM:
chainID, ok := new(big.Int).SetString(relayID.ChainID, 10)
if !ok {
return nil, fmt.Errorf("error parsing chain ID, expected big int: %s", relayID.ChainID)
}

transmitterKeys[relayID] = func() (r []string) {
for _, key := range ethKeys {
r = append(r, key.Hex())
ethKeys, err := d.keystore.Eth().EnabledAddressesForChain(ctx, chainID)
if err != nil {
return nil, fmt.Errorf("error getting enabled addresses for chain: %s %w", chainID.String(), err)
}
return
}()

transmitterKeys[relayID] = func() (r []string) {
for _, key := range ethKeys {
r = append(r, key.Hex())
}
return
}()
default:
return nil, fmt.Errorf("unsupported network: %s", relayID.Network)
}
}
return transmitterKeys, nil
}
Expand Down
211 changes: 211 additions & 0 deletions core/scripts/go.sum

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions deployment/ccip/changeset/cs_ccip_home.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"
cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home"
"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"
)

var (
Expand Down Expand Up @@ -303,13 +303,8 @@ 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)
}
chainState, exists := state.Chains[chainSelector]
if !exists {
return nil, fmt.Errorf("chain %d does not exist", chainSelector)
}
if chainState.OffRamp == nil {
// should not be possible, but a defensive check.
return nil, errors.New("OffRamp contract does not exist")
if err := state.ValidateOffRamp(chainSelector); err != nil {
return nil, err
}

donID, err := internal.DonIDForChain(
Expand Down Expand Up @@ -456,16 +451,14 @@ func (p SetCandidatePluginInfo) Validate(state CCIPOnChainState, homeChain uint6
return errors.New("PluginType must be set to either CCIPCommit or CCIPExec")
}
for chainSelector, params := range p.OCRConfigPerRemoteChainSelector {
_, ok := state.Chains[chainSelector]
if !ok {
if _, exists := state.SupportedChains()[chainSelector]; !exists {
return fmt.Errorf("chain %d does not exist in state", chainSelector)
}
if err := deployment.IsValidChainSelector(chainSelector); err != nil {
return fmt.Errorf("don chain selector invalid: %w", err)
}
if state.Chains[chainSelector].OffRamp == nil {
// should not be possible, but a defensive check.
return fmt.Errorf("OffRamp contract does not exist on don chain selector %d", chainSelector)
if err := state.ValidateOffRamp(chainSelector); err != nil {
return err
}
if p.PluginType == types.PluginTypeCCIPCommit && params.CommitOffChainConfig == nil {
return errors.New("commit off-chain config must be set")
Expand Down Expand Up @@ -619,12 +612,15 @@ func AddDonAndSetCandidateChangeset(
txOpts = deployment.SimTransactOpts()
}
var donOps []mcms.Operation

for chainSelector, params := range cfg.PluginInfo.OCRConfigPerRemoteChainSelector {
offRampAddress, err := state.GetOffRampAddress(chainSelector)
if err != nil {
return deployment.ChangesetOutput{}, err
}
newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome(
e.OCRSecrets,
state.Chains[chainSelector].OffRamp,
e.Chains[chainSelector],
offRampAddress,
chainSelector,
nodes.NonBootstraps(),
state.Chains[cfg.HomeChainSelector].RMNHome.Address(),
params.OCRParameters,
Expand Down Expand Up @@ -808,10 +804,14 @@ func SetCandidateChangeset(
for _, plugin := range cfg.PluginInfo {
pluginInfos = append(pluginInfos, plugin.String())
for chainSelector, params := range plugin.OCRConfigPerRemoteChainSelector {
offRampAddress, err := state.GetOffRampAddress(chainSelector)
if err != nil {
return deployment.ChangesetOutput{}, err
}
newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome(
e.OCRSecrets,
state.Chains[chainSelector].OffRamp,
e.Chains[chainSelector],
offRampAddress,
chainSelector,
nodes.NonBootstraps(),
state.Chains[cfg.HomeChainSelector].RMNHome.Address(),
params.OCRParameters,
Expand Down
4 changes: 2 additions & 2 deletions deployment/ccip/changeset/cs_ccip_home_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func TestInvalidOCR3Params(t *testing.T) {
params.OCRParameters.DeltaRound = params.OCRParameters.DeltaProgress + time.Duration(1)
_, err = internal.BuildOCR3ConfigForCCIPHome(
e.Env.OCRSecrets,
state.Chains[chain1].OffRamp,
e.Env.Chains[chain1],
state.Chains[chain1].OffRamp.Address().Bytes(),
chain1,
nodes.NonBootstraps(),
state.Chains[e.HomeChainSel].RMNHome.Address(),
params.OCRParameters,
Expand Down
53 changes: 41 additions & 12 deletions deployment/ccip/changeset/cs_chain_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock"
chain_selectors "github.com/smartcontractkit/chain-selectors"

"github.com/smartcontractkit/chainlink-common/pkg/logger"

Expand Down Expand Up @@ -219,6 +220,7 @@ func UpdateNonceManagersChangeset(e deployment.Environment, cfg UpdateNonceManag
type UpdateOnRampDestsConfig struct {
// UpdatesByChain is a mapping of source -> dest -> update.
UpdatesByChain map[uint64]map[uint64]OnRampDestinationUpdate

// Disallow mixing MCMS/non-MCMS per chain for simplicity.
// (can still be achieved by calling this function multiple times)
MCMS *MCMSConfig
Expand Down Expand Up @@ -253,16 +255,15 @@ 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
}

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.OnRamp.Address(), 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.OnRamp.Address())
}
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.OnRamp.Address(), err)
}
if destination == sc.ChainSelector {
return errors.New("cannot update onramp destination to the same chain")
}
Expand Down Expand Up @@ -427,7 +428,7 @@ func (cfg UpdateFeeQuoterPricesConfig) Validate(e deployment.Environment) error
if price == nil {
return fmt.Errorf("gas price for chain %d is nil", chainSel)
}
if _, ok := state.Chains[dest]; !ok {
if _, ok := state.SupportedChains()[dest]; !ok {
return fmt.Errorf("dest chain %d not found in onchain state for chain %d", dest, chainSel)
}
}
Expand Down Expand Up @@ -827,9 +828,8 @@ func (cfg UpdateRouterRampsConfig) Validate(e deployment.Environment) error {
if destination == chainSel {
return fmt.Errorf("cannot update onRamp dest to the same chain %d", destination)
}
destChain := state.Chains[destination]
if destChain.OffRamp == nil {
return fmt.Errorf("missing offramp for dest %d", destination)
if err := state.ValidateOffRamp(destination); err != nil {
return err
}
}
}
Expand Down Expand Up @@ -960,13 +960,39 @@ func (c SetOCR3OffRampConfig) Validate(e deployment.Environment) error {
return fmt.Errorf("invalid CCIPHomeConfigType should be either %s or %s", globals.ConfigTypeActive, globals.ConfigTypeCandidate)
}
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", 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 {

// TODO: introduce interface when MCMS is ready
if err := commoncs.ValidateOwnershipSolana(e.GetContext(), c.MCMS != nil, e.SolChains[chainSelector].DeployerKey.PublicKey(), chainState.Timelock, chainState.Router); err != nil {
return err
}
case chain_selectors.FamilyEVM:
chainState, ok := state.Chains[chainSelector]
if !ok {
return fmt.Errorf("remote chain %d not found in onchain state", chainSelector)
}
if err := commoncs.ValidateOwnership(e.GetContext(), c.MCMS != nil, e.Chains[chainSelector].DeployerKey.From, chainState.Timelock.Address(), chainState.OffRamp); err != nil {
return err
}
default:
return fmt.Errorf("unsupported chain family %s", family)
}
return nil
}
Expand All @@ -993,6 +1019,9 @@ func SetOCR3OffRampChangeset(e deployment.Environment, cfg SetOCR3OffRampConfig)
state.Chains[cfg.HomeChainSel].CapabilityRegistry,
state.Chains[cfg.HomeChainSel].CCIPHome,
remote)
if err != nil {
return deployment.ChangesetOutput{}, err
}
args, err := internal.BuildSetOCR3ConfigArgs(
donID, state.Chains[cfg.HomeChainSel].CCIPHome, remote, cfg.CCIPHomeConfigType)
if err != nil {
Expand Down
Loading

0 comments on commit f342658

Please sign in to comment.