Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
82 changes: 82 additions & 0 deletions deployment/ccip/operation/evm/v1_5/ops_evm2evm_onramp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package v1_5

import (
"fmt"
"sync"

"github.com/Masterminds/semver/v3"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"golang.org/x/sync/errgroup"

"github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_5_0/evm_2_evm_onramp"
cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
Expand All @@ -28,6 +31,15 @@ type GetPoolBySourceTokenIn struct {
DestChainSelector uint64
}

type BatchOnRampGetTokenCfgIn struct {
OnRamp common.Address
Tokens []common.Address
ChainSelector uint64
}

// onRampBatchConcurrency caps concurrent RPC calls to avoid overwhelming the node/provider.
const onRampBatchConcurrency = 10

var (
EVM2EVMOnrampGetDynamicCfgOp = operations.NewOperation(
"EVM2EVMOnrampGetDynamicCfgOp",
Expand Down Expand Up @@ -95,4 +107,74 @@ var (
}
return tokenTransferFeeCfg, nil
})

// EVM2EVMOnrampGetAllTokenTransferFeeConfigsOp fetches GetTokenTransferFeeConfig for every
// token in the input list concurrently
EVM2EVMOnrampGetAllTokenTransferFeeConfigsOp = operations.NewOperation(
"EVM2EVMOnrampGetAllTokenTransferFeeConfigsOp",
semver.MustParse("1.0.0"),
"Batch-fetches TokenTransferFeeConfig for all given tokens from a 1.5.0 OnRamp",
func(b operations.Bundle, deps MigrateOnRampToFQDeps, input BatchOnRampGetTokenCfgIn) (map[common.Address]evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig, error) {
onramp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(input.OnRamp, deps.Chain.Client)
if err != nil {
return nil, fmt.Errorf("failed to create EVM2EVMOnRamp contract binding: chainSelector=%d, OnRamp Address=%s, error=%w", deps.Chain.ChainSelector(), input.OnRamp.Hex(), err)
}

var mu sync.Mutex
results := make(map[common.Address]evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfig, len(input.Tokens))
grp, grpCtx := errgroup.WithContext(b.GetContext())
grp.SetLimit(onRampBatchConcurrency)
for _, token := range input.Tokens {
token := token
grp.Go(func() error {
cfg, err := onramp.GetTokenTransferFeeConfig(&bind.CallOpts{Context: grpCtx}, token)
if err != nil {
return fmt.Errorf("failed to get token transfer fee config for token %s on OnRamp %s: %w", token.Hex(), input.OnRamp.Hex(), err)
}
mu.Lock()
results[token] = cfg
mu.Unlock()
return nil
})
}
if err := grp.Wait(); err != nil {
return nil, err
}
return results, nil
})

// EVM2EVMOnrampGetAllFeeTokenConfigsOp fetches GetFeeTokenConfig for every token in the input
// list concurrently
EVM2EVMOnrampGetAllFeeTokenConfigsOp = operations.NewOperation(
"EVM2EVMOnrampGetAllFeeTokenConfigsOp",
semver.MustParse("1.0.0"),
"Batch-fetches FeeTokenConfig for all given fee tokens from a 1.5.0 OnRamp",
func(b operations.Bundle, deps MigrateOnRampToFQDeps, input BatchOnRampGetTokenCfgIn) (map[common.Address]evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig, error) {
onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(input.OnRamp, deps.Chain.Client)
if err != nil {
return nil, fmt.Errorf("failed to create EVM2EVMOnRamp contract binding: chainSelector=%d, OnRamp Address=%s, error=%w", deps.Chain.ChainSelector(), input.OnRamp.Hex(), err)
}

var mu sync.Mutex
results := make(map[common.Address]evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig, len(input.Tokens))
grp, grpCtx := errgroup.WithContext(b.GetContext())
grp.SetLimit(onRampBatchConcurrency)
for _, token := range input.Tokens {
token := token
grp.Go(func() error {
cfg, err := onRamp.GetFeeTokenConfig(&bind.CallOpts{Context: grpCtx}, token)
if err != nil {
return fmt.Errorf("failed to get fee token config for token %s on OnRamp %s: %w", token.Hex(), input.OnRamp.Hex(), err)
}
mu.Lock()
results[token] = cfg
mu.Unlock()
return nil
})
}
if err := grp.Wait(); err != nil {
return nil, err
}
return results, nil
})
)
72 changes: 38 additions & 34 deletions deployment/ccip/sequence/evm/migration/seq_translate_onramp_fq.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ var (
return OnRampToFeeQuoterDestChainConfigOutput{}, fmt.Errorf("failed to Execute GetAllFeeTokensOps: %w", err)
}

