2018-09-04 23:41:17 -07:00
// nolint
package cli
import (
2019-11-14 06:17:21 -08:00
"bufio"
2019-05-18 16:06:08 -07:00
"fmt"
2019-02-06 16:15:37 -08:00
"strings"
2018-09-04 23:41:17 -07:00
2018-09-19 16:00:21 -07:00
"github.com/spf13/cobra"
"github.com/spf13/viper"
2018-11-19 09:02:34 -08:00
"github.com/cosmos/cosmos-sdk/client"
2018-09-04 23:41:17 -07:00
"github.com/cosmos/cosmos-sdk/client/context"
2018-09-19 16:00:21 -07:00
"github.com/cosmos/cosmos-sdk/codec"
2018-09-04 23:41:17 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
2019-05-18 16:06:08 -07:00
"github.com/cosmos/cosmos-sdk/version"
2019-06-15 05:34:11 -07:00
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
"github.com/cosmos/cosmos-sdk/x/gov"
2018-09-19 21:53:48 -07:00
2019-02-04 16:45:18 -08:00
"github.com/cosmos/cosmos-sdk/x/distribution/client/common"
2018-09-19 21:53:48 -07:00
"github.com/cosmos/cosmos-sdk/x/distribution/types"
2018-09-04 23:41:17 -07:00
)
var (
flagOnlyFromValidator = "only-from-validator"
flagIsValidator = "is-validator"
2019-11-13 01:20:13 -08:00
flagCommission = "commission"
2019-05-23 16:00:26 -07:00
flagMaxMessagesPerTx = "max-msgs"
)
const (
MaxMessagesPerTxDefault = 5
2018-09-04 23:41:17 -07:00
)
2018-11-19 09:02:34 -08:00
// GetTxCmd returns the transaction commands for this module
2019-06-05 16:26:17 -07:00
func GetTxCmd ( storeKey string , cdc * codec . Codec ) * cobra . Command {
2018-11-19 09:02:34 -08:00
distTxCmd := & cobra . Command {
2019-06-05 16:26:17 -07:00
Use : types . ModuleName ,
Short : "Distribution transactions subcommands" ,
DisableFlagParsing : true ,
SuggestionsMinimumDistance : 2 ,
2019-06-15 05:34:11 -07:00
RunE : client . ValidateCmd ,
2018-11-19 09:02:34 -08:00
}
distTxCmd . AddCommand ( client . PostCommands (
GetCmdWithdrawRewards ( cdc ) ,
GetCmdSetWithdrawAddr ( cdc ) ,
2019-06-05 16:26:17 -07:00
GetCmdWithdrawAllRewards ( cdc , storeKey ) ,
2019-12-10 11:09:22 -08:00
GetCmdFundCommunityPool ( cdc ) ,
2018-11-19 09:02:34 -08:00
) ... )
return distTxCmd
}
2019-06-05 16:26:17 -07:00
type generateOrBroadcastFunc func ( context . CLIContext , auth . TxBuilder , [ ] sdk . Msg ) error
2019-05-23 16:00:26 -07:00
func splitAndApply (
generateOrBroadcast generateOrBroadcastFunc ,
cliCtx context . CLIContext ,
2019-06-05 16:26:17 -07:00
txBldr auth . TxBuilder ,
2019-05-23 16:00:26 -07:00
msgs [ ] sdk . Msg ,
chunkSize int ,
) error {
if chunkSize == 0 {
return generateOrBroadcast ( cliCtx , txBldr , msgs )
}
// split messages into slices of length chunkSize
totalMessages := len ( msgs )
for i := 0 ; i < len ( msgs ) ; i += chunkSize {
sliceEnd := i + chunkSize
if sliceEnd > totalMessages {
sliceEnd = totalMessages
}
msgChunk := msgs [ i : sliceEnd ]
if err := generateOrBroadcast ( cliCtx , txBldr , msgChunk ) ; err != nil {
return err
}
}
return nil
}
2018-09-18 21:00:48 -07:00
// command to withdraw rewards
2018-09-19 21:53:48 -07:00
func GetCmdWithdrawRewards ( cdc * codec . Codec ) * cobra . Command {
2018-09-04 23:41:17 -07:00
cmd := & cobra . Command {
2019-02-06 16:15:37 -08:00
Use : "withdraw-rewards [validator-addr]" ,
2019-05-18 16:06:08 -07:00
Short : "Withdraw rewards from a given delegation address, and optionally withdraw validator commission if the delegation address given is a validator operator" ,
Long : strings . TrimSpace (
fmt . Sprintf ( ` Withdraw rewards from a given delegation address ,
and optionally withdraw validator commission if the delegation address given is a validator operator .
Example :
$ % s tx distr withdraw - rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj -- from mykey
$ % s tx distr withdraw - rewards cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj -- from mykey -- commission
` ,
version . ClientName , version . ClientName ,
) ,
) ,
2019-02-06 16:15:37 -08:00
Args : cobra . ExactArgs ( 1 ) ,
2018-09-04 23:41:17 -07:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2019-11-14 06:17:21 -08:00
inBuf := bufio . NewReader ( cmd . InOrStdin ( ) )
txBldr := auth . NewTxBuilderFromCLI ( inBuf ) . WithTxEncoder ( utils . GetTxEncoder ( cdc ) )
cliCtx := context . NewCLIContextWithInput ( inBuf ) . WithCodec ( cdc )
2018-09-04 23:41:17 -07:00
2019-02-06 16:15:37 -08:00
delAddr := cliCtx . GetFromAddress ( )
valAddr , err := sdk . ValAddressFromBech32 ( args [ 0 ] )
if err != nil {
return err
2018-09-04 23:41:17 -07:00
}
2019-02-06 16:15:37 -08:00
msgs := [ ] sdk . Msg { types . NewMsgWithdrawDelegatorReward ( delAddr , valAddr ) }
2019-11-13 01:20:13 -08:00
if viper . GetBool ( flagCommission ) {
2019-02-06 16:15:37 -08:00
msgs = append ( msgs , types . NewMsgWithdrawValidatorCommission ( valAddr ) )
2018-12-10 07:29:10 -08:00
}
2019-05-08 13:06:05 -07:00
return utils . GenerateOrBroadcastMsgs ( cliCtx , txBldr , msgs )
2018-09-18 21:00:48 -07:00
} ,
}
2019-11-13 01:20:13 -08:00
cmd . Flags ( ) . Bool ( flagCommission , false , "also withdraw validator's commission" )
2018-09-18 21:00:48 -07:00
return cmd
}
2019-02-04 16:45:18 -08:00
// command to withdraw all rewards
func GetCmdWithdrawAllRewards ( cdc * codec . Codec , queryRoute string ) * cobra . Command {
2019-05-23 16:00:26 -07:00
cmd := & cobra . Command {
2019-02-06 16:15:37 -08:00
Use : "withdraw-all-rewards" ,
2019-02-04 16:45:18 -08:00
Short : "withdraw all delegations rewards for a delegator" ,
2019-05-18 16:06:08 -07:00
Long : strings . TrimSpace (
fmt . Sprintf ( ` Withdraw all rewards for a single delegator .
Example :
$ % s tx distr withdraw - all - rewards -- from mykey
` ,
version . ClientName ,
) ,
) ,
2019-02-06 16:15:37 -08:00
Args : cobra . NoArgs ,
2019-02-04 16:45:18 -08:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2019-11-14 06:17:21 -08:00
inBuf := bufio . NewReader ( cmd . InOrStdin ( ) )
txBldr := auth . NewTxBuilderFromCLI ( inBuf ) . WithTxEncoder ( utils . GetTxEncoder ( cdc ) )
cliCtx := context . NewCLIContextWithInput ( inBuf ) . WithCodec ( cdc )
2019-02-04 16:45:18 -08:00
delAddr := cliCtx . GetFromAddress ( )
2019-08-08 08:51:54 -07:00
// The transaction cannot be generated offline since it requires a query
// to get all the validators.
if cliCtx . GenerateOnly {
return fmt . Errorf ( "command disabled with the provided flag: %s" , client . FlagGenerateOnly )
}
2019-06-06 08:43:15 -07:00
msgs , err := common . WithdrawAllDelegatorRewards ( cliCtx , queryRoute , delAddr )
2019-02-04 16:45:18 -08:00
if err != nil {
return err
}
2019-05-23 16:00:26 -07:00
chunkSize := viper . GetInt ( flagMaxMessagesPerTx )
return splitAndApply ( utils . GenerateOrBroadcastMsgs , cliCtx , txBldr , msgs , chunkSize )
2019-02-04 16:45:18 -08:00
} ,
}
2019-08-08 08:51:54 -07:00
2019-05-23 16:00:26 -07:00
cmd . Flags ( ) . Int ( flagMaxMessagesPerTx , MaxMessagesPerTxDefault , "Limit the number of messages per tx (0 for unlimited)" )
return cmd
2019-02-04 16:45:18 -08:00
}
// command to replace a delegator's withdrawal address
2018-09-19 16:00:21 -07:00
func GetCmdSetWithdrawAddr ( cdc * codec . Codec ) * cobra . Command {
2019-05-23 16:00:26 -07:00
return & cobra . Command {
2018-09-18 21:00:48 -07:00
Use : "set-withdraw-addr [withdraw-addr]" ,
Short : "change the default withdraw address for rewards associated with an address" ,
2019-05-18 16:06:08 -07:00
Long : strings . TrimSpace (
fmt . Sprintf ( ` Set the withdraw address for rewards associated with a delegator address .
Example :
$ % s tx set - withdraw - addr cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p -- from mykey
` ,
version . ClientName ,
) ,
) ,
2019-02-06 16:15:37 -08:00
Args : cobra . ExactArgs ( 1 ) ,
2018-09-18 21:00:48 -07:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2019-11-14 06:17:21 -08:00
inBuf := bufio . NewReader ( cmd . InOrStdin ( ) )
txBldr := auth . NewTxBuilderFromCLI ( inBuf ) . WithTxEncoder ( utils . GetTxEncoder ( cdc ) )
cliCtx := context . NewCLIContextWithInput ( inBuf ) . WithCodec ( cdc )
2018-09-18 21:00:48 -07:00
2019-01-29 11:22:47 -08:00
delAddr := cliCtx . GetFromAddress ( )
2018-09-18 21:00:48 -07:00
withdrawAddr , err := sdk . AccAddressFromBech32 ( args [ 0 ] )
2018-09-04 23:41:17 -07:00
if err != nil {
return err
}
2018-09-19 21:53:48 -07:00
msg := types . NewMsgSetWithdrawAddress ( delAddr , withdrawAddr )
2019-05-08 13:06:05 -07:00
return utils . GenerateOrBroadcastMsgs ( cliCtx , txBldr , [ ] sdk . Msg { msg } )
2018-09-04 23:41:17 -07:00
} ,
}
}
2019-05-21 03:02:10 -07:00
// GetCmdSubmitProposal implements the command to submit a community-pool-spend proposal
func GetCmdSubmitProposal ( cdc * codec . Codec ) * cobra . Command {
cmd := & cobra . Command {
Use : "community-pool-spend [proposal-file]" ,
Args : cobra . ExactArgs ( 1 ) ,
Short : "Submit a community pool spend proposal" ,
Long : strings . TrimSpace (
fmt . Sprintf ( ` Submit a community pool spend proposal along with an initial deposit .
The proposal details must be supplied via a JSON file .
Example :
$ % s tx gov submit - proposal community - pool - spend < path / to / proposal . json > -- from = < key_or_address >
Where proposal . json contains :
{
"title" : "Community Pool Spend" ,
"description" : "Pay me some Atoms!" ,
"recipient" : "cosmos1s5afhd6gxevu37mkqcvvsj8qeylhn0rz46zdlq" ,
"amount" : [
{
"denom" : "stake" ,
"amount" : "10000"
}
] ,
"deposit" : [
{
"denom" : "stake" ,
"amount" : "10000"
}
]
}
` ,
version . ClientName ,
) ,
) ,
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2019-11-14 06:17:21 -08:00
inBuf := bufio . NewReader ( cmd . InOrStdin ( ) )
txBldr := auth . NewTxBuilderFromCLI ( inBuf ) . WithTxEncoder ( utils . GetTxEncoder ( cdc ) )
cliCtx := context . NewCLIContextWithInput ( inBuf ) . WithCodec ( cdc )
2019-05-21 03:02:10 -07:00
proposal , err := ParseCommunityPoolSpendProposalJSON ( cdc , args [ 0 ] )
if err != nil {
return err
}
from := cliCtx . GetFromAddress ( )
content := types . NewCommunityPoolSpendProposal ( proposal . Title , proposal . Description , proposal . Recipient , proposal . Amount )
msg := gov . NewMsgSubmitProposal ( content , proposal . Deposit , from )
if err := msg . ValidateBasic ( ) ; err != nil {
return err
}
return utils . GenerateOrBroadcastMsgs ( cliCtx , txBldr , [ ] sdk . Msg { msg } )
} ,
}
return cmd
}
2019-12-10 11:09:22 -08:00
2019-12-10 20:02:15 -08:00
// GetCmdFundCommunityPool returns a command implementation that supports directly
// funding the community pool.
2019-12-10 11:09:22 -08:00
func GetCmdFundCommunityPool ( cdc * codec . Codec ) * cobra . Command {
return & cobra . Command {
Use : "fund-community-pool [amount]" ,
Args : cobra . ExactArgs ( 1 ) ,
2019-12-10 20:02:15 -08:00
Short : "Funds the community pool with the specified amount" ,
2019-12-10 11:09:22 -08:00
Long : strings . TrimSpace (
fmt . Sprintf ( ` Funds the community pool with the specified amount
Example :
$ % s tx fund - community - pool 100 uatom -- from mykey
` ,
version . ClientName ,
) ,
) ,
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
inBuf := bufio . NewReader ( cmd . InOrStdin ( ) )
txBldr := auth . NewTxBuilderFromCLI ( inBuf ) . WithTxEncoder ( utils . GetTxEncoder ( cdc ) )
cliCtx := context . NewCLIContextWithInput ( inBuf ) . WithCodec ( cdc )
depositorAddr := cliCtx . GetFromAddress ( )
amount , err := sdk . ParseCoins ( args [ 0 ] )
if err != nil {
return err
}
2019-12-10 20:02:15 -08:00
msg := types . NewMsgFundCommunityPool ( amount , depositorAddr )
if err := msg . ValidateBasic ( ) ; err != nil {
return err
}
2019-12-10 11:09:22 -08:00
return utils . GenerateOrBroadcastMsgs ( cliCtx , txBldr , [ ] sdk . Msg { msg } )
} ,
}
}