Skip to content
Merged
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
27 changes: 25 additions & 2 deletions ccv/chains/evm/deployment/v1_7_0/adapters/chain_family.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package adapters

import (
"encoding/binary"
"math/big"

chainsel "github.com/smartcontractkit/chain-selectors"
"github.com/smartcontractkit/chainlink-deployments-framework/chain"
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
Expand Down Expand Up @@ -97,8 +97,31 @@ func (a *ChainFamilyAdapter) GetTestRouter(ds datastore.DataStore, chainSelector
return addr, nil
}

// evmFamilySelector is bytes4(keccak256("CCIP ChainFamilySelector EVM")) = 0x2812d52c.
var evmFamilySelector = [4]byte{0x28, 0x12, 0xd5, 0x2c}

func (a *ChainFamilyAdapter) GetChainFamilySelector() [4]byte {
return evmFamilySelector
}

func (a *ChainFamilyAdapter) GetFeeQuoterDestChainConfig() lanes.FeeQuoterDestChainConfig {
return lanes.DefaultFeeQuoterDestChainConfig(false, chainsel.ETHEREUM_MAINNET.Selector)
sel := a.GetChainFamilySelector()
return lanes.FeeQuoterDestChainConfig{
IsEnabled: true,
MaxDataBytes: 30_000,
MaxPerMsgGasLimit: 3_000_000,
DestGasOverhead: 300_000,
DestGasPerPayloadByteBase: 16,
ChainFamilySelector: binary.BigEndian.Uint32(sel[:]),
DefaultTokenFeeUSDCents: 25,
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
NetworkFeeUSDCents: 10,
V2Params: &lanes.FeeQuoterV2Params{
LinkFeeMultiplierPercent: 90,
USDPerUnitGas: big.NewInt(1e6),
},
}
}

func (a *ChainFamilyAdapter) GetDefaultGasPrice() *big.Int {
Expand Down
9 changes: 5 additions & 4 deletions ccv/chains/evm/deployment/v1_7_0/testsetup/testsetup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ package testsetup

import (
"encoding/binary"
"encoding/hex"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/operations/rmn_remote"
"github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
"github.com/smartcontractkit/chainlink-ccip/deployment/tokens"
"github.com/smartcontractkit/chainlink-ccip/deployment/utils"
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"

Expand All @@ -23,9 +21,12 @@ import (
"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/v2_0_0/operations/fee_quoter"
)

// evmFamilySelector is bytes4(keccak256("CCIP ChainFamilySelector EVM")) = 0x2812d52c.
// Duplicated here to avoid an import cycle (testsetup ← adapters ← cctp ← testsetup).
var evmFamilySelector = [4]byte{0x28, 0x12, 0xd5, 0x2c}

// CreateBasicFeeQuoterDestChainConfig creates a basic fee quoter dest chain config with reasonable defaults for testing
func CreateBasicFeeQuoterDestChainConfig() lanes.FeeQuoterDestChainConfig {
familySelector, _ := hex.DecodeString(utils.EVMFamilySelector)
return lanes.FeeQuoterDestChainConfig{
IsEnabled: true,
MaxDataBytes: 30_000,
Expand All @@ -36,7 +37,7 @@ func CreateBasicFeeQuoterDestChainConfig() lanes.FeeQuoterDestChainConfig {
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
NetworkFeeUSDCents: 10,
ChainFamilySelector: binary.BigEndian.Uint32(familySelector),
ChainFamilySelector: binary.BigEndian.Uint32(evmFamilySelector[:]),
V2Params: &lanes.FeeQuoterV2Params{
LinkFeeMultiplierPercent: 90,
USDPerUnitGas: big.NewInt(1e6),
Expand Down
11 changes: 8 additions & 3 deletions chains/evm/deployment/v1_6_0/sequences/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
deployops "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
ccipapi "github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
tokensapi "github.com/smartcontractkit/chainlink-ccip/deployment/tokens"
"github.com/smartcontractkit/chainlink-ccip/deployment/utils"
datastore_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore"
)

Expand Down Expand Up @@ -203,15 +202,17 @@ func GetFeeQuoterAddress(addresses []datastore.AddressRef, chainSelector uint64,
return feeQRef, nil
}

// evmFamilySelector is bytes4(keccak256("CCIP ChainFamilySelector EVM")) = 0x2812d52c.
var evmFamilySelector = [4]byte{0x28, 0x12, 0xd5, 0x2c}

func (a *EVMAdapter) GetFeeQuoterDestChainConfig() ccipapi.FeeQuoterDestChainConfig {
chainHex := utils.GetHexFromString(utils.EVMFamilySelector)
return ccipapi.FeeQuoterDestChainConfig{
IsEnabled: true,
MaxDataBytes: 30_000,
MaxPerMsgGasLimit: 3_000_000,
DestGasOverhead: 300_000,
DestGasPerPayloadByteBase: 16,
ChainFamilySelector: binary.BigEndian.Uint32(chainHex[:]),
ChainFamilySelector: binary.BigEndian.Uint32(evmFamilySelector[:]),
DefaultTokenFeeUSDCents: 25,
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
Expand All @@ -236,6 +237,10 @@ func (a *EVMAdapter) GetDefaultGasPrice() *big.Int {
return big.NewInt(2e12)
}

func (a *EVMAdapter) GetChainFamilySelector() [4]byte {
return evmFamilySelector
}

// GetFQVersion implements the optional FeeQuoterVersionProvider interface so that
// update_lanes can choose 1.6 vs 2.0 FeeQuoter operations based on the deployed contract version.
func (a *EVMAdapter) GetFQVersion(ds datastore.DataStore, address []byte, chainSelector uint64) (*semver.Version, error) {
Expand Down
11 changes: 8 additions & 3 deletions chains/solana/deployment/v1_6_0/sequences/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
deployapi "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
laneapi "github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
tokensapi "github.com/smartcontractkit/chainlink-ccip/deployment/tokens"
common_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils"
mcmsreaderapi "github.com/smartcontractkit/chainlink-ccip/deployment/utils/changesets"
datastore_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore"
)
Expand Down Expand Up @@ -91,15 +90,17 @@ func (a *SolanaAdapter) GetRMNRemoteAddress(ds datastore.DataStore, chainSelecto
return addr, nil
}

// svmFamilySelector is bytes4(keccak256("CCIP ChainFamilySelector SVM")) = 0x1e10bdc4.
var svmFamilySelector = [4]byte{0x1e, 0x10, 0xbd, 0xc4}

func (a *SolanaAdapter) GetFeeQuoterDestChainConfig() laneapi.FeeQuoterDestChainConfig {
chainHex := common_utils.GetHexFromString(common_utils.SVMFamilySelector)
return laneapi.FeeQuoterDestChainConfig{
IsEnabled: true,
MaxDataBytes: 30_000,
MaxPerMsgGasLimit: 3_000_000,
DestGasOverhead: 300_000,
DestGasPerPayloadByteBase: 16,
ChainFamilySelector: binary.BigEndian.Uint32(chainHex[:]),
ChainFamilySelector: binary.BigEndian.Uint32(svmFamilySelector[:]),
DefaultTokenFeeUSDCents: 25,
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
Expand All @@ -123,3 +124,7 @@ func (a *SolanaAdapter) GetFeeQuoterDestChainConfig() laneapi.FeeQuoterDestChain
func (a *SolanaAdapter) GetDefaultGasPrice() *big.Int {
return big.NewInt(4e12)
}

func (a *SolanaAdapter) GetChainFamilySelector() [4]byte {
return svmFamilySelector
}
53 changes: 1 addition & 52 deletions deployment/lanes/lane_update.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package lanes

import (
"encoding/binary"
"math/big"

"github.com/Masterminds/semver/v3"
chain_selectors "github.com/smartcontractkit/chain-selectors"

"github.com/smartcontractkit/chainlink-ccip/deployment/utils"
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms"
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
)
Expand Down Expand Up @@ -208,53 +205,5 @@ type UpdateLanesInput struct {
}

// FeeQuoterDestChainConfigOverride is a functional option that mutates a
// FeeQuoterDestChainConfig in place. Pass one or more overrides to
// DefaultFeeQuoterDestChainConfig to selectively change default values.
// FeeQuoterDestChainConfig in place. Pass one or more overrides to selectively change default values.
type FeeQuoterDestChainConfigOverride func(*FeeQuoterDestChainConfig)

func DefaultFeeQuoterDestChainConfig(configEnabled bool, selector uint64) FeeQuoterDestChainConfig {
chainHex := utils.GetSelectorHex(selector)
params := FeeQuoterDestChainConfig{
IsEnabled: configEnabled,
MaxDataBytes: 30_000,
MaxPerMsgGasLimit: 3_000_000,
DestGasOverhead: 300_000,
DefaultTokenFeeUSDCents: 25,
DestGasPerPayloadByteBase: 16,
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
NetworkFeeUSDCents: 10,
ChainFamilySelector: binary.BigEndian.Uint32(chainHex[:]),
V1Params: &FeeQuoterV1Params{
MaxNumberOfTokensPerMsg: 10,
DestGasPerPayloadByteHigh: 40,
DestGasPerPayloadByteThreshold: 3000,
DestDataAvailabilityOverheadGas: 100,
DestGasPerDataAvailabilityByte: 16,
DestDataAvailabilityMultiplierBps: 1,
GasMultiplierWeiPerEth: 11e17,
},
V2Params: &FeeQuoterV2Params{
LinkFeeMultiplierPercent: 90,
USDPerUnitGas: big.NewInt(1e6),
},
}
family, _ := chain_selectors.GetSelectorFamily(selector)
switch family {
case chain_selectors.FamilyTon:
params.MaxPerMsgGasLimit = 4_200_000_000 // 4_200_000_000 nano TON = 4.2 TON
}
return params
}

func DefaultGasPrice(selector uint64) *big.Int {
family, _ := chain_selectors.GetSelectorFamily(selector)
switch family {
case chain_selectors.FamilyTon:
return big.NewInt(2.12e9) // 1 TON ~2.13 USD -> 1 nanoTON = 2.13e−9 USD -> 1 nanoTON expressed in 1e18 (1 USD) = 2.13e9
}
// Gas price in USD (18 decimals) per unit of gas
// 2e12 = $0.000002 per gas unit
// With ~500,000 gas, this results in ~$1 USD fee per message
return big.NewInt(2e12)
}
16 changes: 16 additions & 0 deletions deployment/lanes/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
cldf_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations"

"github.com/smartcontractkit/chainlink-ccip/deployment/utils"
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/sequences"
)

Expand Down Expand Up @@ -50,6 +51,15 @@ type TokenPriceProvider interface {
GetDefaultTokenPrices() map[datastore.ContractType]*big.Int
}

// ChainMetadataProvider is an optional interface that LaneAdapters can implement
// to expose the on-chain 4-byte chain family selector (e.g. 0x2812d52c for EVM).
// When implemented, the selector is automatically registered in the global
// family-selector registry so that GetSelectorHex can resolve it without a
// hardcoded switch.
type ChainMetadataProvider interface {
GetChainFamilySelector() [4]byte
}

type laneAdapterID string

// LaneAdapterRegistry maintains a registry of LaneAdapters.
Expand All @@ -67,6 +77,8 @@ func newLaneAdapterRegistry() *LaneAdapterRegistry {
}

// RegisterLaneAdapter registers a new adapter; panics if the key already exists.
// If the adapter implements ChainMetadataProvider, its chain family selector is
// also registered in the global family-selector registry for GetSelectorHex.
func (r *LaneAdapterRegistry) RegisterLaneAdapter(chainFamily string, version *semver.Version, adapter LaneAdapter) {
id := newLaneAdapterID(chainFamily, version)

Expand All @@ -77,6 +89,10 @@ func (r *LaneAdapterRegistry) RegisterLaneAdapter(chainFamily string, version *s
panic(fmt.Errorf("LaneAdapter '%s %s' already registered", chainFamily, version))
}
r.m[id] = adapter

if mp, ok := adapter.(ChainMetadataProvider); ok {
utils.RegisterChainFamilySelector(chainFamily, mp.GetChainFamilySelector())
}
}

// GetLaneAdapter looks up an adapter; the second return value tells you if it was found.
Expand Down
50 changes: 28 additions & 22 deletions deployment/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/hex"
"errors"
"fmt"
"sync"

"github.com/Masterminds/semver/v3"

Expand Down Expand Up @@ -35,38 +36,43 @@ const (
// CLL Identifiers
CLLQualifier = "CLLCCIP"
RMNTimelockQualifier = "RMNMCMS"

// https://github.com/smartcontractkit/chainlink/blob/1423e2581e8640d9e5cd06f745c6067bb2893af2/contracts/src/v0.8/ccip/libraries/Internal.sol#L275-L279
/*
```Solidity
// bytes4(keccak256("CCIP ChainFamilySelector EVM"))
bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c;
// bytes4(keccak256("CCIP ChainFamilySelector SVM"));
bytes4 public constant CHAIN_FAMILY_SELECTOR_SVM = 0x1e10bdc4;
```
*/
EVMFamilySelector = "2812d52c"
SVMFamilySelector = "1e10bdc4"
AptosFamilySelector = "ac77ffec"
TVMFamilySelector = "647e2ba9"
SuiFamilySelector = "c4e05953"
)

// familySelectors is a concurrent-safe registry of chain family → 4-byte
// on-chain selector. It is populated automatically when adapters that implement
// ChainMetadataProvider are registered via LaneAdapterRegistry.RegisterLaneAdapter.
var familySelectors sync.Map

// RegisterChainFamilySelector records the 4-byte on-chain selector for a chain
// family (e.g. "evm" → [0x28,0x12,0xd5,0x2c]). Adapters call this indirectly
// through LaneAdapterRegistry.RegisterLaneAdapter.
func RegisterChainFamilySelector(family string, selector [4]byte) {
familySelectors.Store(family, selector)
}

// GetSelectorHex returns the 4-byte on-chain family selector for a given chain
// selector. It first checks the adapter-populated registry (populated when
// adapters that implement ChainMetadataProvider register via
// LaneAdapterRegistry.RegisterLaneAdapter). For chain families whose adapters
// live in external repos and haven't adopted ChainMetadataProvider yet, it
// falls back to inline constants.
func GetSelectorHex(selector uint64) [4]byte {
destFamily, _ := chain_selectors.GetSelectorFamily(selector)

if val, ok := familySelectors.Load(destFamily); ok {
return val.([4]byte)
}

// Fallback for chain families whose adapters haven't implemented
// ChainMetadataProvider yet (external repos).
var hexStr string
switch destFamily {
case chain_selectors.FamilyEVM:
hexStr = EVMFamilySelector
case chain_selectors.FamilySolana:
hexStr = SVMFamilySelector
case chain_selectors.FamilyAptos:
hexStr = AptosFamilySelector
hexStr = "ac77ffec"
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only keeping these for backwards compat while the usages are migrated

case chain_selectors.FamilyTon:
hexStr = TVMFamilySelector
hexStr = "647e2ba9"
case chain_selectors.FamilySui:
hexStr = SuiFamilySelector
hexStr = "c4e05953"
default:
panic(fmt.Sprintf("unsupported chain family: %s", destFamily))
}
Comment thread
tt-cll marked this conversation as resolved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,18 @@ func (m *mockLaneAdapter) GetFQAddress(_ datastore.DataStore, _ uint64) ([]byte,
}

func (m *mockLaneAdapter) GetFeeQuoterDestChainConfig() lanes.FeeQuoterDestChainConfig {
return lanes.DefaultFeeQuoterDestChainConfig(false, chainsel.ETHEREUM_MAINNET.Selector)
return lanes.FeeQuoterDestChainConfig{
IsEnabled: true,
MaxDataBytes: 30_000,
MaxPerMsgGasLimit: 3_000_000,
DestGasOverhead: 300_000,
DestGasPerPayloadByteBase: 16,
ChainFamilySelector: 0x2812d52c,
DefaultTokenFeeUSDCents: 25,
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
NetworkFeeUSDCents: 10,
}
}

func (m *mockLaneAdapter) GetDefaultGasPrice() *big.Int {
Expand Down
Loading
Loading