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
19 changes: 14 additions & 5 deletions ccv/chains/evm/deployment/v1_7_0/adapters/chain_family.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package adapters

import (
seq_core "github.com/smartcontractkit/chainlink-ccip/deployment/utils/sequences"
"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"

"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/v1_7_0/sequences"

datastore_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore"

"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/latest/operations/offramp"
"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/latest/operations/onramp"
"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/v1_7_0/sequences"
"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/v2_0_0/operations/fee_quoter"
evm_datastore_utils "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/utils/datastore"
evm_sequences "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/sequences"
"github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_2_0/operations/router"
"github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
datastore_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore"
seq_core "github.com/smartcontractkit/chainlink-ccip/deployment/utils/sequences"
)

// ChainFamilyAdapter is the adapter for chains of the EVM family.
Expand Down Expand Up @@ -83,3 +84,11 @@ func (a *ChainFamilyAdapter) GetRouterAddress(ds datastore.DataStore, chainSelec
}
return addr, nil
}

func (a *ChainFamilyAdapter) GetFeeQuoterDestChainConfig() lanes.FeeQuoterDestChainConfig {
return lanes.DefaultFeeQuoterDestChainConfig(false, chainsel.ETHEREUM_MAINNET.Selector)
}

func (a *ChainFamilyAdapter) GetDefaultGasPrice() *big.Int {
return big.NewInt(2e12)
}
13 changes: 6 additions & 7 deletions chains/evm/deployment/v1_6_0/changesets/connect_chains_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ func checkBidirectionalLaneConnectivity(

feeQuoterDestConfig, err := feeQuoterOnSrc.GetDestChainConfig(nil, lane.Dest.Selector)
require.NoError(t, err, "must get dest chain config from feeQuoter")
expectedConfig := convertOpsConfigToGobinding(sequences.TranslateFQ(lane.Dest.FeeQuoterDestChainConfig))
a := &sequences.EVMAdapter{}
expectedConfig := convertOpsConfigToGobinding(sequences.TranslateFQ(a.GetFeeQuoterDestChainConfig()))
require.Equal(t, expectedConfig, feeQuoterDestConfig, "feeQuoter dest chain config must equal expected")

price, err := feeQuoterOnSrc.GetDestinationChainGasPrice(nil, lane.Dest.Selector)
Expand Down Expand Up @@ -191,14 +192,12 @@ func TestConnectChains_EVM2EVM_NoMCMS(t *testing.T) {
e.DataStore = out.DataStore.Seal()
}
chain1 := lanesapi.ChainDefinition{
Selector: chain_selectors.ETHEREUM_MAINNET.Selector,
GasPrice: big.NewInt(1e17),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.ETHEREUM_MAINNET.Selector),
Selector: chain_selectors.ETHEREUM_MAINNET.Selector,
GasPrice: big.NewInt(1e17),
}
chain2 := lanesapi.ChainDefinition{
Selector: chain_selectors.POLYGON_MAINNET.Selector,
GasPrice: big.NewInt(1e9),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.POLYGON_MAINNET.Selector),
Selector: chain_selectors.POLYGON_MAINNET.Selector,
GasPrice: big.NewInt(1e9),
}

_, err = lanesapi.ConnectChains(lanesapi.GetLaneAdapterRegistry(), mcmsRegistry).Apply(*e, lanesapi.ConnectChainsConfig{
Expand Down
31 changes: 31 additions & 0 deletions chains/evm/deployment/v1_6_0/sequences/adapter.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sequences

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

Expand All @@ -25,6 +26,7 @@ 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 @@ -188,3 +190,32 @@ func GetFeeQuoterAddress(addresses []datastore.AddressRef, chainSelector uint64)
}
return feeQRef, nil
}

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[:]),
DefaultTokenFeeUSDCents: 25,
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
NetworkFeeUSDCents: 10,
V1Params: &ccipapi.FeeQuoterV1Params{
MaxNumberOfTokensPerMsg: 10,
DestGasPerPayloadByteHigh: 40,
DestGasPerPayloadByteThreshold: 3000,
DestDataAvailabilityOverheadGas: 100,
DestGasPerDataAvailabilityByte: 16,
DestDataAvailabilityMultiplierBps: 1,
GasMultiplierWeiPerEth: 11e17,
},
}
}

func (a *EVMAdapter) GetDefaultGasPrice() *big.Int {
return big.NewInt(2e12)
}
33 changes: 33 additions & 0 deletions chains/solana/deployment/v1_6_0/sequences/adapter.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sequences

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

