|
| 1 | +package aptos |
| 2 | + |
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "fmt" |
| 6 | + |
| 7 | + "github.com/aptos-labs/aptos-go-sdk" |
| 8 | + "github.com/smartcontractkit/mcms" |
| 9 | + "github.com/smartcontractkit/mcms/types" |
| 10 | + |
| 11 | + cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" |
| 12 | + "github.com/smartcontractkit/chainlink-deployments-framework/operations" |
| 13 | + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/aptos/config" |
| 14 | + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/aptos/dependency" |
| 15 | + seq "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/aptos/sequence" |
| 16 | + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/aptos/utils" |
| 17 | + "github.com/smartcontractkit/chainlink/deployment/ccip/shared/stateview" |
| 18 | +) |
| 19 | + |
| 20 | +var _ cldf.ChangeSetV2[config.UpgradeAptosChainConfig] = UpgradeAptosChain{} |
| 21 | + |
| 22 | +// UpgradeAptosChain upgrades Aptos chain packages and modules |
| 23 | +type UpgradeAptosChain struct{} |
| 24 | + |
| 25 | +func (cs UpgradeAptosChain) VerifyPreconditions(env cldf.Environment, cfg config.UpgradeAptosChainConfig) error { |
| 26 | + var errs []error |
| 27 | + if !cfg.UpgradeCCIP && !cfg.UpgradeOffRamp && !cfg.UpgradeOnRamp && !cfg.UpgradeRouter { |
| 28 | + errs = append(errs, errors.New("no upgrades selected")) |
| 29 | + } |
| 30 | + state, err := stateview.LoadOnchainState(env) |
| 31 | + if err != nil { |
| 32 | + errs = append(errs, fmt.Errorf("failed to load Aptos onchain state: %w", err)) |
| 33 | + } |
| 34 | + // Validate supported chain |
| 35 | + supportedChains := state.SupportedChains() |
| 36 | + if _, ok := supportedChains[cfg.ChainSelector]; !ok { |
| 37 | + errs = append(errs, fmt.Errorf("unsupported chain: %d", cfg.ChainSelector)) |
| 38 | + } |
| 39 | + // Validate MCMS config |
| 40 | + if cfg.MCMS == nil { |
| 41 | + errs = append(errs, errors.New("MCMS config is required for UpgradeAptosChain changeset")) |
| 42 | + } |
| 43 | + // Check CCIP Package |
| 44 | + ccipAddress := state.AptosChains[cfg.ChainSelector].CCIPAddress |
| 45 | + client := env.BlockChains.AptosChains()[cfg.ChainSelector].Client |
| 46 | + if ccipAddress == (aptos.AccountAddress{}) { |
| 47 | + errs = append(errs, fmt.Errorf("package CCIP is not deployed on Aptos chain %d", cfg.ChainSelector)) |
| 48 | + } |
| 49 | + // Check OnRamp module |
| 50 | + hasOnramp, err := utils.IsModuleDeployed(client, ccipAddress, "onramp") |
| 51 | + if err != nil || !hasOnramp { |
| 52 | + errs = append(errs, fmt.Errorf("onRamp module is not deployed on Aptos chain %d: %w", cfg.ChainSelector, err)) |
| 53 | + } |
| 54 | + // Check OffRamp module |
| 55 | + hasOfframp, err := utils.IsModuleDeployed(client, ccipAddress, "offramp") |
| 56 | + if err != nil || !hasOfframp { |
| 57 | + errs = append(errs, fmt.Errorf("offRamp module is not deployed on Aptos chain %d: %w", cfg.ChainSelector, err)) |
| 58 | + } |
| 59 | + // Check Router module |
| 60 | + hasRouter, err := utils.IsModuleDeployed(client, ccipAddress, "router") |
| 61 | + if err != nil || !hasRouter { |
| 62 | + errs = append(errs, fmt.Errorf("router module is not deployed on Aptos chain %d: %w", cfg.ChainSelector, err)) |
| 63 | + } |
| 64 | + |
| 65 | + return errors.Join(errs...) |
| 66 | +} |
| 67 | + |
| 68 | +func (cs UpgradeAptosChain) Apply(env cldf.Environment, cfg config.UpgradeAptosChainConfig) (cldf.ChangesetOutput, error) { |
| 69 | + timeLockProposals := []mcms.TimelockProposal{} |
| 70 | + mcmsOperations := []types.BatchOperation{} |
| 71 | + seqReports := make([]operations.Report[any, any], 0) |
| 72 | + |
| 73 | + state, err := stateview.LoadOnchainState(env) |
| 74 | + if err != nil { |
| 75 | + return cldf.ChangesetOutput{}, fmt.Errorf("failed to load Aptos onchain state: %w", err) |
| 76 | + } |
| 77 | + |
| 78 | + deps := dependency.AptosDeps{ |
| 79 | + AptosChain: env.BlockChains.AptosChains()[cfg.ChainSelector], |
| 80 | + CCIPOnChainState: state, |
| 81 | + } |
| 82 | + |
| 83 | + // Execute the sequence |
| 84 | + upgradeSeqReport, err := operations.ExecuteSequence(env.OperationsBundle, seq.UpgradeCCIPSequence, deps, cfg) |
| 85 | + if err != nil { |
| 86 | + return cldf.ChangesetOutput{}, err |
| 87 | + } |
| 88 | + seqReports = append(seqReports, upgradeSeqReport.ExecutionReports...) |
| 89 | + mcmsOperations = append(mcmsOperations, upgradeSeqReport.Output...) |
| 90 | + |
| 91 | + // Generate MCMS proposals |
| 92 | + proposal, err := utils.GenerateProposal( |
| 93 | + env, |
| 94 | + state.AptosChains[cfg.ChainSelector].MCMSAddress, |
| 95 | + cfg.ChainSelector, |
| 96 | + mcmsOperations, |
| 97 | + "Upgrade chain contracts on Aptos chain", |
| 98 | + *cfg.MCMS, |
| 99 | + ) |
| 100 | + if err != nil { |
| 101 | + return cldf.ChangesetOutput{}, fmt.Errorf("failed to generate MCMS proposal for Aptos chain %d: %w", cfg.ChainSelector, err) |
| 102 | + } |
| 103 | + timeLockProposals = append(timeLockProposals, *proposal) |
| 104 | + |
| 105 | + return cldf.ChangesetOutput{ |
| 106 | + MCMSTimelockProposals: timeLockProposals, |
| 107 | + Reports: seqReports, |
| 108 | + }, nil |
| 109 | +} |
0 commit comments