Skip to content

Commit

Permalink
ACP-77: Implement IncreaseBalanceTx (#3429)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph authored Nov 13, 2024
1 parent 6050f16 commit 4c19989
Show file tree
Hide file tree
Showing 24 changed files with 1,195 additions and 4 deletions.
44 changes: 40 additions & 4 deletions tests/e2e/p/l1.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package p

import (
"bytes"
"context"
"errors"
"math"
Expand Down Expand Up @@ -516,7 +517,7 @@ var _ = e2e.DescribePChain("[L1]", func() {
})

var nextNonce uint64
setWeight := func(validationID ids.ID, weight uint64) {
setWeight := func(validationID ids.ID, weight uint64, genesisValidatorBit int) {
tc.By("creating the unsigned SubnetValidatorWeightMessage")
unsignedSubnetValidatorWeight := must[*warp.UnsignedMessage](tc)(warp.NewUnsignedMessage(
networkID,
Expand Down Expand Up @@ -550,7 +551,7 @@ var _ = e2e.DescribePChain("[L1]", func() {
setSubnetValidatorWeight, err := warp.NewMessage(
unsignedSubnetValidatorWeight,
&warp.BitSetSignature{
Signers: set.NewBits(0).Bytes(), // [signers] has weight from the genesis peer
Signers: set.NewBits(genesisValidatorBit).Bytes(), // [signers] has weight from the genesis validator
Signature: ([bls.SignatureLen]byte)(
bls.SignatureToBytes(setSubnetValidatorWeightSignature),
),
Expand Down Expand Up @@ -585,7 +586,9 @@ var _ = e2e.DescribePChain("[L1]", func() {
}

tc.By("increasing the weight of the validator", func() {
setWeight(registerValidationID, updatedWeight)
// Because registerValidationID is not active, the genesis validator
// is guaranteed to be index 0.
setWeight(registerValidationID, updatedWeight, 0)
})

tc.By("verifying the validator weight was increased", func() {
Expand Down Expand Up @@ -660,10 +663,43 @@ var _ = e2e.DescribePChain("[L1]", func() {
})
})

tc.By("issuing an IncreaseBalanceTx", func() {
_, err := pWallet.IssueIncreaseBalanceTx(
registerValidationID,
units.Avax,
)
require.NoError(err)
})

tc.By("verifying the validator was activated", func() {
verifyValidatorSet(map[ids.NodeID]*snowvalidators.GetValidatorOutput{
subnetGenesisNode.NodeID: {
NodeID: subnetGenesisNode.NodeID,
PublicKey: genesisNodePK,
Weight: genesisWeight,
},
subnetRegisterNode.NodeID: {
NodeID: subnetRegisterNode.NodeID,
PublicKey: registerNodePK,
Weight: updatedWeight,
},
})
})

tc.By("advancing the proposervm P-chain height", advanceProposerVMPChainHeight)

tc.By("removing the registered validator", func() {
setWeight(registerValidationID, 0)
// Because registerValidationID is active, we must calculate which
// bit the genesis validator should be in the warp message.
var (
genesisValidatorPKBytes = bls.PublicKeyToUncompressedBytes(genesisNodePK)
registerValidatorPKBytes = bls.PublicKeyToUncompressedBytes(registerNodePK)
genesisValidatorBit int
)
if bytes.Compare(genesisValidatorPKBytes, registerValidatorPKBytes) > 0 {
genesisValidatorBit = 1
}
setWeight(registerValidationID, 0, genesisValidatorBit)
})

tc.By("verifying the validator was removed", func() {
Expand Down
7 changes: 7 additions & 0 deletions vms/platformvm/metrics/tx_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,10 @@ func (m *txMetrics) SetSubnetValidatorWeightTx(*txs.SetSubnetValidatorWeightTx)
}).Inc()
return nil
}

func (m *txMetrics) IncreaseBalanceTx(*txs.IncreaseBalanceTx) error {
m.numTxs.With(prometheus.Labels{
txLabel: "increase_balance",
}).Inc()
return nil
}
1 change: 1 addition & 0 deletions vms/platformvm/txs/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,6 @@ func RegisterEtnaTypes(targetCodec linearcodec.Codec) error {
targetCodec.RegisterType(&ConvertSubnetTx{}),
targetCodec.RegisterType(&RegisterSubnetValidatorTx{}),
targetCodec.RegisterType(&SetSubnetValidatorWeightTx{}),
targetCodec.RegisterType(&IncreaseBalanceTx{}),
)
}
4 changes: 4 additions & 0 deletions vms/platformvm/txs/executor/atomic_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ func (*atomicTxExecutor) SetSubnetValidatorWeightTx(*txs.SetSubnetValidatorWeigh
return ErrWrongTxType
}

func (*atomicTxExecutor) IncreaseBalanceTx(*txs.IncreaseBalanceTx) error {
return ErrWrongTxType
}

func (e *atomicTxExecutor) ImportTx(*txs.ImportTx) error {
return e.atomicTx()
}
Expand Down
4 changes: 4 additions & 0 deletions vms/platformvm/txs/executor/proposal_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ func (*proposalTxExecutor) SetSubnetValidatorWeightTx(*txs.SetSubnetValidatorWei
return ErrWrongTxType
}

func (*proposalTxExecutor) IncreaseBalanceTx(*txs.IncreaseBalanceTx) error {
return ErrWrongTxType
}

func (e *proposalTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error {
// AddValidatorTx is a proposal transaction until the Banff fork
// activation. Following the activation, AddValidatorTxs must be issued into
Expand Down
72 changes: 72 additions & 0 deletions vms/platformvm/txs/executor/standard_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,78 @@ func (e *standardTxExecutor) SetSubnetValidatorWeightTx(tx *txs.SetSubnetValidat
return nil
}

func (e *standardTxExecutor) IncreaseBalanceTx(tx *txs.IncreaseBalanceTx) error {
var (
currentTimestamp = e.state.GetTimestamp()
upgrades = e.backend.Config.UpgradeConfig
)
if !upgrades.IsEtnaActivated(currentTimestamp) {
return errEtnaUpgradeNotActive
}

if err := e.tx.SyntacticVerify(e.backend.Ctx); err != nil {
return err
}

if err := avax.VerifyMemoFieldLength(tx.Memo, true /*=isDurangoActive*/); err != nil {
return err
}

// Verify the flowcheck
fee, err := e.feeCalculator.CalculateFee(tx)
if err != nil {
return err
}

fee, err = math.Add(fee, tx.Balance)
if err != nil {
return err
}

if err := e.backend.FlowChecker.VerifySpend(
tx,
e.state,
tx.Ins,
tx.Outs,
e.tx.Creds,
map[ids.ID]uint64{
e.backend.Ctx.AVAXAssetID: fee,
},
); err != nil {
return err
}

sov, err := e.state.GetSubnetOnlyValidator(tx.ValidationID)
if err != nil {
return err
}

// If the validator is currently inactive, we are activating it.
if sov.EndAccumulatedFee == 0 {
if gas.Gas(e.state.NumActiveSubnetOnlyValidators()) >= e.backend.Config.ValidatorFeeConfig.Capacity {
return errMaxNumActiveValidators
}

sov.EndAccumulatedFee = e.state.GetAccruedFees()
}
sov.EndAccumulatedFee, err = math.Add(sov.EndAccumulatedFee, tx.Balance)
if err != nil {
return err
}

if err := e.state.PutSubnetOnlyValidator(sov); err != nil {
return err
}

txID := e.tx.ID()

// Consume the UTXOS
avax.Consume(e.state, tx.Ins)
// Produce the UTXOS
avax.Produce(e.state, txID, tx.Outs)
return nil
}

// Creates the staker as defined in [stakerTx] and adds it to [e.State].
func (e *standardTxExecutor) putStaker(stakerTx txs.Staker) error {
var (
Expand Down
Loading

0 comments on commit 4c19989

Please sign in to comment.