Skip to content
Draft
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
62 changes: 62 additions & 0 deletions deployment/ccip/1_6_0/sequences/adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package sequences

import (
"fmt"

"github.com/Masterminds/semver/v3"
chainSelectors "github.com/smartcontractkit/chain-selectors"
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
tonstate "github.com/smartcontractkit/chainlink-ton/deployment/state"

ccipapi "github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
)

func init() {
v, err := semver.NewVersion("1.6.0")
if err != nil {
panic(err)
}
ccipapi.GetLaneAdapterRegistry().RegisterLaneAdapter(chainSelectors.FamilyTon, v, &TonAdapter{})
}

type TonAdapter struct{}

func (a *TonAdapter) GetOnRampAddress(env *cldf.Environment, chainSelector uint64) ([]byte, error) {
tonChains, err := tonstate.LoadOnchainState(*env)
if err != nil {
return []byte{}, fmt.Errorf("failed to load TON onchain state: %w", err)
}

onrampAddress := tonChains[chainSelector].OnRamp
return onrampAddress.Data(), nil
}

func (a *TonAdapter) GetOffRampAddress(env *cldf.Environment, chainSelector uint64) ([]byte, error) {
tonChains, err := tonstate.LoadOnchainState(*env)
if err != nil {
return []byte{}, fmt.Errorf("failed to load TON onchain state: %w", err)
}

offrampAddress := tonChains[chainSelector].OffRamp
return offrampAddress.Data(), nil
}

func (a *TonAdapter) GetFQAddress(env *cldf.Environment, chainSelector uint64) ([]byte, error) {
tonChains, err := tonstate.LoadOnchainState(*env)
if err != nil {
return []byte{}, fmt.Errorf("failed to load TON onchain state: %w", err)
}

feeQuoterAddress := tonChains[chainSelector].FeeQuoter
return feeQuoterAddress.Data(), nil
}

func (a *TonAdapter) GetRouterAddress(env *cldf.Environment, chainSelector uint64) ([]byte, error) {
tonChains, err := tonstate.LoadOnchainState(*env)
if err != nil {
return []byte{}, fmt.Errorf("failed to load TON onchain state: %w", err)
}

routerAddress := tonChains[chainSelector].Router
return routerAddress.Data(), nil
}
224 changes: 224 additions & 0 deletions deployment/ccip/1_6_0/sequences/connect_chains.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package sequences

import (
"fmt"

"github.com/Masterminds/semver/v3"
"github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
ccipapi "github.com/smartcontractkit/chainlink-ccip/deployment/lanes"
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/sequences"
cldfChain "github.com/smartcontractkit/chainlink-deployments-framework/chain"
"github.com/smartcontractkit/chainlink-deployments-framework/chain/ton"
cldfTon "github.com/smartcontractkit/chainlink-deployments-framework/chain/ton"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
cldfOps "github.com/smartcontractkit/chainlink-deployments-framework/operations"
"github.com/smartcontractkit/chainlink-ton/deployment/ccip/operation"
"github.com/smartcontractkit/chainlink-ton/deployment/state"
"github.com/smartcontractkit/chainlink-ton/pkg/ccip/bindings/feequoter"
"github.com/smartcontractkit/chainlink-ton/pkg/ccip/bindings/router"
"github.com/smartcontractkit/chainlink-ton/pkg/ccip/codec"
"github.com/xssnick/tonutils-go/address"
)

func (a *TonAdapter) ConfigureLaneLegAsSource() *cldfOps.Sequence[ccipapi.UpdateLanesInput, sequences.OnChainOutput, cldfChain.BlockChains] {
return ConfigureLaneLegAsSource
}

func (a *TonAdapter) ConfigureLaneLegAsDest() *cldfOps.Sequence[ccipapi.UpdateLanesInput, sequences.OnChainOutput, cldfChain.BlockChains] {
return ConfigureLaneLegAsDest
}

