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-5024 setDynamicConfig on offRamp #16158

Merged
merged 24 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ded3f4c
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 7, 2024
10314c8
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 10, 2024
5f14bf0
remove deployCCIPContracts
AnieeG Dec 10, 2024
75c676f
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 10, 2024
b31ec5a
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 10, 2024
5f6d2d5
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 13, 2024
65616ff
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 13, 2024
6dd9c4a
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 13, 2024
813cc6e
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 18, 2024
a299e7c
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Dec 19, 2024
1837b21
deprecate existing add lane
AnieeG Dec 20, 2024
bda53fc
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 3, 2025
e171316
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 6, 2025
52422ba
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 9, 2025
56b0ff1
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 10, 2025
e261d27
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 14, 2025
35d936e
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 15, 2025
1c1c31a
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 17, 2025
637f6a2
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 23, 2025
a290364
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 27, 2025
8722ae8
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 29, 2025
8e54c04
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 29, 2025
6f28a90
Merge branch 'develop' of github.com:smartcontractkit/chainlink into …
AnieeG Jan 30, 2025
4780717
add setDynamicConfig on offRamp
AnieeG Jan 30, 2025
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
130 changes: 123 additions & 7 deletions deployment/ccip/changeset/cs_chain_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ import (
)

var (
_ deployment.ChangeSet[UpdateOnRampDestsConfig] = UpdateOnRampsDestsChangeset
_ deployment.ChangeSet[UpdateOffRampSourcesConfig] = UpdateOffRampSourcesChangeset
_ deployment.ChangeSet[UpdateRouterRampsConfig] = UpdateRouterRampsChangeset
_ deployment.ChangeSet[UpdateFeeQuoterDestsConfig] = UpdateFeeQuoterDestsChangeset
_ deployment.ChangeSet[SetOCR3OffRampConfig] = SetOCR3OffRampChangeset
_ deployment.ChangeSet[UpdateFeeQuoterPricesConfig] = UpdateFeeQuoterPricesChangeset
_ deployment.ChangeSet[UpdateNonceManagerConfig] = UpdateNonceManagersChangeset
_ deployment.ChangeSet[UpdateOnRampDestsConfig] = UpdateOnRampsDestsChangeset
_ deployment.ChangeSet[UpdateOffRampSourcesConfig] = UpdateOffRampSourcesChangeset
_ deployment.ChangeSet[UpdateRouterRampsConfig] = UpdateRouterRampsChangeset
_ deployment.ChangeSet[UpdateFeeQuoterDestsConfig] = UpdateFeeQuoterDestsChangeset
_ deployment.ChangeSet[SetOCR3OffRampConfig] = SetOCR3OffRampChangeset
_ deployment.ChangeSet[UpdateDynamicConfigOffRampConfig] = UpdateDynamicConfigOffRampChangeset
_ deployment.ChangeSet[UpdateFeeQuoterPricesConfig] = UpdateFeeQuoterPricesChangeset
_ deployment.ChangeSet[UpdateNonceManagerConfig] = UpdateNonceManagersChangeset
)

type UpdateNonceManagerConfig struct {
Expand Down Expand Up @@ -1082,6 +1083,121 @@ func SetOCR3OffRampChangeset(e deployment.Environment, cfg SetOCR3OffRampConfig)
}}, nil
}

type UpdateDynamicConfigOffRampConfig struct {
Updates map[uint64]OffRampParams
MCMS *MCMSConfig
}

