diff --git a/deployment/ccip/changeset/cs_orchestrate_changesets.go b/deployment/ccip/changeset/cs_orchestrate_changesets.go index 9cf6e8fb089..c6d90b7ca74 100644 --- a/deployment/ccip/changeset/cs_orchestrate_changesets.go +++ b/deployment/ccip/changeset/cs_orchestrate_changesets.go @@ -139,6 +139,11 @@ func orchestrateChangesetsLogic(e cldf.Environment, c OrchestrateChangesetsConfi return cldf.ChangesetOutput{}, fmt.Errorf("failed to get EVM MCMS state by chain: %w", err) } + tonMCMSState, err := state.TONMCMSStateByChain(e) + if err != nil { + return cldf.ChangesetOutput{}, fmt.Errorf("failed to get TON MCMS state by chain: %w", err) + } + // Aggregate all Timelock proposals into 1 proposal proposal, err := proposalutils.AggregateProposalsV2( e, @@ -146,6 +151,7 @@ func orchestrateChangesetsLogic(e cldf.Environment, c OrchestrateChangesetsConfi MCMSEVMState: evmMCMSState, MCMSSolanaState: state.SolanaMCMSStateByChain(e), MCMSAptosState: state.AptosMCMSStateByChain(), + MCMSTONState: tonMCMSState, }, finalOutput.MCMSTimelockProposals, c.Description, diff --git a/deployment/ccip/shared/stateview/state.go b/deployment/ccip/shared/stateview/state.go index 7de1bfdd8f6..0bd0554a3d5 100644 --- a/deployment/ccip/shared/stateview/state.go +++ b/deployment/ccip/shared/stateview/state.go @@ -416,6 +416,10 @@ func (c CCIPOnChainState) AptosMCMSStateByChain() map[uint64]aptos.AccountAddres return mcmsByChain } +func (c CCIPOnChainState) TONMCMSStateByChain(e cldf.Environment) (map[uint64]tonstate.MCMSChainState, error) { + return tonstate.LoadMCMSOnChainState(e) +} + func (c CCIPOnChainState) OffRampPermissionLessExecutionThresholdSeconds(ctx context.Context, env cldf.Environment, selector uint64) (uint32, error) { family, err := chain_selectors.GetSelectorFamily(selector) if err != nil { diff --git a/deployment/common/proposalutils/propose.go b/deployment/common/proposalutils/propose.go index 6f6385b17a9..6a470c37abb 100644 --- a/deployment/common/proposalutils/propose.go +++ b/deployment/common/proposalutils/propose.go @@ -23,6 +23,7 @@ import ( cldf_adapters "github.com/smartcontractkit/chainlink-deployments-framework/chain/mcms/adapters" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + tonstate "github.com/smartcontractkit/chainlink-ton/deployment/state" cldfproposalutils "github.com/smartcontractkit/chainlink-deployments-framework/engine/cld/mcms/proposalutils" "github.com/smartcontractkit/chainlink/deployment/common/changeset/state" @@ -61,6 +62,32 @@ func (tc *TimelockConfig) MCMBasedOnActionSolana(s state.MCMSWithTimelockStateSo } } +func (tc *TimelockConfig) MCMBasedOnActionTON(s *tonstate.MCMSSuiteState) (string, error) { + // if MCMSAction is not set, default to timelock.Schedule, this is to ensure no breaking changes for existing code + if tc.MCMSAction == "" { + tc.MCMSAction = types.TimelockActionSchedule + } + switch tc.MCMSAction { + case types.TimelockActionSchedule: + if s.Proposer == nil { + return "", errors.New("missing TON proposer") + } + return s.Proposer.String(), nil + case types.TimelockActionCancel: + if s.Canceller == nil { + return "", errors.New("missing TON canceller") + } + return s.Canceller.String(), nil + case types.TimelockActionBypass: + if s.Bypasser == nil { + return "", errors.New("missing TON bypasser") + } + return s.Bypasser.String(), nil + default: + return "", errors.New("invalid MCMS action") + } +} + func (tc *TimelockConfig) MCMBasedOnAction(s state.MCMSWithTimelockState) (*gethwrappers.ManyChainMultiSig, error) { // if MCMSAction is not set, default to timelock.Schedule, this is to ensure no breaking changes for existing code if tc.MCMSAction == "" { @@ -431,6 +458,7 @@ type MCMSStates struct { MCMSEVMState map[uint64]state.MCMSWithTimelockState MCMSSolanaState map[uint64]state.MCMSWithTimelockStateSolana MCMSAptosState map[uint64]aptos.AccountAddress + MCMSTONState map[uint64]tonstate.MCMSChainState } // AggregateProposalsV2 aggregates multiple MCMS proposals into a single proposal by combining their operations, and @@ -518,6 +546,27 @@ func AggregateProposalsV2( } timelocks[chainSel] = aptosMCMSAddress.StringLong() mcmsPerChain[chainSel] = aptosMCMSAddress.StringLong() + case chain_selectors.FamilyTon: + tonMCMS, exists := mcmsTimelockStates.MCMSTONState[chainSel] + if !exists { + return nil, fmt.Errorf("missing MCMS state for TON chain %d", chainSel) + } + qualifier := mcmsConfig.TimelockQualifierPerChain[chainSel] + // Get the default qualifier suite (or iterate ByQualifier) + suite, ok := tonMCMS.ByQualifier[qualifier] // default qualifier? + if !ok || suite == nil { + return nil, fmt.Errorf("missing TON timelock for chain %d qualifier %q", chainSel, qualifier) + } + if suite.Timelock == nil { + return nil, fmt.Errorf("missing TON timelock address for chain %d", chainSel) + } + timelocks[chainSel] = suite.Timelock.String() + // Select MCMS address based on action + mcmsAddr, err := mcmsConfig.MCMBasedOnActionTON(suite) + if err != nil { + return nil, err + } + mcmsPerChain[chainSel] = mcmsAddr } }