var ConfigureLaneLegAsSource = cldfOps.NewSequence(
"ConfigureLaneLegAsSource",
semver.MustParse("1.6.0"),
"Configures lane leg as source on CCIP 1.6.0",
func(b operations.Bundle, chains cldfChain.BlockChains, input lanes.UpdateLanesInput) (sequences.OnChainOutput, error) {
var txs [][]byte

deps, err := extractTonDeps(input)
if err != nil {
return sequences.OnChainOutput{}, fmt.Errorf("failed to extract TON deps: %w", err)
}

// update fee quoter with dest chain configs
updateFeeQuoterDestChainConfigs := mapToUpdateFeeQuoterDestChainConfigs(input)
b.Logger.Infow("Updating destination configs on FeeQuoter", "input", updateFeeQuoterDestChainConfigs)
feeQuoterReport, err := operations.ExecuteOperation(b, operation.UpdateFeeQuoterDestChainConfigsOp, deps, updateFeeQuoterDestChainConfigs)
if err != nil {
return sequences.OnChainOutput{}, fmt.Errorf("failed to update feequoter destinations: %w", err)
}
txs = append(txs, feeQuoterReport.Output...)

// update onramp with dest chain configs
updateOnRampDestChainConfigs := mapToUpdateOnRampDestChainConfigs(input)
b.Logger.Infow("Updating destination configs on OnRamp", "input", updateOnRampDestChainConfigs)
onRampReport, err := operations.ExecuteOperation(b, operation.UpdateOnRampDestChainConfigsOp, deps, updateOnRampDestChainConfigs)
if err != nil {
return sequences.OnChainOutput{}, fmt.Errorf("failed to update onramp destinations: %w", err)
}
txs = append(txs, onRampReport.Output...)

// update fee quoter with gas prices
updateFeeQuoterPricesConfig := mapToUpdateFeeQuoterPricesConfig(input)
b.Logger.Infow("Updating prices on FeeQuoter", "input", updateFeeQuoterPricesConfig)
updatePricesReport, err := operations.ExecuteOperation(b, operation.UpdateFeeQuoterPricesOp, deps, updateFeeQuoterPricesConfig)
if err != nil {
return sequences.OnChainOutput{}, fmt.Errorf("failed to update feequoter prices: %w", err)
}
txs = append(txs, updatePricesReport.Output...)

return sequences.OnChainOutput{}, nil
},
)

var ConfigureLaneLegAsDest = cldfOps.NewSequence(
"ConfigureLaneLegAsDest",
semver.MustParse("1.6.0"),
"Configures lane leg as dest on CCIP 1.6.0",
func(b operations.Bundle, chains cldfChain.BlockChains, input lanes.UpdateLanesInput) (sequences.OnChainOutput, error) {
var txs [][]byte

deps, err := extractTonDeps(input)
if err != nil {
return sequences.OnChainOutput{}, fmt.Errorf("failed to extract TON deps: %w", err)
}

// configure offramp sources
updateOffRampSourcesConfig := mapToUpdateOffRampSourcesConfig(input)
b.Logger.Infow("Updating source configs on OffRamp", "input", updateOffRampSourcesConfig)
offRampReport, err := operations.ExecuteOperation(b, operation.UpdateOffRampSourceChainConfigsOp, deps, updateOffRampSourcesConfig)
if err != nil {
return sequences.OnChainOutput{}, fmt.Errorf("failed to update offramp sources: %w", err)
}
txs = append(txs, offRampReport.Output...)

// add ccip owner to offramp allowlist

// update router with destination onramp versions
updateRouterDestConfig := mapToUpdateRouterDestConfig(input)
b.Logger.Infow("Updating Router", "input", updateRouterDestConfig)
routerReport, err := operations.ExecuteOperation(b, operation.UpdateRouterDestOp, deps, updateRouterDestConfig)
if err != nil {
return sequences.OnChainOutput{}, fmt.Errorf("failed to update router: %w", err)
}
txs = append(txs, routerReport.Output...)

return sequences.OnChainOutput{}, nil
},
)

func extractTonDeps(input lanes.UpdateLanesInput) (operation.TonDeps, error) {
onRampAddr, err := codec.AddressBytesToTONAddress(input.Source.OnRamp)
if err != nil {
return operation.TonDeps{}, fmt.Errorf("failed to convert onramp address: %w", err)
}
offRampAddr, err := codec.AddressBytesToTONAddress(input.Source.OffRamp)
if err != nil {
return operation.TonDeps{}, fmt.Errorf("failed to convert offramp address: %w", err)
}
routerAddr, err := codec.AddressBytesToTONAddress(input.Source.Router)
if err != nil {
return operation.TonDeps{}, fmt.Errorf("failed to convert router address: %w", err)
}
feeQuoterAddr, err := codec.AddressBytesToTONAddress(input.Source.FeeQuoter)
if err != nil {
return operation.TonDeps{}, fmt.Errorf("failed to convert feequoter address: %w", err)
}
deps := operation.TonDeps{
TonChain: cldfTon.Chain{ // TODO: Check if this is correct
ChainMetadata: ton.ChainMetadata{
Selector: input.Source.Selector,
},
Client: nil,
Wallet: nil,
WalletAddress: nil,
URL: "",
},
CCIPOnChainState: map[uint64]state.CCIPChainState{
input.Source.Selector: {
OnRamp: *onRampAddr,
OffRamp: *offRampAddr,
Router: *routerAddr,
FeeQuoter: *feeQuoterAddr,
ReceiverAddress: *address.NewAddressNone(), // TODO: Check if this is correct
},
},
}
return deps, nil
}

