R4R: Ensure all CLI queries respect output flags (#3320)

This commit is contained in:
Jack Zampolin 2019-01-22 09:28:39 -08:00 committed by GitHub
parent b055c129dd
commit 9f50c9f5b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 740 additions and 709 deletions

View File

@ -8,8 +8,8 @@ BREAKING CHANGES
* [\#2222] all endpoints renamed from `/stake` -> `/staking`
* [\#1268] `LooseTokens` -> `NotBondedTokens`
* [\#3289] misc renames:
* `Validator.UnbondingMinTime` -> `Validator.UnbondingCompletionTime`
* `Delegation` -> `Value` in `MsgCreateValidator` and `MsgDelegate`
* `Validator.UnbondingMinTime` -> `Validator.UnbondingCompletionTime`
* `Delegation` -> `Value` in `MsgCreateValidator` and `MsgDelegate`
* `MsgBeginUnbonding` -> `MsgUndelegate`
* Gaia CLI (`gaiacli`)
@ -19,6 +19,7 @@ BREAKING CHANGES
* [\#3069](https://github.com/cosmos/cosmos-sdk/pull/3069) `--fee` flag renamed to `--fees` to support multiple coins
* [\#3156](https://github.com/cosmos/cosmos-sdk/pull/3156) Remove unimplemented `gaiacli init` command
* [\#2222] `gaiacli tx stake` -> `gaiacli tx staking`, `gaiacli query stake` -> `gaiacli query staking`
* [\#3320](https://github.com/cosmos/cosmos-sdk/pull/3320) Ensure all `gaiacli query` commands respect the `--output` and `--indent` flags
* Gaia
* https://github.com/cosmos/cosmos-sdk/issues/2838 - Move store keys to constants
@ -32,14 +33,21 @@ BREAKING CHANGES
* [\#3064](https://github.com/cosmos/cosmos-sdk/issues/3064) Sanitize `sdk.Coin` denom. Coins denoms are now case insensitive, i.e. 100fooToken equals to 100FOOTOKEN.
* [\#3195](https://github.com/cosmos/cosmos-sdk/issues/3195) Allows custom configuration for syncable strategy
* [\#3242](https://github.com/cosmos/cosmos-sdk/issues/3242) Fix infinite gas
<<<<<<< HEAD
meter utilization during aborted ante handler executions.
* [x/distribution] \#3292 Enable or disable withdraw addresses with a parameter in the param store
* [staking] \#2222 `/stake` -> `/staking` module rename
* [staking] \#1268 `LooseTokens` -> `NotBondedTokens`
* [staking] \#1402 Redelegation and unbonding-delegation structs changed to include multiple an array of entries
* [staking] \#1402 Redelegation and unbonding-delegation structs changed to include multiple an array of entries
=======
meter utilization during aborted ante handler executions.
* [\#2222] [x/staking] `/stake` -> `/staking` module rename
* \#3292 [x/distribution] Enable or disable withdraw addresses with a parameter in the param store
* [staking] \#1402 Redelegation and unbonding-delegation structs changed to include multiple an array of entries
>>>>>>> Pending.md
* [staking] \#3289 misc renames:
* `Validator.UnbondingMinTime` -> `Validator.UnbondingCompletionTime`
* `Delegation` -> `Value` in `MsgCreateValidator` and `MsgDelegate`
* `Validator.UnbondingMinTime` -> `Validator.UnbondingCompletionTime`
* `Delegation` -> `Value` in `MsgCreateValidator` and `MsgDelegate`
* `MsgBeginUnbonding` -> `MsgUndelegate`
* [\#3315] Increase decimal precision to 18
* [\#3328](https://github.com/cosmos/cosmos-sdk/issues/3328) [x/gov] Remove redundant action tag
@ -114,8 +122,12 @@ IMPROVEMENTS
slashing, and staking modules.
* [\#3093](https://github.com/cosmos/cosmos-sdk/issues/3093) Ante handler does no longer read all accounts in one go when processing signatures as signature
verification may fail before last signature is checked.
* [staking] \#1402 Add for multiple simultaneous redelegations or unbonding-delegations within an unbonding period
<<<<<<< HEAD
* [staking] \#1402 Add for multiple simultaneous redelegations or unbonding-delegations within an unbonding period
* [staking] \#1268 staking spec rewrite
=======
* [x/stake] \#1402 Add for multiple simultaneous redelegations or unbonding-delegations within an unbonding period
>>>>>>> Pending.md
* Tendermint

View File

@ -35,6 +35,7 @@ type CLIContext struct {
AccDecoder auth.AccountDecoder
Client rpcclient.Client
Output io.Writer
OutputFormat string
Height int64
NodeURI string
From string
@ -76,6 +77,7 @@ func NewCLIContext() CLIContext {
NodeURI: nodeURI,
AccountStore: auth.StoreKey,
From: viper.GetString(client.FlagFrom),
OutputFormat: viper.GetString(cli.OutputFlag),
Height: viper.GetInt64(client.FlagHeight),
TrustNode: viper.GetBool(client.FlagTrustNode),
UseLedger: viper.GetBool(client.FlagUseLedger),
@ -254,3 +256,28 @@ func (ctx CLIContext) WithSimulation(simulate bool) CLIContext {
ctx.Simulate = simulate
return ctx
}
// PrintOutput prints output while respecting output and indent flags
// NOTE: pass in marshalled structs that have been unmarshaled
// because this function will panic on marshaling errors
func (ctx CLIContext) PrintOutput(toPrint fmt.Stringer) (err error) {
var out []byte
switch ctx.OutputFormat {
case "text":
out = []byte(toPrint.String())
case "json":
if ctx.Indent {
out, err = ctx.Codec.MarshalJSONIndent(toPrint, "", " ")
} else {
out, err = ctx.Codec.MarshalJSON(toPrint)
}
}
if err != nil {
return
}
fmt.Println(string(out))
return
}

View File

@ -98,6 +98,7 @@ $ gaiacli query txs --tags '<tag1>:<value1>&<tag2>:<value2>' --page 1 --limit 30
cmd.Flags().String(flagTags, "", "tag:value list of tags that must match")
cmd.Flags().Int32(flagPage, defaultPage, "Query a specific page of paginated results")
cmd.Flags().Int32(flagLimit, defaultLimit, "Query number of transactions results per page returned")
cmd.MarkFlagRequired(flagTags)
return cmd
}

View File

@ -383,7 +383,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf(stakingTypes.DefaultBondDenom).Int64())
proposalsQuery := f.QueryGovProposals()
require.Equal(t, "No matching proposals found", proposalsQuery)
require.Empty(t, proposalsQuery)
// Test submit generate only for submit proposal
success, stdout, stderr := f.TxGovSubmitProposal(
@ -418,7 +418,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
// Ensure query proposals returns properly
proposalsQuery = f.QueryGovProposals()
require.Equal(t, " 1 - Test", proposalsQuery)
require.Equal(t, uint64(1), proposalsQuery[0].GetProposalID())
// Query the deposits on the proposal
deposit := f.QueryGovDeposit(1, fooAddr)
@ -489,11 +489,11 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
// Ensure no proposals in deposit period
proposalsQuery = f.QueryGovProposals("--status=DepositPeriod")
require.Equal(t, "No matching proposals found", proposalsQuery)
require.Empty(t, proposalsQuery)
// Ensure the proposal returns as in the voting period
proposalsQuery = f.QueryGovProposals("--status=VotingPeriod")
require.Equal(t, " 1 - Test", proposalsQuery)
require.Equal(t, uint64(1), proposalsQuery[0].GetProposalID())
// submit a second test proposal
f.TxGovSubmitProposal(keyFoo, "Text", "Apples", "test", sdk.NewInt64Coin(denom, 5))
@ -501,7 +501,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
// Test limit on proposals query
proposalsQuery = f.QueryGovProposals("--limit=1")
require.Equal(t, " 2 - Apples", proposalsQuery)
require.Equal(t, uint64(2), proposalsQuery[0].GetProposalID())
f.Cleanup()
}

View File

@ -380,7 +380,7 @@ func (f *Fixtures) QueryStakingPool(flags ...string) staking.Pool {
// QueryStakingParameters is gaiacli query staking parameters
func (f *Fixtures) QueryStakingParameters(flags ...string) staking.Params {
cmd := fmt.Sprintf("gaiacli query staking parameters %v", f.Flags())
cmd := fmt.Sprintf("gaiacli query staking params %v", f.Flags())
out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "")
var params staking.Params
cdc := app.MakeCodec()
@ -426,11 +426,18 @@ func (f *Fixtures) QueryGovParamTallying() gov.TallyParams {
}
// QueryGovProposals is gaiacli query gov proposals
func (f *Fixtures) QueryGovProposals(flags ...string) string {
func (f *Fixtures) QueryGovProposals(flags ...string) gov.Proposals {
cmd := fmt.Sprintf("gaiacli query gov proposals %v", f.Flags())
stdout, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), "")
if strings.Contains(stderr, "No matching proposals found") {
return gov.Proposals{}
}
require.Empty(f.T, stderr)
return stdout
var out gov.Proposals
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(stdout), &out)
require.NoError(f.T, err)
return out
}
// QueryGovProposal is gaiacli query gov proposal

View File

@ -380,15 +380,13 @@ Don't use more `steak` thank you have! You can always get more by using the [Fau
Once submitted a delegation to a validator, you can see it's information by using the following command:
```bash
gaiacli query staking delegation \
--address-delegator=<account_cosmos> \
--validator=<account_cosmosval>
gaiacli query staking delegation <delegator_addr> <validator_addr>
```
Or if you want to check all your current delegations with disctinct validators:
```bash
gaiacli query staking delegations <account_cosmos>
gaiacli query staking delegations <delegator_addr>
```
You can also get previous delegation(s) status by adding the `--height` flag.
@ -412,9 +410,7 @@ The unbonding will be automatically completed when the unbonding period has pass
Once you begin an unbonding-delegation, you can see it's information by using the following command:
```bash
gaiacli query staking unbonding-delegation \
--address-delegator=<account_cosmos> \
--validator=<account_cosmosval> \
gaiacli query staking unbonding-delegation <delegator_addr> <validator_addr>
```
Or if you want to check all your current unbonding-delegations with disctinct validators:
@ -426,7 +422,7 @@ gaiacli query staking unbonding-delegations <account_cosmos>
Additionally, as you can get all the unbonding-delegations from a particular validator:
```bash
gaiacli query staking unbonding-delegations-from <account_cosmosval>
gaiacli query staking unbonding-delegations-from <account_cosmosval>
```
To get previous unbonding-delegation(s) status on past blocks, try adding the `--height` flag.
@ -453,10 +449,7 @@ The redelegation will be automatically completed when the unbonding period has p
Once you begin an redelegation, you can see it's information by using the following command:
```bash
gaiacli query staking redelegation \
--address-delegator=<account_cosmos> \
--addr-validator-source=<account_cosmosval> \
--addr-validator-dest=<account_cosmosval> \
gaiacli query staking redelegation <delegator_addr> <src_val_addr> <dst_val_addr>
```
Or if you want to check all your current unbonding-delegations with disctinct validators:
@ -478,7 +471,7 @@ To get previous redelegation(s) status on past blocks, try adding the `--height`
Parameters define high level settings for staking. You can get the current values by using:
```bash
gaiacli query staking parameters
gaiacli query staking params
```
With the above command you will get the values for:
@ -629,6 +622,12 @@ gaiacli query gov tally <proposal_id>
To check the current governance parameters run:
```bash
gaiacli query gov params
```
To query subsets of the governance parameters run:
```bash
gaiacli query gov param voting
gaiacli query gov param tallying

View File

@ -2,6 +2,7 @@ package auth
import (
"errors"
"fmt"
"time"
"github.com/tendermint/tendermint/crypto"
@ -35,6 +36,9 @@ type Account interface {
// Calculates the amount of coins that can be sent to other accounts given
// the current time.
SpendableCoins(blockTime time.Time) sdk.Coins
// Ensure that account implements stringer
String() string
}
// VestingAccount defines an account type that vests coins via a vesting schedule.
@ -74,6 +78,16 @@ type BaseAccount struct {
Sequence uint64 `json:"sequence"`
}
// String implements fmt.Stringer
func (acc BaseAccount) String() string {
return fmt.Sprintf(`Account %s:
Coins: %s
PubKey: %s
AccountNumber: %d
Sequence: %d`, acc.Address, acc.Coins,
acc.PubKey.Address(), acc.AccountNumber, acc.Sequence)
}
// Prototype function for BaseAccount
func ProtoBaseAccount() Account {
return &BaseAccount{}
@ -164,6 +178,22 @@ type BaseVestingAccount struct {
EndTime int64 // when the coins become unlocked
}
// String implements fmt.Stringer
func (bva BaseVestingAccount) String() string {
return fmt.Sprintf(`Vesting Account %s:
Coins: %s
PubKey: %s
AccountNumber: %d
Sequence: %d
OriginalVesting: %s
DelegatedFree: %s
DelegatedVesting: %s
EndTime: %d `, bva.Address, bva.Coins,
bva.PubKey.Address(), bva.AccountNumber, bva.Sequence,
bva.OriginalVesting, bva.DelegatedFree,
bva.DelegatedVesting, bva.EndTime)
}
// spendableCoins returns all the spendable coins for a vesting account given a
// set of vesting coins.
//
@ -342,6 +372,22 @@ func NewContinuousVestingAccount(
}
}
func (cva ContinuousVestingAccount) String() string {
return fmt.Sprintf(`Vesting Account %s:
Coins: %s
PubKey: %s
AccountNumber: %d
Sequence: %d
OriginalVesting: %s
DelegatedFree: %s
DelegatedVesting: %s
StartTime: %d
EndTime: %d `, cva.Address, cva.Coins,
cva.PubKey.Address(), cva.AccountNumber, cva.Sequence,
cva.OriginalVesting, cva.DelegatedFree,
cva.DelegatedVesting, cva.StartTime, cva.EndTime)
}
// GetVestedCoins returns the total number of vested coins. If no coins are vested,
// nil is returned.
func (cva ContinuousVestingAccount) GetVestedCoins(blockTime time.Time) sdk.Coins {

View File

@ -1,8 +1,6 @@
package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
@ -20,18 +18,14 @@ func GetAccountCmd(storeName string, cdc *codec.Codec) *cobra.Command {
Short: "Query account balance",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// find the key to look up the account
addr := args[0]
cliCtx := context.NewCLIContext().
WithCodec(cdc).WithAccountDecoder(cdc)
key, err := sdk.AccAddressFromBech32(addr)
key, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(cdc)
if err = cliCtx.EnsureAccountExistsFromAddr(key); err != nil {
return err
}
@ -41,18 +35,7 @@ func GetAccountCmd(storeName string, cdc *codec.Codec) *cobra.Command {
return err
}
var output []byte
if cliCtx.Indent {
output, err = cdc.MarshalJSONIndent(acc, "", " ")
} else {
output, err = cdc.MarshalJSON(acc)
}
if err != nil {
return err
}
fmt.Println(string(output))
return nil
return cliCtx.PrintOutput(acc)
},
}

View File

@ -10,82 +10,75 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
)
// GetCmdQueryParams implements the query params command.
func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "params",
Args: cobra.ExactArgs(0),
Args: cobra.NoArgs,
Short: "Query distribution params",
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := queryParams(cliCtx, cdc, queryRoute)
route := fmt.Sprintf("custom/%s/params/community_tax", queryRoute)
retCommunityTax, err := cliCtx.QueryWithData(route, []byte{})
if err != nil {
return err
}
fmt.Println(string(res))
return nil
route = fmt.Sprintf("custom/%s/params/base_proposer_reward", queryRoute)
retBaseProposerReward, err := cliCtx.QueryWithData(route, []byte{})
if err != nil {
return err
}
route = fmt.Sprintf("custom/%s/params/bonus_proposer_reward", queryRoute)
retBonusProposerReward, err := cliCtx.QueryWithData(route, []byte{})
if err != nil {
return err
}
route = fmt.Sprintf("custom/%s/params/withdraw_addr_enabled", queryRoute)
retWithdrawAddrEnabled, err := cliCtx.QueryWithData(route, []byte{})
if err != nil {
return err
}
params := NewPrettyParams(retCommunityTax, retBaseProposerReward,
retBonusProposerReward, retWithdrawAddrEnabled)
return cliCtx.PrintOutput(params)
},
}
return cmd
}
func queryParams(cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string) ([]byte, error) {
retCommunityTax, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/community_tax", queryRoute), []byte{})
if err != nil {
return nil, err
}
retBaseProposerReward, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/base_proposer_reward", queryRoute), []byte{})
if err != nil {
return nil, err
}
retBonusProposerReward, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/bonus_proposer_reward", queryRoute), []byte{})
if err != nil {
return nil, err
}
retWithdrawAddrEnabled, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/withdraw_addr_enabled", queryRoute), []byte{})
if err != nil {
return nil, err
}
return codec.MarshalJSONIndent(cdc, NewPrettyParams(retCommunityTax, retBaseProposerReward, retBonusProposerReward, retWithdrawAddrEnabled))
}
// GetCmdQueryOutstandingRewards implements the query outstanding rewards command.
func GetCmdQueryOutstandingRewards(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "outstanding-rewards",
Args: cobra.ExactArgs(0),
Args: cobra.NoArgs,
Short: "Query distribution outstanding (un-withdrawn) rewards",
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := queryOutstandingRewards(cliCtx, cdc, queryRoute)
route := fmt.Sprintf("custom/%s/outstanding_rewards", queryRoute)
res, err := cliCtx.QueryWithData(route, []byte{})
if err != nil {
return err
}
fmt.Println(string(res))
return nil
var outstandingRewards types.OutstandingRewards
cdc.MustUnmarshalJSON(res, &outstandingRewards)
return cliCtx.PrintOutput(outstandingRewards)
},
}
return cmd
}
func queryOutstandingRewards(cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string) ([]byte, error) {
return cliCtx.QueryWithData(fmt.Sprintf("custom/%s/outstanding_rewards", queryRoute), []byte{})
}
// GetCmdQueryValidatorCommission implements the query validator commission command.
func GetCmdQueryValidatorCommission(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "commission [validator]",
Args: cobra.ExactArgs(1),
Short: "Query distribution validator commission",
@ -97,29 +90,27 @@ func GetCmdQueryValidatorCommission(queryRoute string, cdc *codec.Codec) *cobra.
return err
}
res, err := queryValidatorCommission(cliCtx, cdc, queryRoute, distr.NewQueryValidatorCommissionParams(validatorAddr))
bz, err := cdc.MarshalJSON(distr.NewQueryValidatorCommissionParams(validatorAddr))
if err != nil {
return err
}
fmt.Println(string(res))
return nil
route := fmt.Sprintf("custom/%s/validator_commission", queryRoute)
res, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
var valCom types.ValidatorAccumulatedCommission
cdc.MustUnmarshalJSON(res, &valCom)
return cliCtx.PrintOutput(valCom)
},
}
return cmd
}
func queryValidatorCommission(cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string, params distr.QueryValidatorCommissionParams) ([]byte, error) {
bz, err := cdc.MarshalJSON(params)
if err != nil {
return nil, err
}
return cliCtx.QueryWithData(fmt.Sprintf("custom/%s/validator_commission", queryRoute), bz)
}
// GetCmdQueryValidatorSlashes implements the query validator slashes command.
func GetCmdQueryValidatorSlashes(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "slashes [validator] [start-height] [end-height]",
Args: cobra.ExactArgs(3),
Short: "Query distribution validator slashes",
@ -141,29 +132,27 @@ func GetCmdQueryValidatorSlashes(queryRoute string, cdc *codec.Codec) *cobra.Com
return fmt.Errorf("end-height %s not a valid uint, please input a valid end-height", args[2])
}
res, err := queryValidatorSlashes(cliCtx, cdc, queryRoute, distr.NewQueryValidatorSlashesParams(validatorAddr, startHeight, endHeight))
params := distr.NewQueryValidatorSlashesParams(validatorAddr, startHeight, endHeight)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/validator_slashes", queryRoute), bz)
if err != nil {
return err
}
var slashes types.ValidatorSlashEvent
cdc.MustUnmarshalJSON(res, &slashes)
return cliCtx.PrintOutput(slashes)
},
}
return cmd
}
func queryValidatorSlashes(cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string, params distr.QueryValidatorSlashesParams) ([]byte, error) {
bz, err := cdc.MarshalJSON(params)
if err != nil {
return nil, err
}
return cliCtx.QueryWithData(fmt.Sprintf("custom/%s/validator_slashes", queryRoute), bz)
}
// GetCmdQueryDelegatorRewards implements the query delegator rewards command.
func GetCmdQueryDelegatorRewards(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "rewards [delegator] [validator]",
Args: cobra.ExactArgs(2),
Short: "Query distribution delegator rewards",
@ -180,22 +169,21 @@ func GetCmdQueryDelegatorRewards(queryRoute string, cdc *codec.Codec) *cobra.Com
return err
}
res, err := queryDelegationRewards(cliCtx, cdc, queryRoute, distr.NewQueryDelegationRewardsParams(delegatorAddr, validatorAddr))
params := distr.NewQueryDelegationRewardsParams(delegatorAddr, validatorAddr)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
route := fmt.Sprintf("custom/%s/delegation_rewards", queryRoute)
res, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
var coins sdk.DecCoins
cdc.MustUnmarshalJSON(res, &coins)
return cliCtx.PrintOutput(coins)
},
}
return cmd
}
func queryDelegationRewards(cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string, params distr.QueryDelegationRewardsParams) ([]byte, error) {
bz, err := cdc.MarshalJSON(params)
if err != nil {
return nil, err
}
return cliCtx.QueryWithData(fmt.Sprintf("custom/%s/delegation_rewards", queryRoute), bz)
}

View File

@ -2,6 +2,7 @@ package cli
import (
"encoding/json"
"fmt"
)
// Convenience struct for CLI output
@ -21,3 +22,13 @@ func NewPrettyParams(communityTax json.RawMessage, baseProposerReward json.RawMe
WithdrawAddrEnabled: withdrawAddrEnabled,
}
}
func (pp PrettyParams) String() string {
return fmt.Sprintf(`Distribution Params:
Community Tax: %s
Base Proposer Reward: %s
Bonus Proposer Reward: %s
Withdraw Addr Enabled: %s`, pp.CommunityTax,
pp.BaseProposerReward, pp.BonusProposerReward, pp.WithdrawAddrEnabled)
}

View File

@ -1,6 +1,9 @@
package types
import (
"fmt"
"strings"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -50,3 +53,22 @@ func NewValidatorSlashEvent(validatorPeriod uint64, fraction sdk.Dec) ValidatorS
Fraction: fraction,
}
}
func (vs ValidatorSlashEvent) String() string {
return fmt.Sprintf(`Period: %d
Fraction: %s`, vs.ValidatorPeriod, vs.Fraction)
}
// ValidatorSlashEvents is a collection of ValidatorSlashEvent
type ValidatorSlashEvents []ValidatorSlashEvent
func (vs ValidatorSlashEvents) String() string {
out := "Validator Slash Events:\n"
for i, sl := range vs {
out += fmt.Sprintf(` Slash %d:
Period: %d
Fraction: %s
`, i, sl.ValidatorPeriod, sl.Fraction)
}
return strings.TrimSpace(out)
}

View File

@ -17,7 +17,7 @@ import (
// GetCmdQueryProposal implements the query proposal command.
func GetCmdQueryProposal(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "proposal [proposal-id]",
Args: cobra.ExactArgs(1),
Short: "Query details of a single proposal",
@ -36,33 +36,16 @@ $ gaiacli query gov proposal 1
}
// Query the proposal
res, err := queryProposal(proposalID, cliCtx, cdc, queryRoute)
res, err := gcutils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
var proposal gov.Proposal
cdc.MustUnmarshalJSON(res, &proposal)
return cliCtx.PrintOutput(proposal)
},
}
return cmd
}
func queryProposal(proposalID uint64, cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string) ([]byte, error) {
// Construct query
params := gov.NewQueryProposalParams(proposalID)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return nil, err
}
// Query store
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/proposal", queryRoute), bz)
if err != nil {
return nil, err
}
return res, err
}
// GetCmdQueryProposals implements a query proposals command.
@ -125,22 +108,17 @@ $ gaiacli query gov proposals --status (DepositPeriod|VotingPeriod|Passed|Reject
return err
}
var matchingProposals []gov.Proposal
var matchingProposals gov.Proposals
err = cdc.UnmarshalJSON(res, &matchingProposals)
if err != nil {
return err
}
if len(matchingProposals) == 0 {
fmt.Println("No matching proposals found")
return nil
return fmt.Errorf("No matching proposals found")
}
for _, proposal := range matchingProposals {
fmt.Printf(" %d - %s\n", proposal.GetProposalID(), proposal.GetTitle())
}
return nil
return cliCtx.PrintOutput(matchingProposals)
},
}
@ -155,7 +133,7 @@ $ gaiacli query gov proposals --status (DepositPeriod|VotingPeriod|Passed|Reject
// Command to Get a Proposal Information
// GetCmdQueryVote implements the query proposal vote command.
func GetCmdQueryVote(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "vote [proposal-id] [voter-address]",
Args: cobra.ExactArgs(2),
Short: "Query details of a single vote",
@ -175,7 +153,7 @@ $ gaiacli query gov vote 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
}
// check to see if the proposal is in the store
_, err = queryProposal(proposalID, cliCtx, cdc, queryRoute)
_, err = gcutils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return fmt.Errorf("Failed to fetch proposal-id %d: %s", proposalID, err)
}
@ -204,19 +182,17 @@ $ gaiacli query gov vote 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
if err != nil {
return err
}
cdc.UnmarshalJSON(res, &vote)
}
fmt.Println(string(res))
return nil
return cliCtx.PrintOutput(vote)
},
}
return cmd
}
// GetCmdQueryVotes implements the command to query for proposal votes.
func GetCmdQueryVotes(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "votes [proposal-id]",
Args: cobra.ExactArgs(1),
Short: "Query votes on a proposal",
@ -242,15 +218,13 @@ $ gaiacli query gov votes 1
}
// check to see if the proposal is in the store
res, err := queryProposal(proposalID, cliCtx, cdc, queryRoute)
res, err := gcutils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return fmt.Errorf("Failed to fetch proposal-id %d: %s", proposalID, err)
}
var proposal gov.Proposal
if err := cdc.UnmarshalJSON(res, &proposal); err != nil {
return err
}
cdc.MustUnmarshalJSON(res, &proposal)
propStatus := proposal.GetStatus()
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
@ -263,18 +237,17 @@ $ gaiacli query gov votes 1
return err
}
fmt.Println(string(res))
return nil
var votes gov.Votes
cdc.MustUnmarshalJSON(res, &votes)
return cliCtx.PrintOutput(votes)
},
}
return cmd
}
// Command to Get a specific Deposit Information
// GetCmdQueryDeposit implements the query proposal deposit command.
func GetCmdQueryDeposit(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "deposit [proposal-id] [depositer-address]",
Args: cobra.ExactArgs(2),
Short: "Query details of a deposit",
@ -294,7 +267,7 @@ $ gaiacli query gov deposit 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
}
// check to see if the proposal is in the store
_, err = queryProposal(proposalID, cliCtx, cdc, queryRoute)
_, err = gcutils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return fmt.Errorf("Failed to fetch proposal-id %d: %s", proposalID, err)
}
@ -316,26 +289,24 @@ $ gaiacli query gov deposit 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
}
var deposit gov.Deposit
cdc.UnmarshalJSON(res, &deposit)
cdc.MustUnmarshalJSON(res, &deposit)
if deposit.Empty() {
res, err = gcutils.QueryDepositByTxQuery(cdc, cliCtx, params)
if err != nil {
return err
}
cdc.MustUnmarshalJSON(res, &deposit)
}
fmt.Println(string(res))
return nil
return cliCtx.PrintOutput(deposit)
},
}
return cmd
}
// GetCmdQueryDeposits implements the command to query for proposal deposits.
func GetCmdQueryDeposits(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "deposits [proposal-id]",
Args: cobra.ExactArgs(1),
Short: "Query deposits on a proposal",
@ -360,15 +331,13 @@ $ gaiacli query gov deposits 1
}
// check to see if the proposal is in the store
res, err := queryProposal(proposalID, cliCtx, cdc, queryRoute)
res, err := gcutils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return fmt.Errorf("Failed to fetch proposal-id %d: %s", proposalID, err)
return fmt.Errorf("Failed to fetch proposal with id %d: %s", proposalID, err)
}
var proposal gov.Proposal
if err := cdc.UnmarshalJSON(res, &proposal); err != nil {
return err
}
cdc.MustUnmarshalJSON(res, &proposal)
propStatus := proposal.GetStatus()
if !(propStatus == gov.StatusVotingPeriod || propStatus == gov.StatusDepositPeriod) {
@ -381,17 +350,16 @@ $ gaiacli query gov deposits 1
return err
}
fmt.Println(string(res))
return nil
var dep gov.Deposits
cdc.MustUnmarshalJSON(res, &dep)
return cliCtx.PrintOutput(dep)
},
}
return cmd
}
// GetCmdQueryTally implements the command to query for proposal tally result.
func GetCmdQueryTally(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "tally [proposal-id]",
Args: cobra.ExactArgs(1),
Short: "Get the tally of a proposal vote",
@ -410,7 +378,7 @@ $ gaiacli query gov tally 1
}
// check to see if the proposal is in the store
_, err = queryProposal(proposalID, cliCtx, cdc, queryRoute)
_, err = gcutils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return fmt.Errorf("Failed to fetch proposal-id %d: %s", proposalID, err)
}
@ -428,17 +396,48 @@ $ gaiacli query gov tally 1
return err
}
fmt.Println(string(res))
return nil
var tally gov.TallyResult
cdc.MustUnmarshalJSON(res, &tally)
return cliCtx.PrintOutput(tally)
},
}
return cmd
}
// GetCmdQueryProposal implements the query proposal command.
func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "params",
Short: "Query the parameters (voting|tallying|deposit) of the governance process",
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
tp, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/tallying", queryRoute), nil)
if err != nil {
return err
}
dp, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/deposit", queryRoute), nil)
if err != nil {
return err
}
vp, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/voting", queryRoute), nil)
if err != nil {
return err
}
var tallyParams gov.TallyParams
cdc.MustUnmarshalJSON(tp, &tallyParams)
var depositParams gov.DepositParams
cdc.MustUnmarshalJSON(dp, &depositParams)
var votingParams gov.VotingParams
cdc.MustUnmarshalJSON(vp, &votingParams)
return cliCtx.PrintOutput(gov.NewParams(votingParams, tallyParams, depositParams))
},
}
}
// GetCmdQueryProposal implements the query proposal command.
func GetCmdQueryParam(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "param [param-type]",
Args: cobra.ExactArgs(1),
Short: "Query the parameters (voting|tallying|deposit) of the governance process",
@ -450,18 +449,32 @@ func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
if err != nil {
return err
}
var out fmt.Stringer
switch args[0] {
case "voting":
var param gov.VotingParams
cdc.MustUnmarshalJSON(res, &param)
out = param
case "tallying":
var param gov.TallyParams
cdc.MustUnmarshalJSON(res, &param)
out = param
case "deposit":
var param gov.DepositParams
cdc.MustUnmarshalJSON(res, &param)
out = param
default:
return fmt.Errorf("Argument must be one of (voting|tallying|deposit), was %s", args[0])
}
fmt.Println(string(res))
return nil
return cliCtx.PrintOutput(out)
},
}
return cmd
}
// GetCmdQueryProposer implements the query proposer command.
func GetCmdQueryProposer(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "proposer [proposal-id]",
Args: cobra.ExactArgs(1),
Short: "Query the proposer of a governance proposal",
@ -474,15 +487,12 @@ func GetCmdQueryProposer(queryRoute string, cdc *codec.Codec) *cobra.Command {
return fmt.Errorf("proposal-id %s is not a valid uint", args[0])
}
res, err := gcutils.QueryProposerByTxQuery(cdc, cliCtx, proposalID)
prop, err := gcutils.QueryProposerByTxQuery(cdc, cliCtx, proposalID)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
return cliCtx.PrintOutput(prop)
},
}
return cmd
}

View File

@ -194,7 +194,7 @@ $ gaiacli tx gov deposit 1 10stake --from mykey
}
// check to see if the proposal is in the store
_, err = queryProposal(proposalID, cliCtx, cdc, queryRoute)
_, err = govClientUtils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return fmt.Errorf("Failed to fetch proposal-id %d: %s", proposalID, err)
}
@ -270,7 +270,7 @@ $ gaiacli tx gov vote 1 yes --from mykey
}
// check to see if the proposal is in the store
_, err = queryProposal(proposalID, cliCtx, cdc, queryRoute)
_, err = govClientUtils.QueryProposalByID(proposalID, cliCtx, cdc, queryRoute)
if err != nil {
return fmt.Errorf("Failed to fetch proposal-id %d: %s", proposalID, err)
}

View File

@ -31,6 +31,7 @@ func (mc ModuleClient) GetQueryCmd() *cobra.Command {
govCli.GetCmdQueryProposals(mc.storeKey, mc.cdc),
govCli.GetCmdQueryVote(mc.storeKey, mc.cdc),
govCli.GetCmdQueryVotes(mc.storeKey, mc.cdc),
govCli.GetCmdQueryParam(mc.storeKey, mc.cdc),
govCli.GetCmdQueryParams(mc.storeKey, mc.cdc),
govCli.GetCmdQueryProposer(mc.storeKey, mc.cdc),
govCli.GetCmdQueryDeposit(mc.storeKey, mc.cdc),

View File

@ -22,6 +22,15 @@ type Proposer struct {
Proposer string `json:"proposer"`
}
// NewProposer returns a new Proposer given id and proposer
func NewProposer(proposalID uint64, proposer string) Proposer {
return Proposer{proposalID, proposer}
}
func (p Proposer) String() string {
return fmt.Sprintf("Proposal with ID %d was proposed by %s", p.ProposalID, p.Proposer)
}
// QueryDepositsByTxQuery will query for deposits via a direct txs tags query. It
// will fetch and build deposits directly from the returned txs and return a
// JSON marshalled result or any error that occurred.
@ -201,7 +210,7 @@ func QueryDepositByTxQuery(
// ID.
func QueryProposerByTxQuery(
cdc *codec.Codec, cliCtx context.CLIContext, proposalID uint64,
) ([]byte, error) {
) (Proposer, error) {
tags := []string{
fmt.Sprintf("%s='%s'", tags.Action, gov.MsgSubmitProposal{}.Type()),
@ -212,7 +221,7 @@ func QueryProposerByTxQuery(
// support configurable pagination.
infos, err := tx.SearchTxs(cliCtx, cdc, tags, defaultPage, defaultLimit)
if err != nil {
return nil, err
return Proposer{}, err
}
for _, info := range infos {
@ -220,20 +229,24 @@ func QueryProposerByTxQuery(
// there should only be a single proposal under the given conditions
if msg.Type() == gov.TypeMsgSubmitProposal {
subMsg := msg.(gov.MsgSubmitProposal)
proposer := Proposer{
ProposalID: proposalID,
Proposer: subMsg.Proposer.String(),
}
if cliCtx.Indent {
return cdc.MarshalJSONIndent(proposer, "", " ")
}
return cdc.MarshalJSON(proposer)
return NewProposer(proposalID, subMsg.Proposer.String()), nil
}
}
}
return nil, fmt.Errorf("failed to find the proposer for proposalID %d", proposalID)
return Proposer{}, fmt.Errorf("failed to find the proposer for proposalID %d", proposalID)
}
// QueryProposalByID takes a proposalID and returns a proposal
func QueryProposalByID(proposalID uint64, cliCtx context.CLIContext, cdc *codec.Codec, queryRoute string) ([]byte, error) {
params := gov.NewQueryProposalParams(proposalID)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return nil, err
}
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/proposal", queryRoute), bz)
if err != nil {
return nil, err
}
return res, err
}

View File

@ -16,15 +16,29 @@ type Vote struct {
Option VoteOption `json:"option"` // option from OptionSet chosen by the voter
}
func (v Vote) String() string {
return fmt.Sprintf("Voter %s voted with option %s on proposal %d", v.Voter, v.Option, v.ProposalID)
}
// Votes is a collection of Vote
type Votes []Vote
func (v Votes) String() string {
out := fmt.Sprintf("Votes for Proposal %d:", v[0].ProposalID)
for _, vot := range v {
out += fmt.Sprintf("\n %s: %s", vot.Voter, vot.Option)
}
return out
}
// Returns whether 2 votes are equal
func (voteA Vote) Equals(voteB Vote) bool {
return voteA.Voter.Equals(voteB.Voter) && voteA.ProposalID == voteB.ProposalID && voteA.Option == voteB.Option
func (v Vote) Equals(comp Vote) bool {
return v.Voter.Equals(comp.Voter) && v.ProposalID == comp.ProposalID && v.Option == comp.Option
}
// Returns whether a vote is empty
func (voteA Vote) Empty() bool {
voteB := Vote{}
return voteA.Equals(voteB)
func (v Vote) Empty() bool {
return v.Equals(Vote{})
}
// Deposit
@ -34,15 +48,30 @@ type Deposit struct {
Amount sdk.Coins `json:"amount"` // Deposit amount
}
func (d Deposit) String() string {
return fmt.Sprintf("Deposit by %s on Proposal %d is for the amount %s",
d.Depositor, d.ProposalID, d.Amount)
}
// Deposits is a collection of depoist
type Deposits []Deposit
func (d Deposits) String() string {
out := fmt.Sprintf("Deposits for Proposal %d:", d[0].ProposalID)
for _, dep := range d {
out += fmt.Sprintf("\n %s: %s", dep.Depositor, dep.Amount)
}
return out
}
// Returns whether 2 deposits are equal
func (depositA Deposit) Equals(depositB Deposit) bool {
return depositA.Depositor.Equals(depositB.Depositor) && depositA.ProposalID == depositB.ProposalID && depositA.Amount.IsEqual(depositB.Amount)
func (d Deposit) Equals(comp Deposit) bool {
return d.Depositor.Equals(comp.Depositor) && d.ProposalID == comp.ProposalID && d.Amount.IsEqual(comp.Amount)
}
// Returns whether a deposit is empty
func (depositA Deposit) Empty() bool {
depositB := Deposit{}
return depositA.Equals(depositB)
func (d Deposit) Empty() bool {
return d.Equals(Deposit{})
}
// Type that represents VoteOption as a byte

View File

@ -1,6 +1,7 @@
package gov
import (
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -12,6 +13,12 @@ type DepositParams struct {
MaxDepositPeriod time.Duration `json:"max_deposit_period"` // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
}
func (dp DepositParams) String() string {
return fmt.Sprintf(`Deposit Params:
Min Deposit: %s
Max Deposit Period: %s`, dp.MinDeposit, dp.MaxDepositPeriod)
}
// Checks equality of DepositParams
func (dp DepositParams) Equal(dp2 DepositParams) bool {
return dp.MinDeposit.IsEqual(dp2.MinDeposit) && dp.MaxDepositPeriod == dp2.MaxDepositPeriod
@ -25,7 +32,41 @@ type TallyParams struct {
GovernancePenalty sdk.Dec `json:"governance_penalty"` // Penalty if validator does not vote
}
func (tp TallyParams) String() string {
return fmt.Sprintf(`Tally Params:
Quorum: %s
Threshold: %s
Veto: %s
Governance Penalty: %s`, tp.Quorum,
tp.Threshold, tp.Veto, tp.GovernancePenalty)
}
// Param around Voting in governance
type VotingParams struct {
VotingPeriod time.Duration `json:"voting_period"` // Length of the voting period.
}
func (vp VotingParams) String() string {
return fmt.Sprintf(`Voting Params:
Voting Period: %s`, vp.VotingPeriod)
}
// Params returns all of the governance params
type Params struct {
VotingParams VotingParams `json:"voting_params"`
TallyParams TallyParams `json:"tally_params"`
DepositParams DepositParams `json:"deposit_params"`
}
func (gp Params) String() string {
return gp.VotingParams.String() + "\n" +
gp.TallyParams.String() + "\n" + gp.DepositParams.String()
}
func NewParams(vp VotingParams, tp TallyParams, dp DepositParams) Params {
return Params{
VotingParams: vp,
DepositParams: dp,
TallyParams: tp,
}
}

View File

@ -3,6 +3,7 @@ package gov
import (
"encoding/json"
"fmt"
"strings"
"time"
"github.com/pkg/errors"
@ -45,6 +46,21 @@ type Proposal interface {
GetVotingEndTime() time.Time
SetVotingEndTime(time.Time)
String() string
}
// Proposals is an array of proposal
type Proposals []Proposal
func (p Proposals) String() string {
out := "ID - (Status) [Type] Title\n"
for _, prop := range p {
out += fmt.Sprintf("%d - (%s) [%s] %s\n",
prop.GetProposalID(), prop.GetStatus(),
prop.GetProposalType(), prop.GetTitle())
}
return strings.TrimSpace(out)
}
// checks if two proposals are equal
@ -119,6 +135,20 @@ func (tp *TextProposal) SetVotingEndTime(votingEndTime time.Time) {
tp.VotingEndTime = votingEndTime
}
func (tp TextProposal) String() string {
return fmt.Sprintf(`Proposal %d:
Title: %s
Type: %s
Status: %s
Submit Time: %s
Deposit End Time: %s
Total Deposit: %s
Voting Start Time: %s
Voting End Time: %s`, tp.ProposalID, tp.Title, tp.ProposalType,
tp.Status, tp.SubmitTime, tp.DepositEndTime,
tp.TotalDeposit, tp.VotingStartTime, tp.VotingEndTime)
}
//-----------------------------------------------------------
// ProposalQueue
type ProposalQueue []uint64
@ -343,9 +373,17 @@ func EmptyTallyResult() TallyResult {
}
// checks if two proposals are equal
func (resultA TallyResult) Equals(resultB TallyResult) bool {
return (resultA.Yes.Equal(resultB.Yes) &&
resultA.Abstain.Equal(resultB.Abstain) &&
resultA.No.Equal(resultB.No) &&
resultA.NoWithVeto.Equal(resultB.NoWithVeto))
func (tr TallyResult) Equals(comp TallyResult) bool {
return (tr.Yes.Equal(comp.Yes) &&
tr.Abstain.Equal(comp.Abstain) &&
tr.No.Equal(comp.No) &&
tr.NoWithVeto.Equal(comp.NoWithVeto))
}
func (tr TallyResult) String() string {
return fmt.Sprintf(`Tally Result:
Yes: %s
Abstain: %s
No: %s
NoWithVeto: %s`, tr.Yes, tr.Abstain, tr.No, tr.NoWithVeto)
}

View File

@ -4,8 +4,6 @@ import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec" // XXX fix
@ -15,67 +13,49 @@ import (
// GetCmdQuerySigningInfo implements the command to query signing info.
func GetCmdQuerySigningInfo(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "signing-info [validator-pubkey]",
Short: "Query a validator's signing information",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
pk, err := sdk.GetConsPubKeyBech32(args[0])
if err != nil {
return err
}
key := slashing.GetValidatorSigningInfoKey(sdk.ConsAddress(pk.Address()))
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
}
signingInfo := new(slashing.ValidatorSigningInfo)
var signingInfo slashing.ValidatorSigningInfo
cdc.MustUnmarshalBinaryLengthPrefixed(res, signingInfo)
switch viper.Get(cli.OutputFlag) {
case "text":
human := signingInfo.HumanReadableString()
fmt.Println(human)
case "json":
// parse out the signing info
output, err := codec.MarshalJSONIndent(cdc, signingInfo)
if err != nil {
return err
}
fmt.Println(string(output))
}
return nil
return cliCtx.PrintOutput(signingInfo)
},
}
return cmd
}
// GetCmdQueryParams implements a command to fetch slashing parameters.
func GetCmdQueryParams(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "params",
Short: "Query the current slashing parameters",
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
route := fmt.Sprintf("custom/%s/parameters", slashing.QuerierRoute)
route := fmt.Sprintf("custom/%s/parameters", slashing.QuerierRoute)
res, err := cliCtx.QueryWithData(route, nil)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
var params slashing.Params
cdc.MustUnmarshalJSON(res, &params)
return cliCtx.PrintOutput(params)
},
}
return cmd
}

View File

@ -1,6 +1,7 @@
package slashing
import (
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -42,6 +43,19 @@ type Params struct {
SlashFractionDowntime sdk.Dec `json:"slash-fraction-downtime"`
}
func (p Params) String() string {
return fmt.Sprintf(`Slashing Params:
MaxEvidenceAge: %s
SignedBlocksWindow: %d
MinSignedPerWindow: %s
DowntimeJailDuration: %s
SlashFractionDoubleSign: %d
SlashFractionDowntime: %d`, p.MaxEvidenceAge,
p.SignedBlocksWindow, p.MinSignedPerWindow,
p.DowntimeJailDuration, p.SlashFractionDoubleSign,
p.SlashFractionDowntime)
}
// Implements params.ParamStruct
func (p *Params) KeyValuePairs() params.KeyValuePairs {
return params.KeyValuePairs{

View File

@ -111,7 +111,12 @@ type ValidatorSigningInfo struct {
}
// Return human readable signing info
func (i ValidatorSigningInfo) HumanReadableString() string {
return fmt.Sprintf("Start height: %d, index offset: %d, jailed until: %v, missed blocks counter: %d",
i.StartHeight, i.IndexOffset, i.JailedUntil, i.MissedBlocksCounter)
func (i ValidatorSigningInfo) String() string {
return fmt.Sprintf(`Start Height: %d
Index Offset: %d
Jailed Until: %v
Tombstoned: %t
Missed Blocks Counter: %d`,
i.StartHeight, i.IndexOffset, i.JailedUntil,
i.Tombstoned, i.MissedBlocksCounter)
}

View File

@ -4,8 +4,6 @@ import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
@ -16,588 +14,376 @@ import (
// GetCmdQueryValidator implements the validator query command.
func GetCmdQueryValidator(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "validator [operator-addr]",
Short: "Query a validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
addr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetValidatorKey(addr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
res, err := cliCtx.QueryStore(staking.GetValidatorKey(addr), storeName)
if err != nil {
return err
} else if len(res) == 0 {
return fmt.Errorf("No validator found with address %s", args[0])
}
validator := types.MustUnmarshalValidator(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
human, err := validator.HumanReadableString()
if err != nil {
return err
}
fmt.Println(human)
case "json":
// parse out the validator
output, err := codec.MarshalJSONIndent(cdc, validator)
if err != nil {
return err
}
fmt.Println(string(output))
}
// TODO: output with proofs / machine parseable etc.
return nil
return cliCtx.PrintOutput(types.MustUnmarshalValidator(cdc, res))
},
}
return cmd
}
// GetCmdQueryValidators implements the query all validators command.
func GetCmdQueryValidators(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "validators",
Short: "Query for all validators",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
key := staking.ValidatorsKey
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
resKVs, err := cliCtx.QuerySubspace(staking.ValidatorsKey, storeName)
if err != nil {
return err
}
// parse out the validators
var validators []staking.Validator
var validators staking.Validators
for _, kv := range resKVs {
validator := types.MustUnmarshalValidator(cdc, kv.Value)
validators = append(validators, validator)
validators = append(validators, types.MustUnmarshalValidator(cdc, kv.Value))
}
switch viper.Get(cli.OutputFlag) {
case "text":
for _, validator := range validators {
resp, err := validator.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
}
case "json":
output, err := codec.MarshalJSONIndent(cdc, validators)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
// TODO: output with proofs / machine parseable etc.
return nil
return cliCtx.PrintOutput(validators)
},
}
return cmd
}
// GetCmdQueryValidatorUnbondingDelegations implements the query all unbonding delegatations from a validator command.
func GetCmdQueryValidatorUnbondingDelegations(storeKey string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "unbonding-delegations-from [operator-addr]",
Short: "Query all unbonding delegatations from a validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
valAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
params := staking.NewQueryValidatorParams(valAddr)
bz, err := cdc.MarshalJSON(params)
bz, err := cdc.MarshalJSON(staking.NewQueryValidatorParams(valAddr))
if err != nil {
return err
}
res, err := cliCtx.QueryWithData(
fmt.Sprintf("custom/%s/validatorUnbondingDelegations", storeKey),
bz)
route := fmt.Sprintf("custom/%s/%s", storeKey, staking.QueryValidatorUnbondingDelegations)
res, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
var ubds staking.UnbondingDelegations
cdc.MustUnmarshalJSON(res, &ubds)
return cliCtx.PrintOutput(ubds)
},
}
return cmd
}
// GetCmdQueryValidatorRedelegations implements the query all redelegatations from a validator command.
func GetCmdQueryValidatorRedelegations(storeKey string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "redelegations-from [operator-addr]",
Short: "Query all outgoing redelegatations from a validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
valAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
params := staking.NewQueryValidatorParams(valAddr)
bz, err := cdc.MarshalJSON(params)
bz, err := cdc.MarshalJSON(staking.NewQueryValidatorParams(valAddr))
if err != nil {
return err
}
res, err := cliCtx.QueryWithData(
fmt.Sprintf("custom/%s/validatorRedelegations", storeKey),
bz)
route := fmt.Sprintf("custom/%s/%s", storeKey, staking.QueryValidatorRedelegations)
res, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
var reds staking.Redelegations
cdc.MustUnmarshalJSON(res, &reds)
return cliCtx.PrintOutput(reds)
},
}
return cmd
}
// GetCmdQueryDelegation the query delegation command.
func GetCmdQueryDelegation(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "delegation",
return &cobra.Command{
Use: "delegation [delegator-addr] [validator-addr]",
Short: "Query a delegation based on address and validator address",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
valAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidator))
if err != nil {
return err
}
delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator))
if err != nil {
return err
}
key := staking.GetDelegationKey(delAddr, valAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
valAddr, err := sdk.ValAddressFromBech32(args[1])
if err != nil {
return err
}
delAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
res, err := cliCtx.QueryStore(staking.GetDelegationKey(delAddr, valAddr), storeName)
if err != nil {
return err
}
// parse out the delegation
delegation, err := types.UnmarshalDelegation(cdc, res)
if err != nil {
return err
}
switch viper.Get(cli.OutputFlag) {
case "text":
resp, err := delegation.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
case "json":
output, err := codec.MarshalJSONIndent(cdc, delegation)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
return nil
return cliCtx.PrintOutput(delegation)
},
}
cmd.Flags().AddFlagSet(fsValidator)
cmd.Flags().AddFlagSet(fsDelegator)
return cmd
}
// GetCmdQueryDelegations implements the command to query all the delegations
// made from one delegator.
func GetCmdQueryDelegations(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "delegations [delegator-addr]",
Short: "Query all delegations made from one delegator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
delegatorAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetDelegationsKey(delegatorAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
resKVs, err := cliCtx.QuerySubspace(staking.GetDelegationsKey(delegatorAddr), storeName)
if err != nil {
return err
}
// parse out the validators
var delegations []staking.Delegation
var delegations staking.Delegations
for _, kv := range resKVs {
delegation := types.MustUnmarshalDelegation(cdc, kv.Value)
delegations = append(delegations, delegation)
delegations = append(delegations, types.MustUnmarshalDelegation(cdc, kv.Value))
}
output, err := codec.MarshalJSONIndent(cdc, delegations)
if err != nil {
return err
}
fmt.Println(string(output))
// TODO: output with proofs / machine parseable etc.
return nil
return cliCtx.PrintOutput(delegations)
},
}
return cmd
}
// GetCmdQueryValidatorDelegations implements the command to query all the
// delegations to a specific validator.
func GetCmdQueryValidatorDelegations(storeKey string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "delegations-to [validator-addr]",
Short: "Query all delegations made to one validator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
validatorAddr, err := sdk.ValAddressFromBech32(args[0])
if err != nil {
return err
}
params := staking.NewQueryValidatorParams(validatorAddr)
bz, err := cdc.MarshalJSON(params)
bz, err := cdc.MarshalJSON(staking.NewQueryValidatorParams(validatorAddr))
if err != nil {
return err
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/validatorDelegations", storeKey), bz)
route := fmt.Sprintf("custom/%s/%s", storeKey, staking.QueryValidatorDelegations)
res, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
fmt.Println(string(res))
return nil
var dels staking.Delegations
cdc.MustUnmarshalJSON(res, &dels)
return cliCtx.PrintOutput(dels)
},
}
return cmd
}
// GetCmdQueryUnbondingDelegation implements the command to query a single
// unbonding-delegation record.
func GetCmdQueryUnbondingDelegation(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unbonding-delegation",
return &cobra.Command{
Use: "unbonding-delegation [delegator-addr] [validator-addr]",
Short: "Query an unbonding-delegation record based on delegator and validator address",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
valAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidator))
if err != nil {
return err
}
delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator))
if err != nil {
return err
}
key := staking.GetUBDKey(delAddr, valAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
valAddr, err := sdk.ValAddressFromBech32(args[1])
if err != nil {
return err
}
// parse out the unbonding delegation
ubd := types.MustUnmarshalUBD(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
resp, err := ubd.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
case "json":
output, err := codec.MarshalJSONIndent(cdc, ubd)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
delAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
return nil
res, err := cliCtx.QueryStore(staking.GetUBDKey(delAddr, valAddr), storeName)
if err != nil {
return err
}
return cliCtx.PrintOutput(types.MustUnmarshalUBD(cdc, res))
},
}
cmd.Flags().AddFlagSet(fsValidator)
cmd.Flags().AddFlagSet(fsDelegator)
return cmd
}
// GetCmdQueryUnbondingDelegations implements the command to query all the
// unbonding-delegation records for a delegator.
func GetCmdQueryUnbondingDelegations(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "unbonding-delegations [delegator-addr]",
Short: "Query all unbonding-delegations records for one delegator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
delegatorAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetUBDsKey(delegatorAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
resKVs, err := cliCtx.QuerySubspace(staking.GetUBDsKey(delegatorAddr), storeName)
if err != nil {
return err
}
// parse out the unbonding delegations
var ubds []staking.UnbondingDelegation
var ubds staking.UnbondingDelegations
for _, kv := range resKVs {
ubd := types.MustUnmarshalUBD(cdc, kv.Value)
ubds = append(ubds, ubd)
ubds = append(ubds, types.MustUnmarshalUBD(cdc, kv.Value))
}
output, err := codec.MarshalJSONIndent(cdc, ubds)
if err != nil {
return err
}
fmt.Println(string(output))
// TODO: output with proofs / machine parseable etc.
return nil
return cliCtx.PrintOutput(ubds)
},
}
return cmd
}
// GetCmdQueryRedelegation implements the command to query a single
// redelegation record.
func GetCmdQueryRedelegation(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "redelegation",
return &cobra.Command{
Use: "redelegation [delegator-addr] [validator-src-addr] [validator-dst-addr]",
Short: "Query a redelegation record based on delegator and a source and destination validator address",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
valSrcAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidatorSrc))
if err != nil {
return err
}
valDstAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidatorDst))
if err != nil {
return err
}
delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator))
if err != nil {
return err
}
key := staking.GetREDKey(delAddr, valSrcAddr, valDstAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
valSrcAddr, err := sdk.ValAddressFromBech32(args[1])
if err != nil {
return err
}
// parse out the unbonding delegation
red := types.MustUnmarshalRED(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
resp, err := red.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
case "json":
output, err := codec.MarshalJSONIndent(cdc, red)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
valDstAddr, err := sdk.ValAddressFromBech32(args[2])
if err != nil {
return err
}
return nil
delAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
res, err := cliCtx.QueryStore(staking.GetREDKey(delAddr, valSrcAddr, valDstAddr), storeName)
if err != nil {
return err
}
return cliCtx.PrintOutput(types.MustUnmarshalRED(cdc, res))
},
}
cmd.Flags().AddFlagSet(fsRedelegation)
cmd.Flags().AddFlagSet(fsDelegator)
return cmd
}
// GetCmdQueryRedelegations implements the command to query all the
// redelegation records for a delegator.
func GetCmdQueryRedelegations(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "redelegations [delegator-addr]",
Short: "Query all redelegations records for one delegator",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
delegatorAddr, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
key := staking.GetREDsKey(delegatorAddr)
cliCtx := context.NewCLIContext().WithCodec(cdc)
resKVs, err := cliCtx.QuerySubspace(key, storeName)
resKVs, err := cliCtx.QuerySubspace(staking.GetREDsKey(delegatorAddr), storeName)
if err != nil {
return err
}
// parse out the validators
var reds []staking.Redelegation
var reds staking.Redelegations
for _, kv := range resKVs {
red := types.MustUnmarshalRED(cdc, kv.Value)
reds = append(reds, red)
reds = append(reds, types.MustUnmarshalRED(cdc, kv.Value))
}
output, err := codec.MarshalJSONIndent(cdc, reds)
if err != nil {
return err
}
fmt.Println(string(output))
// TODO: output with proofs / machine parseable etc.
return nil
return cliCtx.PrintOutput(reds)
},
}
return cmd
}
// GetCmdQueryPool implements the pool query command.
func GetCmdQueryPool(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
return &cobra.Command{
Use: "pool",
Short: "Query the current staking pool values",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
key := staking.PoolKey
cliCtx := context.NewCLIContext().WithCodec(cdc)
res, err := cliCtx.QueryStore(key, storeName)
res, err := cliCtx.QueryStore(staking.PoolKey, storeName)
if err != nil {
return err
}
pool := types.MustUnmarshalPool(cdc, res)
switch viper.Get(cli.OutputFlag) {
case "text":
human := pool.HumanReadableString()
fmt.Println(human)
case "json":
// parse out the pool
output, err := codec.MarshalJSONIndent(cdc, pool)
if err != nil {
return err
}
fmt.Println(string(output))
}
return nil
return cliCtx.PrintOutput(types.MustUnmarshalPool(cdc, res))
},
}
return cmd
}
// GetCmdQueryPool implements the params query command.
func GetCmdQueryParams(storeName string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "parameters",
return &cobra.Command{
Use: "params",
Short: "Query the current staking parameters information",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
bz, err := cliCtx.QueryWithData("custom/staking/"+staking.QueryParameters, nil)
route := fmt.Sprintf("custom/%s/%s", storeName, staking.QueryParameters)
bz, err := cliCtx.QueryWithData(route, nil)
if err != nil {
return err
}
var params staking.Params
err = cdc.UnmarshalJSON(bz, &params)
if err != nil {
return err
}
switch viper.Get(cli.OutputFlag) {
case "text":
human := params.HumanReadableString()
fmt.Println(human)
case "json":
// parse out the params
output, err := codec.MarshalJSONIndent(cdc, params)
if err != nil {
return err
}
fmt.Println(string(output))
}
return nil
cdc.MustUnmarshalJSON(bz, &params)
return cliCtx.PrintOutput(params)
},
}
return cmd
}

View File

@ -17,6 +17,7 @@ const (
QueryDelegatorUnbondingDelegations = "delegatorUnbondingDelegations"
QueryRedelegations = "redelegations"
QueryValidatorDelegations = "validatorDelegations"
QueryValidatorRedelegations = "validatorRedelegations"
QueryValidatorUnbondingDelegations = "validatorUnbondingDelegations"
QueryDelegator = "delegator"
QueryDelegation = "delegation"

View File

@ -11,11 +11,15 @@ import (
type (
Keeper = keeper.Keeper
Validator = types.Validator
Validators = types.Validators
Description = types.Description
Commission = types.Commission
Delegation = types.Delegation
Delegations = types.Delegations
UnbondingDelegation = types.UnbondingDelegation
UnbondingDelegations = types.UnbondingDelegations
Redelegation = types.Redelegation
Redelegations = types.Redelegations
Params = types.Params
Pool = types.Pool
MsgCreateValidator = types.MsgCreateValidator
@ -94,6 +98,8 @@ var (
const (
QueryValidators = querier.QueryValidators
QueryValidator = querier.QueryValidator
QueryValidatorDelegations = querier.QueryValidatorDelegations
QueryValidatorRedelegations = querier.QueryValidatorRedelegations
QueryValidatorUnbondingDelegations = querier.QueryValidatorUnbondingDelegations
QueryDelegation = querier.QueryDelegation
QueryUnbondingDelegation = querier.QueryUnbondingDelegation

View File

@ -3,6 +3,7 @@ package types
import (
"bytes"
"fmt"
"strings"
"time"
"github.com/cosmos/cosmos-sdk/codec"
@ -83,16 +84,23 @@ func (d Delegation) GetDelegatorAddr() sdk.AccAddress { return d.DelegatorAddr }
func (d Delegation) GetValidatorAddr() sdk.ValAddress { return d.ValidatorAddr }
func (d Delegation) GetShares() sdk.Dec { return d.Shares }
// HumanReadableString returns a human readable string representation of a
// Delegation. An error is returned if the Delegation's delegator or validator
// addresses cannot be Bech32 encoded.
func (d Delegation) HumanReadableString() (string, error) {
resp := "Delegation \n"
resp += fmt.Sprintf("Delegator: %s\n", d.DelegatorAddr)
resp += fmt.Sprintf("Validator: %s\n", d.ValidatorAddr)
resp += fmt.Sprintf("Shares: %s\n", d.Shares.String())
// String returns a human readable string representation of a Delegation.
func (d Delegation) String() string {
return fmt.Sprintf(`Delegation:
Delegator: %s
Validator: %s
Shares: %s`, d.DelegatorAddr,
d.ValidatorAddr, d.Shares)
}
return resp, nil
// Delegations is a collection of delegations
type Delegations []Delegation
func (d Delegations) String() (out string) {
for _, del := range d {
out += del.String() + "\n"
}
return strings.TrimSpace(out)
}
//________________________________________________________________________
@ -183,21 +191,30 @@ func (d UnbondingDelegation) Equal(d2 UnbondingDelegation) bool {
return bytes.Equal(bz1, bz2)
}
// HumanReadableString returns a human readable string representation of an
// UnbondingDelegation. An error is returned if the UnbondingDelegation's
// delegator or validator addresses cannot be Bech32 encoded.
func (d UnbondingDelegation) HumanReadableString() (string, error) {
resp := "Unbonding Delegation \n"
resp += fmt.Sprintf("Delegator: %s\n", d.DelegatorAddr)
resp += fmt.Sprintf("Validator: %s\n", d.ValidatorAddr)
for _, entry := range d.Entries {
resp += "Unbonding Delegation Entry\n"
resp += fmt.Sprintf("Creation height: %v\n", entry.CreationHeight)
resp += fmt.Sprintf("Min time to unbond (unix): %v\n", entry.CompletionTime)
resp += fmt.Sprintf("Expected balance: %s", entry.Balance.String())
// String returns a human readable string representation of an UnbondingDelegation.
func (d UnbondingDelegation) String() string {
out := fmt.Sprintf(`Unbonding Delegations between:
Delegator: %s
Validator: %s
Entries:`, d.DelegatorAddr, d.ValidatorAddr)
for i, entry := range d.Entries {
out += fmt.Sprintf(` Unbonding Delegation %d:
Creation Height: %v
Min time to unbond (unix): %v
Expected balance: %s`, i, entry.CreationHeight,
entry.CompletionTime, entry.Balance)
}
return out
}
return resp, nil
// UnbondingDelegations is a collection of UnbondingDelegation
type UnbondingDelegations []UnbondingDelegation
func (ubds UnbondingDelegations) String() (out string) {
for _, u := range ubds {
out += u.String() + "\n"
}
return strings.TrimSpace(out)
}
// Redelegation reflects a delegation's passive re-delegation queue.
@ -296,19 +313,30 @@ func (d Redelegation) Equal(d2 Redelegation) bool {
return bytes.Equal(bz1, bz2)
}
// HumanReadableString returns a human readable string representation of a
// Redelegation. An error is returned if the UnbondingDelegation's delegator or
// validator addresses cannot be Bech32 encoded.
func (d Redelegation) HumanReadableString() (string, error) {
resp := "Redelegation \n"
resp += fmt.Sprintf("Delegator: %s\n", d.DelegatorAddr)
resp += fmt.Sprintf("Source Validator: %s\n", d.ValidatorSrcAddr)
resp += fmt.Sprintf("Destination Validator: %s\n", d.ValidatorDstAddr)
for _, entry := range d.Entries {
resp += fmt.Sprintf("Creation height: %v\n", entry.CreationHeight)
resp += fmt.Sprintf("Min time to unbond (unix): %v\n", entry.CompletionTime)
resp += fmt.Sprintf("Source shares: %s\n", entry.SharesSrc.String())
resp += fmt.Sprintf("Destination shares: %s", entry.SharesDst.String())
// String returns a human readable string representation of a Redelegation.
func (d Redelegation) String() string {
out := fmt.Sprintf(`Redelegations between:
Delegator: %s
Source Validator: %s
Destination Validator: %s
Entries:`, d.DelegatorAddr, d.ValidatorSrcAddr, d.ValidatorDstAddr)
for i, entry := range d.Entries {
out += fmt.Sprintf(` Redelegation %d:
Creation height: %v
Min time to unbond (unix): %v
Source shares: %s
Dest Shares: %s`, i, entry.CreationHeight,
entry.CompletionTime, entry.SharesSrc, entry.SharesDst)
}
return resp, nil
return out
}
// Redelegations are a collection of Redelegation
type Redelegations []Redelegation
func (d Redelegations) String() (out string) {
for _, red := range d {
out += red.String() + "\n"
}
return strings.TrimSpace(out)
}

View File

@ -23,14 +23,9 @@ func TestDelegationEqual(t *testing.T) {
require.False(t, ok)
}
func TestDelegationHumanReadableString(t *testing.T) {
func TestDelegationString(t *testing.T) {
d := NewDelegation(sdk.AccAddress(addr1), addr2, sdk.NewDec(100))
// NOTE: Being that the validator's keypair is random, we cannot test the
// actual contents of the string.
valStr, err := d.HumanReadableString()
require.Nil(t, err)
require.NotEmpty(t, valStr)
require.NotEmpty(t, d.String())
}
func TestUnbondingDelegationEqual(t *testing.T) {
@ -48,15 +43,11 @@ func TestUnbondingDelegationEqual(t *testing.T) {
require.False(t, ok)
}
func TestUnbondingDelegationHumanReadableString(t *testing.T) {
func TestUnbondingDelegationString(t *testing.T) {
ubd := NewUnbondingDelegation(sdk.AccAddress(addr1), addr2, 0,
time.Unix(0, 0), sdk.NewInt64Coin(DefaultBondDenom, 0))
// NOTE: Being that the validator's keypair is random, we cannot test the
// actual contents of the string.
valStr, err := ubd.HumanReadableString()
require.Nil(t, err)
require.NotEmpty(t, valStr)
require.NotEmpty(t, ubd.String())
}
func TestRedelegationEqual(t *testing.T) {
@ -78,14 +69,10 @@ func TestRedelegationEqual(t *testing.T) {
require.False(t, ok)
}
func TestRedelegationHumanReadableString(t *testing.T) {
func TestRedelegationString(t *testing.T) {
r := NewRedelegation(sdk.AccAddress(addr1), addr2, addr3, 0,
time.Unix(0, 0), sdk.NewInt64Coin(DefaultBondDenom, 0),
sdk.NewDec(10), sdk.NewDec(20))
// NOTE: Being that the validator's keypair is random, we cannot test the
// actual contents of the string.
valStr, err := r.HumanReadableString()
require.Nil(t, err)
require.NotEmpty(t, valStr)
require.NotEmpty(t, r.String())
}

View File

@ -65,15 +65,13 @@ func DefaultParams() Params {
}
}
// HumanReadableString returns a human readable string representation of the
// parameters.
func (p Params) HumanReadableString() string {
resp := "Params \n"
resp += fmt.Sprintf("Unbonding Time: %s\n", p.UnbondingTime)
resp += fmt.Sprintf("Max Validators: %d\n", p.MaxValidators)
resp += fmt.Sprintf("Bonded Coin Denomination: %s\n", p.BondDenom)
return resp
// String returns a human readable string representation of the parameters.
func (p Params) String() string {
return fmt.Sprintf(`Params:
Unbonding Time: %s)
Max Validators: %d)
Bonded Coin Denomination: %s`, p.UnbondingTime,
p.MaxValidators, p.BondDenom)
}
// unmarshal the current staking params value from store key or panic

View File

@ -10,8 +10,8 @@ import (
// Pool - dynamic parameters of the current state
type Pool struct {
NotBondedTokens sdk.Int `json:"not_bonded_tokens"` // tokens which are not bonded in a validator
BondedTokens sdk.Int `json:"bonded_tokens"` // reserve of bonded tokens
NotBondedTokens sdk.Int `json:"not_bonded_tokens"` // tokens which are not bonded in a validator
BondedTokens sdk.Int `json:"bonded_tokens"` // reserve of bonded tokens
}
// nolint
@ -24,8 +24,8 @@ func (p Pool) Equal(p2 Pool) bool {
// initial pool for testing
func InitialPool() Pool {
return Pool{
NotBondedTokens: sdk.ZeroInt(),
BondedTokens: sdk.ZeroInt(),
NotBondedTokens: sdk.ZeroInt(),
BondedTokens: sdk.ZeroInt(),
}
}
@ -68,16 +68,15 @@ func (p Pool) bondedTokensToNotBonded(bondedTokens sdk.Int) Pool {
return p
}
// HumanReadableString returns a human readable string representation of a
// pool.
func (p Pool) HumanReadableString() string {
resp := "Pool \n"
resp += fmt.Sprintf("Not-Bonded Tokens: %s\n", p.NotBondedTokens)
resp += fmt.Sprintf("Bonded Tokens: %s\n", p.BondedTokens)
resp += fmt.Sprintf("Token Supply: %s\n", p.TokenSupply())
resp += fmt.Sprintf("Bonded Ratio: %v\n", p.BondedRatio())
return resp
// String returns a human readable string representation of a pool.
func (p Pool) String() string {
return fmt.Sprintf(`Pool:
Loose Tokens: %s
Bonded Tokens: %s
Token Supply: %s
Bonded Ratio: %v`, p.NotBondedTokens,
p.BondedTokens, p.TokenSupply(),
p.BondedRatio())
}
// unmarshal the current pool value from store key or panics

View File

@ -3,6 +3,7 @@ package types
import (
"bytes"
"fmt"
"strings"
"time"
abci "github.com/tendermint/tendermint/abci/types"
@ -38,6 +39,16 @@ type Validator struct {
Commission Commission `json:"commission"` // commission parameters
}
// Validators is a collection of Validator
type Validators []Validator
func (v Validators) String() (out string) {
for _, val := range v {
out += val.String() + "\n"
}
return strings.TrimSpace(out)
}
// NewValidator - initialize a new validator
func NewValidator(operator sdk.ValAddress, pubKey crypto.PubKey, description Description) Validator {
return Validator{
@ -75,29 +86,27 @@ func UnmarshalValidator(cdc *codec.Codec, value []byte) (validator Validator, er
return validator, err
}
// HumanReadableString returns a human readable string representation of a
// validator. An error is returned if the operator or the operator's public key
// cannot be converted to Bech32 format.
func (v Validator) HumanReadableString() (string, error) {
// String returns a human readable string representation of a validator.
func (v Validator) String() string {
bechConsPubKey, err := sdk.Bech32ifyConsPub(v.ConsPubKey)
if err != nil {
return "", err
panic(err)
}
resp := "Validator \n"
resp += fmt.Sprintf("Operator Address: %s\n", v.OperatorAddr)
resp += fmt.Sprintf("Validator Consensus Pubkey: %s\n", bechConsPubKey)
resp += fmt.Sprintf("Jailed: %v\n", v.Jailed)
resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status))
resp += fmt.Sprintf("Tokens: %s\n", v.Tokens)
resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.String())
resp += fmt.Sprintf("Description: %s\n", v.Description)
resp += fmt.Sprintf("Bond Height: %d\n", v.BondHeight)
resp += fmt.Sprintf("Unbonding Height: %d\n", v.UnbondingHeight)
resp += fmt.Sprintf("Minimum Unbonding Time: %v\n", v.UnbondingCompletionTime)
resp += fmt.Sprintf("Commission: {%s}\n", v.Commission)
return resp, nil
return fmt.Sprintf(`Validator
Operator Address: %s
Validator Consensus Pubkey: %s
Jailed: %v
Status: %s
Tokens: %s
Delegator Shares: %s
Description: %s
Bond Height: %d
Unbonding Height: %d
Unbonding Completion Time: %v
Commission: %s`, v.OperatorAddr, bechConsPubKey,
v.Jailed, sdk.BondStatusToString(v.Status), v.Tokens,
v.DelegatorShares, v.Description, v.BondHeight,
v.UnbondingHeight, v.UnbondingCompletionTime, v.Commission)
}
//___________________________________________________________________

View File

@ -245,16 +245,6 @@ func TestPossibleOverflow(t *testing.T) {
msg, newValidator.DelegatorShareExRate())
}
func TestHumanReadableString(t *testing.T) {
validator := NewValidator(addr1, pk1, Description{})
// NOTE: Being that the validator's keypair is random, we cannot test the
// actual contents of the string.
valStr, err := validator.HumanReadableString()
require.Nil(t, err)
require.NotEmpty(t, valStr)
}
func TestValidatorMarshalUnmarshalJSON(t *testing.T) {
validator := NewValidator(addr1, pk1, Description{})
js, err := codec.Cdc.MarshalJSON(validator)