func (cfg UpdateDynamicConfigOffRampConfig) Validate(e deployment.Environment) error {
state, err := LoadOnchainState(e)
if err != nil {
return err
}
for chainSel, params := range cfg.Updates {
if deployment.IsValidChainSelector(chainSel) != nil {
return fmt.Errorf("invalid chain selector %d", chainSel)
}
if _, ok := state.Chains[chainSel]; !ok {
return fmt.Errorf("chain %d not found in onchain state", chainSel)
}
if state.Chains[chainSel].OffRamp == nil {
return fmt.Errorf("missing offramp for chain %d", chainSel)
}
if state.Chains[chainSel].FeeQuoter == nil {
return fmt.Errorf("missing fee quoter for chain %d", chainSel)
}
if state.Chains[chainSel].Timelock == nil {
return fmt.Errorf("missing timelock for chain %d", chainSel)
}
if params.GasForCallExactCheck > 0 {
e.Logger.Infow(
"GasForCallExactCheck is set, please note it's a static config and will be ignored for this changeset",
"chain", chainSel, "gas", params.GasForCallExactCheck)
}
if err := commoncs.ValidateOwnership(
e.GetContext(),
cfg.MCMS != nil,
e.Chains[chainSel].DeployerKey.From,
state.Chains[chainSel].Timelock.Address(),
state.Chains[chainSel].OffRamp,
); err != nil {
return err
}
if err := params.Validate(true); err != nil {
return fmt.Errorf("chain %d: %w", chainSel, err)
}
}
return nil
}

func UpdateDynamicConfigOffRampChangeset(e deployment.Environment, cfg UpdateDynamicConfigOffRampConfig) (deployment.ChangesetOutput, error) {
if err := cfg.Validate(e); err != nil {
return deployment.ChangesetOutput{}, err
}
state, err := LoadOnchainState(e)
if err != nil {
return deployment.ChangesetOutput{}, err
}
var batches []timelock.BatchChainOperation
timelocks := make(map[uint64]common.Address)
proposers := make(map[uint64]*gethwrappers.ManyChainMultiSig)
for chainSel, params := range cfg.Updates {
chain := e.Chains[chainSel]
txOpts := e.Chains[chainSel].DeployerKey
if cfg.MCMS != nil {
txOpts = deployment.SimTransactOpts()
}
offRamp := state.Chains[chainSel].OffRamp
dCfg := offramp.OffRampDynamicConfig{
FeeQuoter: state.Chains[chainSel].FeeQuoter.Address(),
PermissionLessExecutionThresholdSeconds: params.PermissionLessExecutionThresholdSeconds,
IsRMNVerificationDisabled: params.IsRMNVerificationDisabled,
MessageInterceptor: params.MessageInterceptor,
}
tx, err := offRamp.SetDynamicConfig(txOpts, dCfg)
if err != nil {
return deployment.ChangesetOutput{}, err
}
if cfg.MCMS == nil {
if _, err := deployment.ConfirmIfNoError(e.Chains[chainSel], tx, err); err != nil {
return deployment.ChangesetOutput{}, deployment.DecodedErrFromABIIfDataErr(err, offramp.OffRampABI)
}
e.Logger.Infow("Updated offramp dynamic config", "chain", chain.String(), "config", dCfg)
} else {
batches = append(batches, timelock.BatchChainOperation{
ChainIdentifier: mcms.ChainIdentifier(chainSel),
Batch: []mcms.Operation{
{
To: offRamp.Address(),
Data: tx.Data(),
Value: big.NewInt(0),
},
},
})
timelocks[chainSel] = state.Chains[chainSel].Timelock.Address()
proposers[chainSel] = state.Chains[chainSel].ProposerMcm
}
}
if cfg.MCMS == nil {
return deployment.ChangesetOutput{}, nil
}
p, err := proposalutils.BuildProposalFromBatches(
timelocks,
proposers,
batches,
"Update offramp dynamic config",
cfg.MCMS.MinDelay,
)

if err != nil {
return deployment.ChangesetOutput{}, err
}
e.Logger.Infow("Proposing offramp dynamic config update", "config", cfg.Updates)
return deployment.ChangesetOutput{Proposals: []timelock.MCMSWithTimelockProposal{
*p,
}}, nil
}

func isOCR3ConfigSetOnOffRamp(
lggr logger.Logger,
chain deployment.Chain,
Expand Down
63 changes: 63 additions & 0 deletions deployment/ccip/changeset/cs_chain_contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset/testhelpers"
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter"
"github.com/smartcontractkit/chainlink/v2/evm/utils"
)

func TestUpdateOnRampsDests(t *testing.T) {
Expand Down Expand Up @@ -307,6 +308,68 @@ func TestUpdateRouterRamps(t *testing.T) {
}
}