"github.com/Masterminds/semver/v3"
"github.com/gagliardetto/solana-go"
chain_selectors "github.com/smartcontractkit/chain-selectors"
Expand All @@ -15,6 +18,7 @@ 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 @@ -86,3 +90,32 @@ func (a *SolanaAdapter) GetRMNRemoteAddress(ds datastore.DataStore, chainSelecto
}
return addr, nil
}

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[:]),
DefaultTokenFeeUSDCents: 25,
DefaultTokenDestGasOverhead: 90_000,
DefaultTxGasLimit: 200_000,
NetworkFeeUSDCents: 10,
V1Params: &laneapi.FeeQuoterV1Params{
MaxNumberOfTokensPerMsg: 10,
DestGasPerPayloadByteHigh: 40,
DestGasPerPayloadByteThreshold: 3000,
DestDataAvailabilityOverheadGas: 100,
DestGasPerDataAvailabilityByte: 16,
DestDataAvailabilityMultiplierBps: 1,
GasMultiplierWeiPerEth: 11e17,
},
}
}

func (a *SolanaAdapter) GetDefaultGasPrice() *big.Int {
return big.NewInt(4e12)
}
11 changes: 11 additions & 0 deletions deployment/lanes/connect_chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func makeApply(laneRegistry *LaneAdapterRegistry, mcmsRegistry *changesets.MCMSR
if err != nil {
return cldf.ChangesetOutput{}, fmt.Errorf("error fetching address for dest chain %d: %w", chainB.Selector, err)
}
// to allow for type serialization, we apply fee quoter dest chain config overrides
// at the lane level and then set them to nil before passing to the adapters
chainA.FeeQuoterDestChainConfigOverrides = nil
chainB.FeeQuoterDestChainConfigOverrides = nil
type lanePair struct {
src *ChainDefinition
dest *ChainDefinition
Expand Down Expand Up @@ -142,6 +146,13 @@ func populateAddresses(ds datastore.DataStore, chainDef *ChainDefinition, adapte
if err != nil {
return fmt.Errorf("error fetching router address for chain %d: %w", chainDef.Selector, err)
}
chainDef.FeeQuoterDestChainConfig = adapter.GetFeeQuoterDestChainConfig()
if chainDef.FeeQuoterDestChainConfigOverrides != nil {
(*chainDef.FeeQuoterDestChainConfigOverrides)(&chainDef.FeeQuoterDestChainConfig)
}
if chainDef.GasPrice == nil {
chainDef.GasPrice = adapter.GetDefaultGasPrice()
}
// handle v2 separately
return populateAddressesV2(ds, chainDef, adapter, version)
}
Expand Down
14 changes: 11 additions & 3 deletions deployment/lanes/lane_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ type ChainDefinition struct {
// This is provided by the user
// 1.6 only
TokenPrices map[string]*big.Int
// FeeQuoterDestChainConfig is the configuration to be applied on source chain when this chain is a destination.
// This is provided by the user
FeeQuoterDestChainConfig FeeQuoterDestChainConfig
// FeeQuoterDestChainConfigOverrides is a functional option that mutates a
// FeeQuoterDestChainConfig in place. Pass one or more overrides to selectively change default values.
FeeQuoterDestChainConfigOverrides *FeeQuoterDestChainConfigOverride
// RMNVerificationEnabled is true if we want the RMN to bless messages FROM this chain.
// This is provided by the user
// 1.6 only
Expand Down Expand Up @@ -76,6 +76,9 @@ type ChainDefinition struct {
// FeeQuoter is the address of the FeeQuoter contract on this chain.
// This is populated programmatically
FeeQuoter []byte
// FeeQuoterDestChainConfig is the configuration that should be applied to this chain's FeeQuoter for it to be a destination in the lane.
// This is populated programmatically and is based on the chain family, with possible overrides from the user.
FeeQuoterDestChainConfig FeeQuoterDestChainConfig
}

// CantonLaneConfig holds Canton-specific configuration for lane setup.
Expand Down Expand Up @@ -202,6 +205,11 @@ type UpdateLanesInput struct {
ExtraConfigs ExtraConfigs
}

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

func DefaultFeeQuoterDestChainConfig(configEnabled bool, selector uint64) FeeQuoterDestChainConfig {
chainHex := utils.GetSelectorHex(selector)
params := FeeQuoterDestChainConfig{
Expand Down
3 changes: 3 additions & 0 deletions deployment/lanes/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type LaneAdapter interface {
GetOffRampAddress(ds datastore.DataStore, chainSelector uint64) ([]byte, error)
GetRouterAddress(ds datastore.DataStore, chainSelector uint64) ([]byte, error)
GetFQAddress(ds datastore.DataStore, chainSelector uint64) ([]byte, error)
GetFeeQuoterDestChainConfig() FeeQuoterDestChainConfig
// GasPrice defines the USD price (18 decimals) per unit gas for this chain as a destination.
GetDefaultGasPrice() *big.Int
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice, since you are adding this default gas price value, I'm also thinking about if we should provide the default token price as well. This because the existing evm add lane changeset will update the fq destChain config, but we used empty tokenPrice map in our changeset. Doesn't have to be in this PR, but worth adding to TODOs cc @krebernisak @nicolasgnr

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes I think we should

}

// TokenPriceProvider is an optional interface that LaneAdapters can implement
Expand Down
6 changes: 5 additions & 1 deletion deployment/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ func GetSelectorHex(selector uint64) [4]byte {
panic(fmt.Sprintf("unsupported chain family: %s", destFamily))
}

b, _ := hex.DecodeString(hexStr)
return GetHexFromString(hexStr)
}

func GetHexFromString(hexstr string) [4]byte {
b, _ := hex.DecodeString(hexstr)
var out [4]byte
copy(out[:], b)
return out
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package changesets_test
import (
"context"
"fmt"
"math/big"
"strconv"
"testing"

Expand Down Expand Up @@ -133,6 +134,14 @@ func (m *mockLaneAdapter) GetFQAddress(_ datastore.DataStore, _ uint64) ([]byte,
return []byte("0xFeeQuoter"), nil
}

func (m *mockLaneAdapter) GetFeeQuoterDestChainConfig() lanes.FeeQuoterDestChainConfig {
return lanes.DefaultFeeQuoterDestChainConfig(false, chainsel.ETHEREUM_MAINNET.Selector)
}

func (m *mockLaneAdapter) GetDefaultGasPrice() *big.Int {
return big.NewInt(2e12)
}

func (m *mockLaneAdapter) DisableRemoteChain() *cldf_ops.Sequence[lanes.DisableRemoteChainInput, sequences.OnChainOutput, cldf_chain.BlockChains] {
return nil
}
Expand Down
4 changes: 0 additions & 4 deletions devenv/common/implcommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,6 @@ func ConnectContractsWithSelectors(ctx context.Context, e *deployment.Environmen

chainA := lanesapi.ChainDefinition{
Selector: selector,
GasPrice: lanesapi.DefaultGasPrice(selector),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, selector),
TokenPrices: chainATokenPrices,
}
for _, destSelector := range remoteSelectors {
Expand All @@ -298,8 +296,6 @@ func ConnectContractsWithSelectors(ctx context.Context, e *deployment.Environmen

chainB := lanesapi.ChainDefinition{
Selector: destSelector,
GasPrice: lanesapi.DefaultGasPrice(destSelector),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, destSelector),
TokenPrices: chainBTokenPrices,
}
_, err := lanesapi.ConnectChains(lanesapi.GetLaneAdapterRegistry(), mcmsRegistry).Apply(*e, lanesapi.ConnectChainsConfig{
Expand Down
46 changes: 30 additions & 16 deletions integration-tests/deployment/connect_chains_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ func convertOpsConfigToGobinding(cfg evmfqops.DestChainConfig) evmfq.FeeQuoterDe
}
}

func getFQOverrides() lanesapi.FeeQuoterDestChainConfigOverride {
override := lanesapi.FeeQuoterDestChainConfigOverride(func(c *lanesapi.FeeQuoterDestChainConfig) {
c.MaxDataBytes = 60_000
if c.V1Params != nil {
c.V1Params.EnforceOutOfOrder = true
}
})
return override
}

func checkBidirectionalLaneConnectivity(
t *testing.T,
e *fdeployment.Environment,
Expand Down Expand Up @@ -123,7 +133,8 @@ func checkBidirectionalLaneConnectivity(
err = e.BlockChains.SolanaChains()[solanaChain.Selector].GetAccountDataBorshInto(e.GetContext(), fqEvmDestChainPDA, &destChainFqAccount)
require.NoError(t, err, "failed to get account info")
require.Equal(t, !disable, destChainFqAccount.Config.IsEnabled)
require.Equal(t, solanasequences.TranslateFQ(evmChain.FeeQuoterDestChainConfig), destChainFqAccount.Config)
ea := evmsequences.EVMAdapter{}
require.Equal(t, solanasequences.TranslateFQ(ea.GetFeeQuoterDestChainConfig()), destChainFqAccount.Config)

// Validate EVM onRamp/OffRamp/Router/FeeQuoter state
destChainConfig, err := onRampDest.GetDestChainConfig(nil, solanaChain.Selector)
Expand Down Expand Up @@ -155,7 +166,11 @@ func checkBidirectionalLaneConnectivity(

feeQuoterDestConfig, err := feeQuoterOnDest.GetDestChainConfig(nil, solanaChain.Selector)
require.NoError(t, err, "must get dest chain config from feeQuoter")
expectedConfig := convertOpsConfigToGobinding(evmsequences.TranslateFQ(solanaChain.FeeQuoterDestChainConfig))
sa := solanasequences.SolanaAdapter{}
safq := sa.GetFeeQuoterDestChainConfig()
override := getFQOverrides()
override(&safq)
expectedConfig := convertOpsConfigToGobinding(evmsequences.TranslateFQ(safq))
require.Equal(t, expectedConfig, feeQuoterDestConfig, "feeQuoter dest chain config must equal expected")

price, err := feeQuoterOnDest.GetDestinationChainGasPrice(nil, solanaChain.Selector)
Expand Down Expand Up @@ -262,17 +277,17 @@ func TestConnectChains_EVM2SVM_NoMCMS(t *testing.T) {
}
DeployMCMS(t, e, chain_selectors.SOLANA_MAINNET.Selector, []string{cciputils.CLLQualifier})
SolanaTransferOwnership(t, e, chain_selectors.SOLANA_MAINNET.Selector)
DeployMCMS(t, e, chain_selectors.ETHEREUM_MAINNET.Selector, []string{cciputils.CLLQualifier})
EVMTransferOwnership(t, e, chain_selectors.ETHEREUM_MAINNET.Selector)
// TODO: EVM doesn't work with a non-zero timelock delay
// DeployMCMS(t, e, chain_selectors.ETHEREUM_MAINNET.Selector)
// EVMTransferOwnership(t, e, chain_selectors.ETHEREUM_MAINNET.Selector)
override := getFQOverrides()
chain1 := lanesapi.ChainDefinition{
Selector: chain_selectors.SOLANA_MAINNET.Selector,
GasPrice: big.NewInt(1e17),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.SOLANA_MAINNET.Selector),
Selector: chain_selectors.SOLANA_MAINNET.Selector,
GasPrice: big.NewInt(1e17),
FeeQuoterDestChainConfigOverrides: &override,
}
chain2 := lanesapi.ChainDefinition{
Selector: chain_selectors.ETHEREUM_MAINNET.Selector,
GasPrice: big.NewInt(1e9),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.ETHEREUM_MAINNET.Selector),
Selector: chain_selectors.ETHEREUM_MAINNET.Selector,
}

connectOut, err := lanesapi.ConnectChains(lanesapi.GetLaneAdapterRegistry(), mcmsRegistry).Apply(*e, lanesapi.ConnectChainsConfig{
Expand Down Expand Up @@ -357,15 +372,14 @@ func TestDisableLane_EVM2SVM(t *testing.T) {
DeployMCMS(t, e, chain_selectors.SOLANA_MAINNET.Selector, []string{cciputils.CLLQualifier})
SolanaTransferOwnership(t, e, chain_selectors.SOLANA_MAINNET.Selector)

override := getFQOverrides()
chain1 := lanesapi.ChainDefinition{
Selector: chain_selectors.SOLANA_MAINNET.Selector,
GasPrice: big.NewInt(1e17),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.SOLANA_MAINNET.Selector),
Selector: chain_selectors.SOLANA_MAINNET.Selector,
GasPrice: big.NewInt(1e17),
FeeQuoterDestChainConfigOverrides: &override,
}
chain2 := lanesapi.ChainDefinition{
Selector: chain_selectors.ETHEREUM_MAINNET.Selector,
GasPrice: big.NewInt(1e9),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.ETHEREUM_MAINNET.Selector),
Selector: chain_selectors.ETHEREUM_MAINNET.Selector,
}

connectOut, err := lanesapi.ConnectChains(lanesapi.GetLaneAdapterRegistry(), mcmsRegistry).Apply(*e, lanesapi.ConnectChainsConfig{
Expand Down
2 changes: 0 additions & 2 deletions integration-tests/deployment/lane_migrator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ func TestMigrateTo1_6_0(t *testing.T) {
chain1 := lanesapi.ChainDefinition{
Selector: chain_selectors.ETHEREUM_MAINNET.Selector,
GasPrice: big.NewInt(1e9),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.ETHEREUM_MAINNET.Selector),
Router: testRouterRefChain1.Bytes(),
}
testRouterRefChain2, err := datastore_utils.FindAndFormatRef(
Expand All @@ -83,7 +82,6 @@ func TestMigrateTo1_6_0(t *testing.T) {
chain2 := lanesapi.ChainDefinition{
Selector: chain_selectors.AVALANCHE_MAINNET.Selector,
GasPrice: big.NewInt(1e9),
FeeQuoterDestChainConfig: lanesapi.DefaultFeeQuoterDestChainConfig(true, chain_selectors.AVALANCHE_MAINNET.Selector),
Router: testRouterRefChain2.Bytes(),
}
_, err = lanesapi.ConnectChains(lanesapi.GetLaneAdapterRegistry(), mcmsRegistry).Apply(*e, lanesapi.ConnectChainsConfig{
Expand Down
Loading
Loading