Skip to content

Commit

Permalink
feat: Refactor account cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
matevz committed May 16, 2023
1 parent 9cd47d4 commit 67d9e13
Show file tree
Hide file tree
Showing 14 changed files with 1,094 additions and 938 deletions.
915 changes: 0 additions & 915 deletions cmd/account.go

This file was deleted.

27 changes: 27 additions & 0 deletions cmd/account/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package account

import (
"github.com/spf13/cobra"
)

var (

Check failure on line 7 in cmd/account/account.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
Cmd = &cobra.Command{
Use: "account",
Short: "Account operations",
Aliases: []string{"accounts"},
}
)

func init() {
Cmd.AddCommand(allowCmd)
Cmd.AddCommand(amendCommissionScheduleCmd)
Cmd.AddCommand(burnCmd)
Cmd.AddCommand(delegateCmd)
Cmd.AddCommand(depositCmd)
Cmd.AddCommand(entityCmd)
Cmd.AddCommand(fromPublicKeyCmd)
Cmd.AddCommand(showCmd)
Cmd.AddCommand(transferCmd)
Cmd.AddCommand(undelegateCmd)
Cmd.AddCommand(withdrawCmd)
}
70 changes: 70 additions & 0 deletions cmd/account/allow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package account

import (
"context"

"github.com/spf13/cobra"

staking "github.com/oasisprotocol/oasis-core/go/staking/api"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/helpers"

"github.com/oasisprotocol/cli/cmd/common"
cliConfig "github.com/oasisprotocol/cli/config"
)

