Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CCIP-4320 ccip changeset parametrize #15989

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
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
13 changes: 9 additions & 4 deletions deployment/ccip/changeset/cs_ccip_home_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ func TestInvalidOCR3Params(t *testing.T) {
{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContractsChangeset),
Config: changeset.DeployChainContractsConfig{
ChainSelectors: []uint64{chain1},
HomeChainSelector: e.HomeChainSel,
ContractParamsPerChain: map[uint64]changeset.ContractParams{
chain1: {
FeeQuoterParams: changeset.DefaultFeeQuoterParams(),
OffRampParams: changeset.DefaultOffRampParams(),
},
},
},
},
})
Expand Down Expand Up @@ -557,9 +562,9 @@ func Test_UpdateChainConfigs(t *testing.T) {
RemoteChainAdds: map[uint64]changeset.ChainConfig{
otherChain: {
EncodableChainConfig: chainconfig.ChainConfig{
GasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(internal.GasPriceDeviationPPB)},
DAGasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(internal.DAGasPriceDeviationPPB)},
OptimisticConfirmations: internal.OptimisticConfirmations,
GasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(testhelpers.GasPriceDeviationPPB)},
DAGasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(testhelpers.DAGasPriceDeviationPPB)},
OptimisticConfirmations: testhelpers.OptimisticConfirmations,
},
FChain: otherChainConfig.FChain,
Readers: otherChainConfig.Readers,
Expand Down
128 changes: 102 additions & 26 deletions deployment/ccip/changeset/cs_deploy_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func DeployChainContractsChangeset(env deployment.Environment, c DeployChainCont
return deployment.ChangesetOutput{}, fmt.Errorf("invalid DeployChainContractsConfig: %w", err)
}
newAddresses := deployment.NewMemoryAddressBook()
err := deployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors)
err := deployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ContractParamsPerChain)
if err != nil {
env.Logger.Errorw("Failed to deploy CCIP contracts", "err", err, "newAddresses", newAddresses)
return deployment.ChangesetOutput{AddressBook: newAddresses}, deployment.MaybeDataErr(err)
Expand All @@ -52,27 +52,108 @@ func DeployChainContractsChangeset(env deployment.Environment, c DeployChainCont
}

type DeployChainContractsConfig struct {
ChainSelectors []uint64
HomeChainSelector uint64
HomeChainSelector uint64
ContractParamsPerChain map[uint64]ContractParams
}

func (c DeployChainContractsConfig) Validate() error {
for _, cs := range c.ChainSelectors {
if err := deployment.IsValidChainSelector(c.HomeChainSelector); err != nil {
return fmt.Errorf("invalid home chain selector: %d - %w", c.HomeChainSelector, err)
}
for cs, args := range c.ContractParamsPerChain {
if err := deployment.IsValidChainSelector(cs); err != nil {
return fmt.Errorf("invalid chain selector: %d - %w", cs, err)
}
if err := args.Validate(); err != nil {
return fmt.Errorf("invalid contract args for chain %d: %w", cs, err)
}
}
if err := deployment.IsValidChainSelector(c.HomeChainSelector); err != nil {
return fmt.Errorf("invalid home chain selector: %d - %w", c.HomeChainSelector, err)
return nil
}

type ContractParams struct {
FeeQuoterParams FeeQuoterParams
OffRampParams OffRampParams
}

func (c ContractParams) Validate() error {
if err := c.FeeQuoterParams.Validate(); err != nil {
return fmt.Errorf("invalid FeeQuoterParams: %w", err)
}
if err := c.OffRampParams.Validate(); err != nil {
return fmt.Errorf("invalid OffRampParams: %w", err)
}
return nil
}

func deployChainContractsForChains(
e deployment.Environment,
ab deployment.AddressBook,
homeChainSel uint64,
chainsToDeploy []uint64) error {
type FeeQuoterParams struct {
MaxFeeJuelsPerMsg *big.Int
TokenPriceStalenessThreshold uint32
LinkPremiumMultiplierWeiPerEth uint64
WethPremiumMultiplierWeiPerEth uint64
}

func (c FeeQuoterParams) Validate() error {
if c.MaxFeeJuelsPerMsg == nil {
return errors.New("MaxFeeJuelsPerMsg is nil")
}
if c.MaxFeeJuelsPerMsg.Cmp(big.NewInt(0)) <= 0 {
return errors.New("MaxFeeJuelsPerMsg must be positive")
}
if c.TokenPriceStalenessThreshold == 0 {
return errors.New("TokenPriceStalenessThreshold can't be 0")
}
return nil
}

func DefaultFeeQuoterParams() FeeQuoterParams {
return FeeQuoterParams{
MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)),
TokenPriceStalenessThreshold: uint32(24 * 60 * 60),
LinkPremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH,
WethPremiumMultiplierWeiPerEth: 1e18, // 1.0 ETH,
}
}

type OffRampParams struct {
GasForCallExactCheck uint16
PermissionLessExecutionThresholdSeconds uint32
IsRMNVerificationDisabled bool
}

func (c OffRampParams) Validate() error {
if c.GasForCallExactCheck == 0 {
return errors.New("GasForCallExactCheck is 0")
}
if c.PermissionLessExecutionThresholdSeconds == 0 {
return errors.New("PermissionLessExecutionThresholdSeconds is 0")
}
return nil
}

func DefaultOffRampParams() OffRampParams {
return OffRampParams{
GasForCallExactCheck: uint16(5000),
PermissionLessExecutionThresholdSeconds: uint32(24 * 60 * 60),
IsRMNVerificationDisabled: true,
}
}

func DeriveContractParams(opts ...interface{}) (*ContractParams, error) {
params := &ContractParams{}
for _, opt := range opts {
if f, ok := opt.(FeeQuoterParams); ok {
params.FeeQuoterParams = f
} else if f, ok := opt.(OffRampParams); ok {
params.OffRampParams = f
} else {
return nil, fmt.Errorf("unknown option type: %T", opt)
}
}
return params, nil
}

func deployChainContractsForChains(e deployment.Environment, ab deployment.AddressBook, homeChainSel uint64, contractParamsPerChain map[uint64]ContractParams) error {
existingState, err := LoadOnchainState(e)
if err != nil {
e.Logger.Errorw("Failed to load existing onchain state", "err")
Expand Down Expand Up @@ -114,7 +195,7 @@ func deployChainContractsForChains(
return errors.New("rmn home not found")
}
deployGrp := errgroup.Group{}
for _, chainSel := range chainsToDeploy {
for chainSel, contractParams := range contractParamsPerChain {
chain, ok := e.Chains[chainSel]
if !ok {
return fmt.Errorf("chain %d not found", chainSel)
Expand All @@ -130,7 +211,7 @@ func deployChainContractsForChains(
}
deployGrp.Go(
func() error {
err := deployChainContracts(e, chain, ab, rmnHome)
err := deployChainContracts(e, chain, ab, rmnHome, contractParams)
if err != nil {
e.Logger.Errorw("Failed to deploy chain contracts", "chain", chainSel, "err", err)
return fmt.Errorf("failed to deploy chain contracts for chain %d: %w", chainSel, err)
Expand All @@ -145,12 +226,7 @@ func deployChainContractsForChains(
return nil
}

func deployChainContracts(
e deployment.Environment,
chain deployment.Chain,
ab deployment.AddressBook,
rmnHome *rmn_home.RMNHome,
) error {
func deployChainContracts(e deployment.Environment, chain deployment.Chain, ab deployment.AddressBook, rmnHome *rmn_home.RMNHome, contractParams ContractParams) error {
// check for existing contracts
state, err := LoadOnchainState(e)
if err != nil {
Expand Down Expand Up @@ -290,21 +366,21 @@ func deployChainContracts(
chain.DeployerKey,
chain.Client,
fee_quoter.FeeQuoterStaticConfig{
MaxFeeJuelsPerMsg: big.NewInt(0).Mul(big.NewInt(2e2), big.NewInt(1e18)),
MaxFeeJuelsPerMsg: contractParams.FeeQuoterParams.MaxFeeJuelsPerMsg,
LinkToken: linkTokenContractAddr,
TokenPriceStalenessThreshold: uint32(24 * 60 * 60),
TokenPriceStalenessThreshold: contractParams.FeeQuoterParams.TokenPriceStalenessThreshold,
},
[]common.Address{state.Chains[chain.Selector].Timelock.Address()}, // timelock should be able to update, ramps added after
[]common.Address{weth9Contract.Address(), linkTokenContractAddr}, // fee tokens
[]fee_quoter.FeeQuoterTokenPriceFeedUpdate{},
[]fee_quoter.FeeQuoterTokenTransferFeeConfigArgs{}, // TODO: tokens
[]fee_quoter.FeeQuoterPremiumMultiplierWeiPerEthArgs{
{
PremiumMultiplierWeiPerEth: 9e17, // 0.9 ETH
PremiumMultiplierWeiPerEth: contractParams.FeeQuoterParams.LinkPremiumMultiplierWeiPerEth,
Token: linkTokenContractAddr,
},
{
PremiumMultiplierWeiPerEth: 1e18,
PremiumMultiplierWeiPerEth: contractParams.FeeQuoterParams.WethPremiumMultiplierWeiPerEth,
Token: weth9Contract.Address(),
},
},
Expand Down Expand Up @@ -362,15 +438,15 @@ func deployChainContracts(
chain.Client,
offramp.OffRampStaticConfig{
ChainSelector: chain.Selector,
GasForCallExactCheck: 5_000,
GasForCallExactCheck: contractParams.OffRampParams.GasForCallExactCheck,
RmnRemote: RMNProxy.Address(),
NonceManager: nmContract.Address(),
TokenAdminRegistry: tokenAdminReg.Address(),
},
offramp.OffRampDynamicConfig{
FeeQuoter: feeQuoterContract.Address(),
PermissionLessExecutionThresholdSeconds: uint32(86400),
IsRMNVerificationDisabled: true,
PermissionLessExecutionThresholdSeconds: contractParams.OffRampParams.PermissionLessExecutionThresholdSeconds,
IsRMNVerificationDisabled: contractParams.OffRampParams.IsRMNVerificationDisabled,
},
[]offramp.OffRampSourceChainConfigArgs{},
)
Expand Down
9 changes: 7 additions & 2 deletions deployment/ccip/changeset/cs_deploy_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ func TestDeployChainContractsChangeset(t *testing.T) {
require.NoError(t, err)
p2pIds := nodes.NonBootstraps().PeerIDs()
cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
contractParams := make(map[uint64]changeset.ContractParams)
for _, chain := range e.AllChainSelectors() {
cfg[chain] = proposalutils.SingleGroupTimelockConfig(t)
contractParams[chain] = changeset.ContractParams{
FeeQuoterParams: changeset.DefaultFeeQuoterParams(),
OffRampParams: changeset.DefaultOffRampParams(),
}
}
prereqCfg := make([]changeset.DeployPrerequisiteConfigPerChain, 0)
for _, chain := range e.AllChainSelectors() {
Expand Down Expand Up @@ -71,8 +76,8 @@ func TestDeployChainContractsChangeset(t *testing.T) {
{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContractsChangeset),
Config: changeset.DeployChainContractsConfig{
ChainSelectors: selectors,
HomeChainSelector: homeChainSel,
HomeChainSelector: homeChainSel,
ContractParamsPerChain: contractParams,
},
},
})
Expand Down
9 changes: 7 additions & 2 deletions deployment/ccip/changeset/cs_update_rmn_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,16 @@ func TestSetRMNRemoteOnRMNProxy(t *testing.T) {
contractsByChain[chain] = []common.Address{rmnProxy.Address()}
}
timelockContractsPerChain := make(map[uint64]*proposalutils.TimelockExecutionContracts)
allContractParams := make(map[uint64]changeset.ContractParams)
for _, chain := range allChains {
timelockContractsPerChain[chain] = &proposalutils.TimelockExecutionContracts{
Timelock: state.Chains[chain].Timelock,
CallProxy: state.Chains[chain].CallProxy,
}
allContractParams[chain] = changeset.ContractParams{
FeeQuoterParams: changeset.DefaultFeeQuoterParams(),
OffRampParams: changeset.DefaultOffRampParams(),
}
}
envNodes, err := deployment.NodeInfo(e.Env.NodeIDs, e.Env.Offchain)
require.NoError(t, err)
Expand Down Expand Up @@ -294,8 +299,8 @@ func TestSetRMNRemoteOnRMNProxy(t *testing.T) {
{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContractsChangeset),
Config: changeset.DeployChainContractsConfig{
ChainSelectors: allChains,
HomeChainSelector: e.HomeChainSel,
HomeChainSelector: e.HomeChainSel,
ContractParamsPerChain: allContractParams,
},
},
{
Expand Down
4 changes: 0 additions & 4 deletions deployment/ccip/changeset/internal/deploy_home_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ const (
MaxDurationObservation = 5 * time.Second
MaxDurationShouldAcceptAttestedReport = 10 * time.Second
MaxDurationShouldTransmitAcceptedReport = 10 * time.Second

GasPriceDeviationPPB = 1000
DAGasPriceDeviationPPB = 0
OptimisticConfirmations = 1
)

var (
Expand Down
22 changes: 16 additions & 6 deletions deployment/ccip/changeset/testhelpers/test_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext"

"github.com/smartcontractkit/chainlink/deployment/ccip/changeset"
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"

"github.com/smartcontractkit/chainlink/deployment"
Expand All @@ -37,6 +36,10 @@ const (
Memory EnvType = "in-memory"
Docker EnvType = "docker"
ENVTESTTYPE = "CCIP_V16_TEST_ENV"

GasPriceDeviationPPB = 1000
DAGasPriceDeviationPPB = 0
OptimisticConfirmations = 1
)

type TestConfigs struct {
Expand Down Expand Up @@ -496,11 +499,18 @@ func AddCCIPContractsToEnvironment(t *testing.T, allChains []uint64, tEnv TestEn
},
})
}
allContractParams := make(map[uint64]changeset.ContractParams)
for _, chain := range allChains {
allContractParams[chain] = changeset.ContractParams{
FeeQuoterParams: changeset.DefaultFeeQuoterParams(),
OffRampParams: changeset.DefaultOffRampParams(),
}
}
apps = append(apps, commonchangeset.ChangesetApplication{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContractsChangeset),
Config: changeset.DeployChainContractsConfig{
ChainSelectors: allChains,
HomeChainSelector: e.HomeChainSel,
HomeChainSelector: e.HomeChainSel,
ContractParamsPerChain: allContractParams,
},
})
e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, apps)
Expand Down Expand Up @@ -567,9 +577,9 @@ func AddCCIPContractsToEnvironment(t *testing.T, allChains []uint64, tEnv TestEn
Readers: nodeInfo.NonBootstraps().PeerIDs(),
FChain: uint8(len(nodeInfo.NonBootstraps().PeerIDs()) / 3),
EncodableChainConfig: chainconfig.ChainConfig{
GasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(internal.GasPriceDeviationPPB)},
DAGasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(internal.DAGasPriceDeviationPPB)},
OptimisticConfirmations: internal.OptimisticConfirmations,
GasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(GasPriceDeviationPPB)},
DAGasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(DAGasPriceDeviationPPB)},
OptimisticConfirmations: OptimisticConfirmations,
},
}
}
Expand Down
9 changes: 7 additions & 2 deletions deployment/environment/crib/ccip_deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
if err != nil {
return DeployCCIPOutput{}, fmt.Errorf("failed to get node info from env: %w", err)
}
contractParams := make(map[uint64]changeset.ContractParams)
for _, chain := range chainSelectors {
chainConfigs[chain] = changeset.ChainConfig{
Readers: nodeInfo.NonBootstraps().PeerIDs(),
Expand All @@ -113,6 +114,10 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
OptimisticConfirmations: 1,
},
}
contractParams[chain] = changeset.ContractParams{
FeeQuoterParams: changeset.DefaultFeeQuoterParams(),
OffRampParams: changeset.DefaultOffRampParams(),
}
}

// Setup because we only need to deploy the contracts and distribute job specs
Expand Down Expand Up @@ -141,8 +146,8 @@ func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig de
{
Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContractsChangeset),
Config: changeset.DeployChainContractsConfig{
ChainSelectors: chainSelectors,
HomeChainSelector: homeChainSel,
HomeChainSelector: homeChainSel,
ContractParamsPerChain: contractParams,
},
},
{
Expand Down
Loading