func mapToUpdateFeeQuoterDestChainConfigs(input lanes.UpdateLanesInput) operation.UpdateFeeQuoterDestChainConfigsInput {
return []feequoter.UpdateDestChainConfig{
{
DestinationChainSelector: input.Dest.Selector,
DestChainConfig: feequoter.DestChainConfig{
IsEnabled: input.Dest.FeeQuoterDestChainConfig.IsEnabled,
MaxNumberOfTokensPerMsg: input.Dest.FeeQuoterDestChainConfig.MaxNumberOfTokensPerMsg,
MaxDataBytes: input.Dest.FeeQuoterDestChainConfig.MaxDataBytes,
MaxPerMsgGasLimit: input.Dest.FeeQuoterDestChainConfig.MaxPerMsgGasLimit,
DestGasOverhead: input.Dest.FeeQuoterDestChainConfig.DestGasOverhead,
DestGasPerPayloadByteBase: input.Dest.FeeQuoterDestChainConfig.DestGasPerPayloadByteBase,
DestGasPerPayloadByteHigh: input.Dest.FeeQuoterDestChainConfig.DestGasPerPayloadByteHigh,
DestGasPerPayloadByteThreshold: input.Dest.FeeQuoterDestChainConfig.DestGasPerPayloadByteThreshold,
DestDataAvailabilityOverheadGas: input.Dest.FeeQuoterDestChainConfig.DestDataAvailabilityOverheadGas,
DestGasPerDataAvailabilityByte: input.Dest.FeeQuoterDestChainConfig.DestGasPerDataAvailabilityByte,
DestDataAvailabilityMultiplierBps: input.Dest.FeeQuoterDestChainConfig.DestDataAvailabilityMultiplierBps,
ChainFamilySelector: input.Dest.FeeQuoterDestChainConfig.ChainFamilySelector,
EnforceOutOfOrder: input.Dest.FeeQuoterDestChainConfig.EnforceOutOfOrder,
DefaultTokenFeeUsdCents: input.Dest.FeeQuoterDestChainConfig.DefaultTokenFeeUSDCents,
DefaultTokenDestGasOverhead: input.Dest.FeeQuoterDestChainConfig.DefaultTokenDestGasOverhead,
DefaultTxGasLimit: input.Dest.FeeQuoterDestChainConfig.DefaultTxGasLimit,
GasMultiplierWeiPerEth: input.Dest.FeeQuoterDestChainConfig.GasMultiplierWeiPerEth,
GasPriceStalenessThreshold: input.Dest.FeeQuoterDestChainConfig.GasPriceStalenessThreshold,
NetworkFeeUsdCents: input.Dest.FeeQuoterDestChainConfig.NetworkFeeUSDCents,
},
},
}
}

func mapToUpdateOnRampDestChainConfigs(input ccipapi.UpdateLanesInput) operation.UpdateOnRampDestChainConfigsInput {
return operation.UpdateOnRampDestChainConfigsInput{
Updates: map[uint64]operation.OnRampDestinationUpdate{
input.Dest.Selector: {
IsEnabled: !input.IsDisabled,
TestRouter: input.TestRouter,
AllowListEnabled: input.Dest.AllowListEnabled,
},
},
}
}

func mapToUpdateFeeQuoterPricesConfig(input ccipapi.UpdateLanesInput) operation.UpdateFeeQuoterPricesInput {
return operation.UpdateFeeQuoterPricesInput{
TokenPrices: input.Dest.TokenPrices,
GasPrices: map[uint64]operation.GasPrice{
input.Dest.Selector: {
ExecutionGasPrice: input.Dest.GasPrice,
DataAvailabilityGasPrice: input.Dest.GasPrice,
},
},
}
}

func mapToUpdateOffRampSourcesConfig(input ccipapi.UpdateLanesInput) operation.UpdateOffRampSourcesInput {
return operation.UpdateOffRampSourcesInput{
Updates: map[uint64]operation.OffRampSourceUpdate{
input.Source.Selector: {
IsEnabled: true,
TestRouter: false, // TODO: Should we check if the source is a test router?
IsRMNVerificationDisabled: !input.Source.RMNVerificationEnabled,
OnRamp: input.Source.OnRamp,
},
},
}
}

func mapToUpdateRouterDestConfig(input ccipapi.UpdateLanesInput) operation.UpdateRouterDestInput {
return operation.UpdateRouterDestInput{ // TODO: Check if this map is correct
string(input.Dest.OnRamp): []router.DestChainSelector{
{
Value: input.Dest.Selector,
},
},
}
}
Loading
Loading