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