Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 36 additions & 42 deletions chains/evm/deployment/v1_5_0/adapters/configimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import (
cldf_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations"
"golang.org/x/sync/errgroup"

"github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_2_0/router"

adapters1_2 "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_2_0/adapters"
"github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_5_0/evm_2_evm_offramp"
"github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_5_0/evm_2_evm_onramp"
"github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_5_0/token_admin_registry"
Expand Down Expand Up @@ -122,25 +121,14 @@ func (ci *ConfigImportAdapter) InitializeAdapter(e cldf.Environment, sel uint64)

func (ci *ConfigImportAdapter) ConnectedChains(e cldf.Environment, chainsel uint64) ([]uint64, error) {
var connected []uint64
// to ensure deduplication in case there are multiple onramps addresses in datastore for the same remote chain selector
var mapConnectedChains = make(map[uint64]bool)
chain, ok := e.BlockChains.EVMChains()[chainsel]
if !ok {
return nil, fmt.Errorf("chain with selector %d not found in environment", chainsel)
}
routerC, err := router.NewRouter(ci.Router, chain.Client)
laneResolver := adapters1_2.LaneVersionResolver{}
remoteChainToVersionMap, _, err := laneResolver.DeriveLaneVersionsForChain(e, chainsel)
if err != nil {
return nil, fmt.Errorf("failed to instantiate router contract at %s on chain %d: %w", ci.Router.String(), chain.Selector, err)
return nil, fmt.Errorf("failed to derive lane versions for chain %d: %w", chainsel, err)
}
for destSel, onrampForDest := range ci.OnRamp {
onRamp, err := routerC.GetOnRamp(nil, destSel)
if err != nil {
return nil, fmt.Errorf("failed to get onramp for dest chain %d from router at %s on chain %d: %w", destSel, ci.Router.String(), chain.Selector, err)
}
// if the onramp address from the router doesn't match the onramp address we have, then this chain is not actually connected with 1.5
if onRamp == onrampForDest && !mapConnectedChains[destSel] {
for destSel, version := range remoteChainToVersionMap {
if version.Equal(semver.MustParse("1.5.0")) {
Comment on lines +149 to +150
connected = append(connected, destSel)
mapConnectedChains[destSel] = true
}
}
return connected, nil
Expand All @@ -151,8 +139,12 @@ func (ci *ConfigImportAdapter) SupportedTokensPerRemoteChain(e cldf.Environment,
if !ok {
return nil, fmt.Errorf("chain with selector %d not found in environment", chainsel)
}
remoteChains, err := ci.ConnectedChains(e, chainsel)
if err != nil {
return nil, fmt.Errorf("failed to get connected chains for chain %d: %w", chainsel, err)
}
// get all supported tokens from token admin registry
return GetSupportedTokensPerRemoteChain(e.GetContext(), e.Logger, ci.TokenAdminReg, chain)
return GetSupportedTokensPerRemoteChain(e.GetContext(), e.Logger, ci.TokenAdminReg, chain, remoteChains)
}

func (ci *ConfigImportAdapter) SequenceImportConfig() *cldf_ops.Sequence[api.ImportConfigPerChainInput, sequences.OnChainOutput, cldf_chain.BlockChains] {
Expand Down Expand Up @@ -192,7 +184,7 @@ func (ci *ConfigImportAdapter) SequenceImportConfig() *cldf_ops.Sequence[api.Imp
})
}

func GetSupportedTokensPerRemoteChain(ctx context.Context, l logger.Logger, tokenAdminRegAddr common.Address, chain evm.Chain) (map[uint64][]common.Address, error) {
func GetSupportedTokensPerRemoteChain(ctx context.Context, l logger.Logger, tokenAdminRegAddr common.Address, chain evm.Chain, remoteChains []uint64) (map[uint64][]common.Address, error) {
// get all supported tokens from token admin registry
tokenAdminRegC, err := token_admin_registry.NewTokenAdminRegistry(tokenAdminRegAddr, chain.Client)
if err != nil {
Expand Down Expand Up @@ -230,29 +222,31 @@ func GetSupportedTokensPerRemoteChain(ctx context.Context, l logger.Logger, toke
if err != nil {
return fmt.Errorf("failed to instantiate token pool contract at %s on chain %d: %w", poolAddr.String(), chain.Selector, err)
}
chains, err := tokenPoolC.GetSupportedChains(&bind.CallOpts{
Context: grpCtx,
})
if err != nil {
// if we fail to get the supported chains for a pool, we skip it and move on to avoid failing the entire config import
// since it's possible for some pools do not support the getSupportedChains function
l.Warnf("failed to get supported chains for token pool at %s on chain %d: %v", poolAddr.String(), chain.Selector, err)
return nil
}
tokenAddr, err := tokenPoolC.GetToken(&bind.CallOpts{
Context: grpCtx,
})
if err != nil {
// if we fail to get the token address for a pool, we skip it and move on to avoid failing the entire config import
// since it's possible for some pools do not support the getToken function
l.Warnf("failed to get token address for token pool at %s on chain %d: %v", poolAddr.String(), chain.Selector, err)
return nil
}
mu.Lock()
for _, remoteChain := range chains {
tokensPerRemoteChain[remoteChain] = append(tokensPerRemoteChain[remoteChain], tokenAddr)
for _, remoteChain := range remoteChains {
supported, err := tokenPoolC.IsSupportedChain(&bind.CallOpts{
Context: grpCtx,
}, remoteChain)
if err != nil {
// if we fail to check if the pool supports a remote chain, we skip it and move on to avoid failing the entire config import
// since it's possible for some pools do not support the isSupportedChain function
l.Warnf("failed to check if token pool at %s on chain %d supports remote chain %d: %v", poolAddr.String(), chain.Selector, remoteChain, err)
continue
}
if supported {
tokenAddr, err := tokenPoolC.GetToken(&bind.CallOpts{
Context: grpCtx,
})
if err != nil {
// if we fail to get the token address for a pool, we skip it and move on to avoid failing the entire config import
// since it's possible for some pools do not support the getToken function
l.Warnf("failed to get token address for token pool at %s on chain %d: %v", poolAddr.String(), chain.Selector, err)
continue
}
mu.Lock()
tokensPerRemoteChain[remoteChain] = append(tokensPerRemoteChain[remoteChain], tokenAddr)
mu.Unlock()
}
}
mu.Unlock()
return nil
})
}
Expand Down
52 changes: 14 additions & 38 deletions chains/evm/deployment/v1_6_0/adapters/configimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import (
"fmt"

"github.com/Masterminds/semver/v3"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain"
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
cldf_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations"

"github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_2_0/router"

evm_datastore_utils "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/utils/datastore"
adapters1_2 "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_2_0/adapters"
routerops "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_2_0/operations/router"
adapters1_5 "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_5_0/adapters"
tokenadminops "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_5_0/operations/token_admin_registry"
Expand Down Expand Up @@ -90,49 +88,27 @@ func (ci *ConfigImportAdapter) SupportedTokensPerRemoteChain(e cldf.Environment,
if !ok {
return nil, fmt.Errorf("chain with selector %d not found in environment", chainsel)
}
remoteChains, err := ci.ConnectedChains(e, chainsel)
if err != nil {
return nil, fmt.Errorf("failed to get connected chains for chain %d: %w", chainsel, err)
}
// get all supported tokens from token admin registry
return adapters1_5.GetSupportedTokensPerRemoteChain(e.GetContext(), e.Logger, ci.TokenAdminReg, chain)
return adapters1_5.GetSupportedTokensPerRemoteChain(e.GetContext(), e.Logger, ci.TokenAdminReg, chain, remoteChains)
}

func (ci *ConfigImportAdapter) ConnectedChains(e cldf.Environment, chainsel uint64) ([]uint64, error) {
chain, ok := e.BlockChains.EVMChains()[chainsel]
if !ok {
return nil, fmt.Errorf("chain with selector %d not found in environment", chainsel)
}
routerAddr := ci.Router
if routerAddr == (common.Address{}) {
return nil, fmt.Errorf("router address not initialized for chain %d", chainsel)
}
// get all offRamps from router to find connected chains
routerC, err := router.NewRouter(ci.Router, chain.Client)
if err != nil {
return nil, fmt.Errorf("failed to instantiate router contract at %s on chain %d: %w", routerAddr.String(), chain.Selector, err)
}
offRamps, err := routerC.GetOffRamps(&bind.CallOpts{
Context: e.GetContext(),
})
var connected []uint64
laneResolver := adapters1_2.LaneVersionResolver{}
remoteChainToVersionMap, _, err := laneResolver.DeriveLaneVersionsForChain(e, chainsel)
if err != nil {
return nil, fmt.Errorf("failed to get off ramps from router at %s on chain %d: %w", routerAddr.String(), chain.Selector, err)
return nil, fmt.Errorf("failed to derive lane versions for chain %d: %w", chainsel, err)
}
connectedChains := make([]uint64, 0)
for _, offRamp := range offRamps {
// if the offramp's address matches our offramp, then we are connected to the source chain via 1.6
if offRamp.OffRamp == ci.OffRamp {
// get the onRamp on router for the source chain and check if it matches our onRamp, if it does then we are connected to that chain
// lanes are always bi-directional so source and destination chain selectors are interchangeable for the purpose of finding connected chains
onRamp, err := routerC.GetOnRamp(&bind.CallOpts{
Context: e.GetContext(),
}, offRamp.SourceChainSelector)
if err != nil {
return nil, fmt.Errorf("failed to get on ramp for source chain selector %d from router at %s on chain %d: %w", offRamp.SourceChainSelector, routerAddr.String(), chain.Selector, err)
}
if onRamp != ci.OnRamp {
continue
}
connectedChains = append(connectedChains, offRamp.SourceChainSelector)
for destSel, version := range remoteChainToVersionMap {
if version.Equal(semver.MustParse("1.6.0")) {
connected = append(connected, destSel)
}
Comment on lines +121 to 130
}
return connectedChains, nil
return connected, nil
}

func (ci *ConfigImportAdapter) SequenceImportConfig() *cldf_ops.Sequence[api.ImportConfigPerChainInput, sequences.OnChainOutput, cldf_chain.BlockChains] {
Expand Down
Loading