func TestUpdateDynamicConfigOffRampChangeset(t *testing.T) {
for _, tc := range []struct {
name string
mcmsEnabled bool
}{
{
name: "MCMS enabled",
mcmsEnabled: true,
},
{
name: "MCMS disabled",
mcmsEnabled: false,
},
} {
t.Run(tc.name, func(t *testing.T) {
tenv, _ := testhelpers.NewMemoryEnvironment(t)
state, err := changeset.LoadOnchainState(tenv.Env)
require.NoError(t, err)

allChains := maps.Keys(tenv.Env.Chains)
source := allChains[0]
dest := allChains[1]

if tc.mcmsEnabled {
// Transfer ownership to timelock so that we can promote the zero digest later down the line.
transferToTimelock(t, tenv, state, source, dest)
}

var mcmsConfig *changeset.MCMSConfig
if tc.mcmsEnabled {
mcmsConfig = &changeset.MCMSConfig{
MinDelay: 0,
}
}
msgInterceptor := utils.RandomAddress()
_, err = commonchangeset.ApplyChangesets(t, tenv.Env, tenv.TimelockContracts(t), []commonchangeset.ChangesetApplication{
{
Changeset: commonchangeset.WrapChangeSet(changeset.UpdateDynamicConfigOffRampChangeset),
Config: changeset.UpdateDynamicConfigOffRampConfig{
Updates: map[uint64]changeset.OffRampParams{
source: {
PermissionLessExecutionThresholdSeconds: uint32(2 * 60 * 60),
IsRMNVerificationDisabled: false,
MessageInterceptor: msgInterceptor,
},
},
MCMS: mcmsConfig,
},
},
})
require.NoError(t, err)
// Assert the nonce manager configuration is as we expect.
actualConfig, err := state.Chains[source].OffRamp.GetDynamicConfig(nil)
require.NoError(t, err)
require.Equal(t, uint32(2*60*60), actualConfig.PermissionLessExecutionThresholdSeconds)
require.False(t, actualConfig.IsRMNVerificationDisabled)
require.Equal(t, msgInterceptor, actualConfig.MessageInterceptor)
require.Equal(t, state.Chains[source].FeeQuoter.Address(), actualConfig.FeeQuoter)
})
}
}

func TestUpdateNonceManagersCS(t *testing.T) {
for _, tc := range []struct {
name string
Expand Down
8 changes: 5 additions & 3 deletions deployment/ccip/changeset/cs_deploy_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (c ChainContractParams) Validate() error {
if err := c.FeeQuoterParams.Validate(); err != nil {
return fmt.Errorf("invalid FeeQuoterParams: %w", err)
}
if err := c.OffRampParams.Validate(); err != nil {
if err := c.OffRampParams.Validate(false); err != nil {
return fmt.Errorf("invalid OffRampParams: %w", err)
}
return nil
Expand Down Expand Up @@ -145,10 +145,11 @@ type OffRampParams struct {
GasForCallExactCheck uint16
PermissionLessExecutionThresholdSeconds uint32
IsRMNVerificationDisabled bool
MessageInterceptor common.Address
}

func (c OffRampParams) Validate() error {
if c.GasForCallExactCheck == 0 {
func (c OffRampParams) Validate(ignoreGasForCallExactCheck bool) error {
if !ignoreGasForCallExactCheck && c.GasForCallExactCheck == 0 {
return errors.New("GasForCallExactCheck is 0")
}
if c.PermissionLessExecutionThresholdSeconds == 0 {
Expand Down Expand Up @@ -496,6 +497,7 @@ func deployChainContractsEVM(e deployment.Environment, chain deployment.Chain, a
FeeQuoter: feeQuoterContract.Address(),
PermissionLessExecutionThresholdSeconds: contractParams.OffRampParams.PermissionLessExecutionThresholdSeconds,
IsRMNVerificationDisabled: contractParams.OffRampParams.IsRMNVerificationDisabled,
MessageInterceptor: contractParams.OffRampParams.MessageInterceptor,
},
[]offramp.OffRampSourceChainConfigArgs{},
)
Expand Down
Loading