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  }