var allowCmd = &cobra.Command{
Use: "allow <beneficiary> <amount>",
Short: "Configure beneficiary allowance for an account",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
cfg := cliConfig.Global()
npa := common.GetNPASelection(cfg)
txCfg := common.GetTransactionConfig()
beneficiary, amount := args[0], args[1]

if npa.Account == nil {
cobra.CheckErr("no accounts configured in your wallet")
}

// When not in offline mode, connect to the given network endpoint.
ctx := context.Background()
var conn connection.Connection
if !txCfg.Offline {
var err error
conn, err = connection.Connect(ctx, npa.Network)
cobra.CheckErr(err)
}

// Resolve beneficiary address.
benAddr, _, err := common.ResolveLocalAccountOrAddress(npa.Network, beneficiary)
cobra.CheckErr(err)

// Parse amount.
var negative bool
if amount[0] == '-' {
negative = true
amount = amount[1:]
}
amountChange, err := helpers.ParseConsensusDenomination(npa.Network, amount)
cobra.CheckErr(err)

// Prepare transaction.
tx := staking.NewAllowTx(0, nil, &staking.Allow{
Beneficiary: benAddr.ConsensusAddress(),
Negative: negative,
AmountChange: *amountChange,
})

acc := common.LoadAccount(cfg, npa.AccountName)
sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

func init() {
allowCmd.Flags().AddFlagSet(common.SelectorNAFlags)
allowCmd.Flags().AddFlagSet(common.TransactionFlags)
}
182 changes: 182 additions & 0 deletions cmd/account/amend_commission_schedule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package account

import (
"context"
"fmt"
"math/big"

"github.com/spf13/cobra"
flag "github.com/spf13/pflag"

beacon "github.com/oasisprotocol/oasis-core/go/beacon/api"
staking "github.com/oasisprotocol/oasis-core/go/staking/api"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"

"github.com/oasisprotocol/cli/cmd/common"
cliConfig "github.com/oasisprotocol/cli/config"
)

var (
commissionScheduleRates []string
commissionScheduleBounds []string

amendCommissionScheduleCmd = &cobra.Command{
Use: "amend-commission-schedule",
Short: "Amend the account's commission schedule",
Run: func(cmd *cobra.Command, args []string) {
cfg := cliConfig.Global()
npa := common.GetNPASelection(cfg)
txCfg := common.GetTransactionConfig()

if npa.Account == nil {
cobra.CheckErr("no accounts configured in your wallet")
}
acc := common.LoadAccount(cfg, npa.AccountName)

// When not in offline mode, connect to the given network endpoint.
ctx := context.Background()
var (
conn connection.Connection

rules *staking.CommissionScheduleRules
schedule *staking.CommissionSchedule
now beacon.EpochTime
)
if !txCfg.Offline {
var err error
conn, err = connection.Connect(ctx, npa.Network)
cobra.CheckErr(err)

// And also query the various dynamic values required
// to validate the amendment.

var height int64
height, err = common.GetActualHeight(
ctx,
conn.Consensus(),
)
cobra.CheckErr(err)

now, err = conn.Consensus().Beacon().GetEpoch(ctx, height)
cobra.CheckErr(err)

addr, _, err := common.ResolveLocalAccountOrAddress(npa.Network, npa.Account.Address)
cobra.CheckErr(err)

stakingConn := conn.Consensus().Staking()

params, err := stakingConn.ConsensusParameters(ctx, height)
cobra.CheckErr(err)

consensusAccount, err := stakingConn.Account(
ctx,
&staking.OwnerQuery{
Owner: addr.ConsensusAddress(),
Height: height,
},
)
cobra.CheckErr(err)

rules = &params.CommissionScheduleRules
schedule = &consensusAccount.Escrow.CommissionSchedule
}

var amendment staking.AmendCommissionSchedule
if rawRates := commissionScheduleRates; len(rawRates) > 0 {
amendment.Amendment.Rates = make([]staking.CommissionRateStep, len(rawRates))
for i, rawRate := range rawRates {
if err := scanRateStep(&amendment.Amendment.Rates[i], rawRate); err != nil {
cobra.CheckErr(fmt.Errorf("failed to parse commission schedule rate step %d: %w", i, err))
}
}
}
if rawBounds := commissionScheduleBounds; len(rawBounds) > 0 {
amendment.Amendment.Bounds = make([]staking.CommissionRateBoundStep, len(rawBounds))
for i, rawBound := range rawBounds {
if err := scanBoundStep(&amendment.Amendment.Bounds[i], rawBound); err != nil {
cobra.CheckErr(fmt.Errorf("failed to parse commission schedule bound step %d: %w", i, err))
}
}
}

if rules != nil && schedule != nil {
// If we are in online mode, try to validate the amendment.
err := schedule.AmendAndPruneAndValidate(
&amendment.Amendment,
rules,
now,
)
cobra.CheckErr(err)
}

// Prepare transaction.
tx := staking.NewAmendCommissionScheduleTx(0, nil, &amendment)

sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}
)

func scanRateStep(
dst *staking.CommissionRateStep,
raw string,
) error {
var rateBI big.Int
n, err := fmt.Sscanf(raw, "%d/%d", &dst.Start, &rateBI)
if err != nil {
return err
}
if n != 2 {
return fmt.Errorf("scanned %d values (need 2)", n)
}
if err = dst.Rate.FromBigInt(&rateBI); err != nil {
return fmt.Errorf("rate: %w", err)
}
return nil
}

func scanBoundStep(
dst *staking.CommissionRateBoundStep,
raw string,
) error {
var (
rateMinBI big.Int
rateMaxBI big.Int
)
n, err := fmt.Sscanf(raw, "%d/%d/%d", &dst.Start, &rateMinBI, &rateMaxBI)
if err != nil {
return err
}
if n != 3 {
return fmt.Errorf("scanned %d values (need 3)", n)
}
if err = dst.RateMin.FromBigInt(&rateMinBI); err != nil {
return fmt.Errorf("rate min: %w", err)
}

if err = dst.RateMax.FromBigInt(&rateMaxBI); err != nil {
return fmt.Errorf("rate max: %w", err)
}
return nil
}

func init() {
f := flag.NewFlagSet("", flag.ContinueOnError)
f.StringSliceVar(&commissionScheduleRates, "rates", nil, fmt.Sprintf(
"commission rate step. Multiple of this flag is allowed. "+
"Each step is in the format start_epoch/rate_numerator. "+
"The rate is rate_numerator divided by %v", staking.CommissionRateDenominator,
))
f.StringSliceVar(&commissionScheduleBounds, "bounds", nil, fmt.Sprintf(
"commission rate bound step. Multiple of this flag is allowed. "+
"Each step is in the format start_epoch/rate_min_numerator/rate_max_numerator. "+
"The minimum rate is rate_min_numerator divided by %v, and the maximum rate is "+
"rate_max_numerator divided by %v", staking.CommissionRateDenominator, staking.CommissionRateDenominator,
))
amendCommissionScheduleCmd.Flags().AddFlagSet(common.SelectorNAFlags)
amendCommissionScheduleCmd.Flags().AddFlagSet(common.TransactionFlags)
amendCommissionScheduleCmd.Flags().AddFlagSet(f)
}
64 changes: 64 additions & 0 deletions cmd/account/burn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package account

import (
"context"

"github.com/spf13/cobra"

staking "github.com/oasisprotocol/oasis-core/go/staking/api"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/helpers"

"github.com/oasisprotocol/cli/cmd/common"
cliConfig "github.com/oasisprotocol/cli/config"
)

var burnCmd = &cobra.Command{
Use: "burn <amount>",
Short: "Burn given amount of tokens",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
cfg := cliConfig.Global()
npa := common.GetNPASelection(cfg)
txCfg := common.GetTransactionConfig()
amountStr := args[0]

if npa.Account == nil {
cobra.CheckErr("no accounts configured in your wallet")
}

// When not in offline mode, connect to the given network endpoint.
ctx := context.Background()
var conn connection.Connection
if !txCfg.Offline {
var err error
conn, err = connection.Connect(ctx, npa.Network)
cobra.CheckErr(err)
}

acc := common.LoadAccount(cfg, npa.AccountName)

if npa.ParaTime != nil {
cobra.CheckErr("burns within paratimes are not supported; use --no-paratime")
}

// Consensus layer transfer.
amount, err := helpers.ParseConsensusDenomination(npa.Network, amountStr)
cobra.CheckErr(err)

// Prepare transaction.
tx := staking.NewBurnTx(0, nil, &staking.Burn{
Amount: *amount,
})

sigTx, err := common.SignConsensusTransaction(ctx, npa, acc, conn, tx)
cobra.CheckErr(err)

common.BroadcastOrExportTransaction(ctx, npa.ParaTime, conn, sigTx, nil, nil)
},
}

func init() {
burnCmd.Flags().AddFlagSet(common.SelectorNAFlags)
burnCmd.Flags().AddFlagSet(common.TransactionFlags)
}

0 comments on commit 67d9e13

Please sign in to comment.