Skip to content

Commit

Permalink
[AV-1817] Add TransformSubnetTx to lock a subnet's state (ava-labs#1627)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph authored Aug 30, 2022
1 parent bccc164 commit 59e302f
Show file tree
Hide file tree
Showing 41 changed files with 2,521 additions and 815 deletions.
3 changes: 3 additions & 0 deletions api/info/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type Parameters struct {
TxFee uint64
CreateAssetTxFee uint64
CreateSubnetTxFee uint64
TransformSubnetTxFee uint64
CreateBlockchainTxFee uint64
VMManager vms.Manager
}
Expand Down Expand Up @@ -280,6 +281,7 @@ type GetTxFeeResponse struct {
CreationTxFee json.Uint64 `json:"creationTxFee"`
CreateAssetTxFee json.Uint64 `json:"createAssetTxFee"`
CreateSubnetTxFee json.Uint64 `json:"createSubnetTxFee"`
TransformSubnetTxFee json.Uint64 `json:"transformSubnetTxFee"`
CreateBlockchainTxFee json.Uint64 `json:"createBlockchainTxFee"`
}

Expand All @@ -289,6 +291,7 @@ func (service *Info) GetTxFee(_ *http.Request, args *struct{}, reply *GetTxFeeRe
reply.CreationTxFee = json.Uint64(service.CreateAssetTxFee)
reply.CreateAssetTxFee = json.Uint64(service.CreateAssetTxFee)
reply.CreateSubnetTxFee = json.Uint64(service.CreateSubnetTxFee)
reply.TransformSubnetTxFee = json.Uint64(service.TransformSubnetTxFee)
reply.CreateBlockchainTxFee = json.Uint64(service.CreateBlockchainTxFee)
return nil
}
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig {
TxFee: v.GetUint64(TxFeeKey),
CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey),
CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey),
TransformSubnetTxFee: v.GetUint64(TransformSubnetTxFeeKey),
CreateBlockchainTxFee: v.GetUint64(CreateBlockchainTxFeeKey),
}
}
Expand Down
1 change: 1 addition & 0 deletions config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func addNodeFlags(fs *flag.FlagSet) {
fs.Uint64(TxFeeKey, genesis.LocalParams.TxFee, "Transaction fee, in nAVAX")
fs.Uint64(CreateAssetTxFeeKey, genesis.LocalParams.CreateAssetTxFee, "Transaction fee, in nAVAX, for transactions that create new assets")
fs.Uint64(CreateSubnetTxFeeKey, genesis.LocalParams.CreateSubnetTxFee, "Transaction fee, in nAVAX, for transactions that create new subnets")
fs.Uint64(TransformSubnetTxFeeKey, genesis.LocalParams.TransformSubnetTxFee, "Transaction fee, in nAVAX, for transactions that transform subnets")
fs.Uint64(CreateBlockchainTxFeeKey, genesis.LocalParams.CreateBlockchainTxFee, "Transaction fee, in nAVAX, for transactions that create new blockchains")

// Database
Expand Down
1 change: 1 addition & 0 deletions config/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
TxFeeKey = "tx-fee"
CreateAssetTxFeeKey = "create-asset-tx-fee"
CreateSubnetTxFeeKey = "create-subnet-tx-fee"
TransformSubnetTxFeeKey = "transform-subnet-tx-fee"
CreateBlockchainTxFeeKey = "create-blockchain-tx-fee"
UptimeRequirementKey = "uptime-requirement"
MinValidatorStakeKey = "min-validator-stake"
Expand Down
1 change: 1 addition & 0 deletions genesis/genesis_fuji.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var (
TxFee: units.MilliAvax,
CreateAssetTxFee: 10 * units.MilliAvax,
CreateSubnetTxFee: 100 * units.MilliAvax,
TransformSubnetTxFee: 100 * units.MilliAvax,
CreateBlockchainTxFee: 100 * units.MilliAvax,
},
StakingConfig: StakingConfig{
Expand Down
1 change: 1 addition & 0 deletions genesis/genesis_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ var (
TxFee: units.MilliAvax,
CreateAssetTxFee: units.MilliAvax,
CreateSubnetTxFee: 100 * units.MilliAvax,
TransformSubnetTxFee: 100 * units.MilliAvax,
CreateBlockchainTxFee: 100 * units.MilliAvax,
},
StakingConfig: StakingConfig{
Expand Down
1 change: 1 addition & 0 deletions genesis/genesis_mainnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var (
TxFee: units.MilliAvax,
CreateAssetTxFee: 10 * units.MilliAvax,
CreateSubnetTxFee: 1 * units.Avax,
TransformSubnetTxFee: 1 * units.Avax,
CreateBlockchainTxFee: 1 * units.Avax,
},
StakingConfig: StakingConfig{
Expand Down
2 changes: 2 additions & 0 deletions genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type TxFeeConfig struct {
CreateAssetTxFee uint64 `json:"createAssetTxFee"`
// Transaction fee for create subnet transactions
CreateSubnetTxFee uint64 `json:"createSubnetTxFee"`
// Transaction fee for transform subnet transactions
TransformSubnetTxFee uint64 `json:"transformSubnetTxFee"`
// Transaction fee for create blockchain transactions
CreateBlockchainTxFee uint64 `json:"createBlockchainTxFee"`
}
Expand Down
2 changes: 2 additions & 0 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ func (n *Node) initVMs() error {
TxFee: n.Config.TxFee,
CreateAssetTxFee: n.Config.CreateAssetTxFee,
CreateSubnetTxFee: n.Config.CreateSubnetTxFee,
TransformSubnetTxFee: n.Config.TransformSubnetTxFee,
CreateBlockchainTxFee: n.Config.CreateBlockchainTxFee,
UptimePercentage: n.Config.UptimeRequirement,
MinValidatorStake: n.Config.MinValidatorStake,
Expand Down Expand Up @@ -965,6 +966,7 @@ func (n *Node) initInfoAPI() error {
TxFee: n.Config.TxFee,
CreateAssetTxFee: n.Config.CreateAssetTxFee,
CreateSubnetTxFee: n.Config.CreateSubnetTxFee,
TransformSubnetTxFee: n.Config.TransformSubnetTxFee,
CreateBlockchainTxFee: n.Config.CreateBlockchainTxFee,
VMManager: n.Config.VMManager,
},
Expand Down
3 changes: 3 additions & 0 deletions vms/platformvm/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type Config struct {
// Fee that must be burned by every subnet creating transaction after AP3
CreateSubnetTxFee uint64

// Fee that must be burned by every transform subnet transaction
TransformSubnetTxFee uint64

// Fee that must be burned by every blockchain creating transaction after AP3
CreateBlockchainTxFee uint64

Expand Down
36 changes: 36 additions & 0 deletions vms/platformvm/docs/subnets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Subnets

The Avalanche network consists of the Primary Network and a collection of
sub-networks (subnets).

## Subnet Creation

Subnets are created by issuing a *CreateSubnetTx*. After a *CreateSubnetTx* is
accepted, a new subnet will exist with the *SubnetID* equal to the *TxID* of the
*CreateSubnetTx*. The *CreateSubnetTx* creates a permissioned subnet. The
*Owner* field in *CreateSubnetTx* specifies who can modify the state of the
subnet.

## Permissioned Subnets

A permissioned subnet can be modified by a few different transactions.

- CreateChainTx
- Creates a new chain that will be validated by all validators of the subnet.
- AddSubnetValidatorTx
- Adds a new validator to the subnet with the specified *StartTime*,
*EndTime*, and *Weight*.
- RemoveSubnetValidatorTx
- Removes a validator from the subnet.
- TransformSubnetTx
- Converts the permissioned subnet into a permissionless subnet.
- Specifies all of the staking parameters.
- AVAX is not allowed to be used as a staking token. In general, it is not
advisable to have multiple subnets using the same staking token.
- After becoming a permissionless subnet, previously added permissioned
validators will remain to finish their staking period.
- No more chains will be able to be added to the subnet.

### Permissionless Subnets

Currently, nothing can be performed on a permissionless subnet.
9 changes: 8 additions & 1 deletion vms/platformvm/metrics/tx_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ type txMetrics struct {
numExportTxs,
numImportTxs,
numRewardValidatorTxs,
numRemoveSubnetValidatorTxs prometheus.Counter
numRemoveSubnetValidatorTxs,
numTransformSubnetTxs prometheus.Counter
}

func newTxMetrics(
Expand All @@ -43,6 +44,7 @@ func newTxMetrics(
numImportTxs: newTxMetric(namespace, "import", registerer, &errs),
numRewardValidatorTxs: newTxMetric(namespace, "reward_validator", registerer, &errs),
numRemoveSubnetValidatorTxs: newTxMetric(namespace, "remove_subnet_validator", registerer, &errs),
numTransformSubnetTxs: newTxMetric(namespace, "transform_subnet", registerer, &errs),
}
return m, errs.Err
}
Expand Down Expand Up @@ -111,3 +113,8 @@ func (m *txMetrics) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error
m.numRemoveSubnetValidatorTxs.Inc()
return nil
}

func (m *txMetrics) TransformSubnetTx(*txs.TransformSubnetTx) error {
m.numTransformSubnetTxs.Inc()
return nil
}
63 changes: 61 additions & 2 deletions vms/platformvm/state/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ type diff struct {
timestamp time.Time

currentSupply uint64
// Subnet ID --> supply of native asset of the subnet
subnetSupplies map[ids.ID]uint64

currentStakerDiffs diffStakers
pendingStakerDiffs diffStakers

addedSubnets []*txs.Tx
cachedSubnets []*txs.Tx
addedSubnets []*txs.Tx
// Subnet ID --> Tx that transforms the subnet
transformedSubnets map[ids.ID]*txs.Tx
cachedSubnets []*txs.Tx

addedChains map[ids.ID][]*txs.Tx
cachedChains map[ids.ID][]*txs.Tx
Expand Down Expand Up @@ -91,6 +95,30 @@ func (d *diff) SetCurrentSupply(currentSupply uint64) {
d.currentSupply = currentSupply
}

func (d *diff) GetCurrentSubnetSupply(subnetID ids.ID) (uint64, error) {
supply, ok := d.subnetSupplies[subnetID]
if ok {
return supply, nil
}

// If the subnet supply wasn't modified in this diff, ask the parent state.
parentState, ok := d.stateVersions.GetState(d.parentID)
if !ok {
return 0, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID)
}
return parentState.GetCurrentSubnetSupply(subnetID)
}

func (d *diff) SetCurrentSubnetSupply(subnetID ids.ID, currentSupply uint64) {
if d.subnetSupplies == nil {
d.subnetSupplies = map[ids.ID]uint64{
subnetID: currentSupply,
}
} else {
d.subnetSupplies[subnetID] = currentSupply
}
}

func (d *diff) GetCurrentValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) {
// If the validator was modified in this diff, return the modified
// validator.
Expand Down Expand Up @@ -254,6 +282,31 @@ func (d *diff) AddSubnet(createSubnetTx *txs.Tx) {
}
}

func (d *diff) GetSubnetTransformation(subnetID ids.ID) (*txs.Tx, error) {
tx, exists := d.transformedSubnets[subnetID]
if exists {
return tx, nil
}

// If the subnet wasn't transformed in this diff, ask the parent state.
parentState, ok := d.stateVersions.GetState(d.parentID)
if !ok {
return nil, ErrMissingParentState
}
return parentState.GetSubnetTransformation(subnetID)
}

func (d *diff) AddSubnetTransformation(transformSubnetTxIntf *txs.Tx) {
transformSubnetTx := transformSubnetTxIntf.Unsigned.(*txs.TransformSubnetTx)
if d.transformedSubnets == nil {
d.transformedSubnets = map[ids.ID]*txs.Tx{
transformSubnetTx.Subnet: transformSubnetTxIntf,
}
} else {
d.transformedSubnets[transformSubnetTx.Subnet] = transformSubnetTxIntf
}
}

func (d *diff) GetChains(subnetID ids.ID) ([]*txs.Tx, error) {
addedChains := d.addedChains[subnetID]
if len(addedChains) == 0 {
Expand Down Expand Up @@ -404,6 +457,9 @@ func (d *diff) DeleteUTXO(utxoID ids.ID) {
func (d *diff) Apply(baseState State) {
baseState.SetTimestamp(d.timestamp)
baseState.SetCurrentSupply(d.currentSupply)
for subnetID, supply := range d.subnetSupplies {
baseState.SetCurrentSubnetSupply(subnetID, supply)
}
for _, subnetValidatorDiffs := range d.currentStakerDiffs.validatorDiffs {
for _, validatorDiff := range subnetValidatorDiffs {
if validatorDiff.validatorModified {
Expand Down Expand Up @@ -449,6 +505,9 @@ func (d *diff) Apply(baseState State) {
for _, subnet := range d.addedSubnets {
baseState.AddSubnet(subnet)
}
for _, tx := range d.transformedSubnets {
baseState.AddSubnetTransformation(tx)
}
for _, chains := range d.addedChains {
for _, chain := range chains {
baseState.AddChain(chain)
Expand Down
Loading

0 comments on commit 59e302f

Please sign in to comment.