// Batch-fetch all fee token configs concurrently
allFeeTokenCfgsOp, err := operations.ExecuteOperation(
b, migration_ops.EVM2EVMOnrampGetAllFeeTokenConfigsOp,
migration_ops.MigrateOnRampToFQDeps{
Chain: srcChain,
},
migration_ops.BatchOnRampGetTokenCfgIn{
OnRamp: onRamp1_5,
Tokens: allFeeTokensOp.Output,
ChainSelector: chainSel,
},
)
if err != nil {
return OnRampToFeeQuoterDestChainConfigOutput{}, fmt.Errorf("failed to batch-fetch fee token configs on source chain %d: %w", chainSel, err)
}

// add supported fee token config to FeeQuoter

// This is per token in 1.5.0 onRamp, but in FeeQuoter its per destination chain,
Expand All @@ -92,31 +108,17 @@ var (

feeTokenPremiumMultipliers := make([]fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs, 0, len(allFeeTokensOp.Output))
for _, ft := range allFeeTokensOp.Output {
feetokenCfgReport, err := operations.ExecuteOperation(
b, migration_ops.EVM2EVMOnrampGetFeeTokenConfigOp,
migration_ops.MigrateOnRampToFQDeps{
Chain: srcChain,
},
migration_ops.OnRampGetTokenCfgIn{
OnRamp: onRamp1_5,
Address: ft,
ChainSelector: chainSel,
},
)
if err != nil {
return OnRampToFeeQuoterDestChainConfigOutput{}, fmt.Errorf("failed to Execute GetOnRampGetFeeTokenConfigOps: %w", err)
}

if !feetokenCfgReport.Output.Enabled {
feeTokenCfg := allFeeTokenCfgsOp.Output[ft]
if !feeTokenCfg.Enabled {
continue // skip disabled fee tokens, same as TTFC loop below
}

// Translate the feeToken PremiumMultiplierCfg to 1.6 FeeQuoter config
premiumMultiplierCfg := EVM2EVMOnRampMigratePremiumMultiplierCfg{}
premiumMultiplierCfg.TranslateOnrampToFeeQFeePremiumCfg(ft, feetokenCfgReport.Output)
premiumMultiplierCfg.TranslateOnrampToFeeQFeePremiumCfg(ft, feeTokenCfg)
feeTokenPremiumMultipliers = append(feeTokenPremiumMultipliers, premiumMultiplierCfg.FeeQuoterPremiumMultiplierWeiPerEthArgs)
if onRampFeeTokenCfgReport == (evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfig{}) {
onRampFeeTokenCfgReport = feetokenCfgReport.Output
onRampFeeTokenCfgReport = feeTokenCfg
}
}

Expand Down Expand Up @@ -175,28 +177,30 @@ var (
if err != nil {
return OnRampToFeeQuoterTokenTransferFeeCfgOutput{}, fmt.Errorf("failed to get all configured tokens from TokenAdminRegistry on source chain %d: %w", chainSel, err)
}
// Batch-fetch all token transfer fee configs concurrently
allTokens := getAllConfiguredTokensOps.Output
batchCfgsOp, err := operations.ExecuteOperation(
b, migration_ops.EVM2EVMOnrampGetAllTokenTransferFeeConfigsOp,
migration_ops.MigrateOnRampToFQDeps{
Chain: srcChain,
},
migration_ops.BatchOnRampGetTokenCfgIn{
OnRamp: onRamp1_5,
Tokens: allTokens,
ChainSelector: chainSel,
},
)
if err != nil {
return OnRampToFeeQuoterTokenTransferFeeCfgOutput{}, fmt.Errorf("failed to batch-fetch token transfer fee configs on source chain %d: %w", chainSel, err)
}
for _, token := range allTokens {
tokenTransferFeeCfgOp, err := operations.ExecuteOperation(
b, migration_ops.EVM2EVMOnrampGetTokenTransferFeeConfigOp,
migration_ops.MigrateOnRampToFQDeps{
Chain: srcChain,
},
migration_ops.OnRampGetTokenCfgIn{
OnRamp: onRamp1_5,
Address: token,
ChainSelector: chainSel,
},
)
if err != nil {
return OnRampToFeeQuoterTokenTransferFeeCfgOutput{}, fmt.Errorf("failed to get suported chains for the toksn Pool on source chain %d: %w", chainSel, err)
}
if !tokenTransferFeeCfgOp.Output.IsEnabled {
tokenTransferFeeCfg := batchCfgsOp.Output[token]
if !tokenTransferFeeCfg.IsEnabled {
continue // skip this token if the transfer fee config is not enabled
}

allTransferTokensAndCfgs = append(allTransferTokensAndCfgs,
migrateOnRamp.TranslateOnrampToFeequoterTokenTransferFeeConfig(token, tokenTransferFeeCfgOp.Output),
migrateOnRamp.TranslateOnrampToFeequoterTokenTransferFeeConfig(token, tokenTransferFeeCfg),
)
}
tokenTransferFeeConfigsPerDestChain = append(tokenTransferFeeConfigsPerDestChain, fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{
Expand Down
Loading
Loading