github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/txs/transform_subnet_tx.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package txs 5 6 import ( 7 "errors" 8 "fmt" 9 10 "github.com/MetalBlockchain/metalgo/ids" 11 "github.com/MetalBlockchain/metalgo/snow" 12 "github.com/MetalBlockchain/metalgo/utils/constants" 13 "github.com/MetalBlockchain/metalgo/vms/components/verify" 14 "github.com/MetalBlockchain/metalgo/vms/platformvm/reward" 15 ) 16 17 var ( 18 _ UnsignedTx = (*TransformSubnetTx)(nil) 19 20 errCantTransformPrimaryNetwork = errors.New("cannot transform primary network") 21 errEmptyAssetID = errors.New("empty asset ID is not valid") 22 errAssetIDCantBeAVAX = errors.New("asset ID can't be AVAX") 23 errInitialSupplyZero = errors.New("initial supply must be non-0") 24 errInitialSupplyGreaterThanMaxSupply = errors.New("initial supply can't be greater than maximum supply") 25 errMinConsumptionRateTooLarge = errors.New("min consumption rate must be less than or equal to max consumption rate") 26 errMaxConsumptionRateTooLarge = fmt.Errorf("max consumption rate must be less than or equal to %d", reward.PercentDenominator) 27 errMinValidatorStakeZero = errors.New("min validator stake must be non-0") 28 errMinValidatorStakeAboveSupply = errors.New("min validator stake must be less than or equal to initial supply") 29 errMinValidatorStakeAboveMax = errors.New("min validator stake must be less than or equal to max validator stake") 30 errMaxValidatorStakeTooLarge = errors.New("max validator stake must be less than or equal to max supply") 31 errMinStakeDurationZero = errors.New("min stake duration must be non-0") 32 errMinStakeDurationTooLarge = errors.New("min stake duration must be less than or equal to max stake duration") 33 errMinDelegationFeeTooLarge = fmt.Errorf("min delegation fee must be less than or equal to %d", reward.PercentDenominator) 34 errMinDelegatorStakeZero = errors.New("min delegator stake must be non-0") 35 errMaxValidatorWeightFactorZero = errors.New("max validator weight factor must be non-0") 36 errUptimeRequirementTooLarge = fmt.Errorf("uptime requirement must be less than or equal to %d", reward.PercentDenominator) 37 ) 38 39 // TransformSubnetTx is an unsigned transformSubnetTx 40 type TransformSubnetTx struct { 41 // Metadata, inputs and outputs 42 BaseTx `serialize:"true"` 43 // ID of the Subnet to transform 44 // Restrictions: 45 // - Must not be the Primary Network ID 46 Subnet ids.ID `serialize:"true" json:"subnetID"` 47 // Asset to use when staking on the Subnet 48 // Restrictions: 49 // - Must not be the Empty ID 50 // - Must not be the AVAX ID 51 AssetID ids.ID `serialize:"true" json:"assetID"` 52 // Amount to initially specify as the current supply 53 // Restrictions: 54 // - Must be > 0 55 InitialSupply uint64 `serialize:"true" json:"initialSupply"` 56 // Amount to specify as the maximum token supply 57 // Restrictions: 58 // - Must be >= [InitialSupply] 59 MaximumSupply uint64 `serialize:"true" json:"maximumSupply"` 60 // MinConsumptionRate is the rate to allocate funds if the validator's stake 61 // duration is 0 62 MinConsumptionRate uint64 `serialize:"true" json:"minConsumptionRate"` 63 // MaxConsumptionRate is the rate to allocate funds if the validator's stake 64 // duration is equal to the minting period 65 // Restrictions: 66 // - Must be >= [MinConsumptionRate] 67 // - Must be <= [reward.PercentDenominator] 68 MaxConsumptionRate uint64 `serialize:"true" json:"maxConsumptionRate"` 69 // MinValidatorStake is the minimum amount of funds required to become a 70 // validator. 71 // Restrictions: 72 // - Must be > 0 73 // - Must be <= [InitialSupply] 74 MinValidatorStake uint64 `serialize:"true" json:"minValidatorStake"` 75 // MaxValidatorStake is the maximum amount of funds a single validator can 76 // be allocated, including delegated funds. 77 // Restrictions: 78 // - Must be >= [MinValidatorStake] 79 // - Must be <= [MaximumSupply] 80 MaxValidatorStake uint64 `serialize:"true" json:"maxValidatorStake"` 81 // MinStakeDuration is the minimum number of seconds a staker can stake for. 82 // Restrictions: 83 // - Must be > 0 84 MinStakeDuration uint32 `serialize:"true" json:"minStakeDuration"` 85 // MaxStakeDuration is the maximum number of seconds a staker can stake for. 86 // Restrictions: 87 // - Must be >= [MinStakeDuration] 88 // - Must be <= [GlobalMaxStakeDuration] 89 MaxStakeDuration uint32 `serialize:"true" json:"maxStakeDuration"` 90 // MinDelegationFee is the minimum percentage a validator must charge a 91 // delegator for delegating. 92 // Restrictions: 93 // - Must be <= [reward.PercentDenominator] 94 MinDelegationFee uint32 `serialize:"true" json:"minDelegationFee"` 95 // MinDelegatorStake is the minimum amount of funds required to become a 96 // delegator. 97 // Restrictions: 98 // - Must be > 0 99 MinDelegatorStake uint64 `serialize:"true" json:"minDelegatorStake"` 100 // MaxValidatorWeightFactor is the factor which calculates the maximum 101 // amount of delegation a validator can receive. 102 // Note: a value of 1 effectively disables delegation. 103 // Restrictions: 104 // - Must be > 0 105 MaxValidatorWeightFactor byte `serialize:"true" json:"maxValidatorWeightFactor"` 106 // UptimeRequirement is the minimum percentage a validator must be online 107 // and responsive to receive a reward. 108 // Restrictions: 109 // - Must be <= [reward.PercentDenominator] 110 UptimeRequirement uint32 `serialize:"true" json:"uptimeRequirement"` 111 // Authorizes this transformation 112 SubnetAuth verify.Verifiable `serialize:"true" json:"subnetAuthorization"` 113 } 114 115 func (tx *TransformSubnetTx) SyntacticVerify(ctx *snow.Context) error { 116 switch { 117 case tx == nil: 118 return ErrNilTx 119 case tx.SyntacticallyVerified: // already passed syntactic verification 120 return nil 121 case tx.Subnet == constants.PrimaryNetworkID: 122 return errCantTransformPrimaryNetwork 123 case tx.AssetID == ids.Empty: 124 return errEmptyAssetID 125 case tx.AssetID == ctx.AVAXAssetID: 126 return errAssetIDCantBeAVAX 127 case tx.InitialSupply == 0: 128 return errInitialSupplyZero 129 case tx.InitialSupply > tx.MaximumSupply: 130 return errInitialSupplyGreaterThanMaxSupply 131 case tx.MinConsumptionRate > tx.MaxConsumptionRate: 132 return errMinConsumptionRateTooLarge 133 case tx.MaxConsumptionRate > reward.PercentDenominator: 134 return errMaxConsumptionRateTooLarge 135 case tx.MinValidatorStake == 0: 136 return errMinValidatorStakeZero 137 case tx.MinValidatorStake > tx.InitialSupply: 138 return errMinValidatorStakeAboveSupply 139 case tx.MinValidatorStake > tx.MaxValidatorStake: 140 return errMinValidatorStakeAboveMax 141 case tx.MaxValidatorStake > tx.MaximumSupply: 142 return errMaxValidatorStakeTooLarge 143 case tx.MinStakeDuration == 0: 144 return errMinStakeDurationZero 145 case tx.MinStakeDuration > tx.MaxStakeDuration: 146 return errMinStakeDurationTooLarge 147 case tx.MinDelegationFee > reward.PercentDenominator: 148 return errMinDelegationFeeTooLarge 149 case tx.MinDelegatorStake == 0: 150 return errMinDelegatorStakeZero 151 case tx.MaxValidatorWeightFactor == 0: 152 return errMaxValidatorWeightFactorZero 153 case tx.UptimeRequirement > reward.PercentDenominator: 154 return errUptimeRequirementTooLarge 155 } 156 157 if err := tx.BaseTx.SyntacticVerify(ctx); err != nil { 158 return err 159 } 160 if err := tx.SubnetAuth.Verify(); err != nil { 161 return err 162 } 163 164 tx.SyntacticallyVerified = true 165 return nil 166 } 167 168 func (tx *TransformSubnetTx) Visit(visitor Visitor) error { 169 return visitor.TransformSubnetTx(tx) 170 }