diff --git a/PENDING.md b/PENDING.md index cce96f09b..6f99f5705 100644 --- a/PENDING.md +++ b/PENDING.md @@ -10,6 +10,7 @@ BREAKING CHANGES * [cli] [\#2786](https://github.com/cosmos/cosmos-sdk/pull/2786) Fix redelegation command flow * [cli] [\#2829](https://github.com/cosmos/cosmos-sdk/pull/2829) add-genesis-account command now validates state when adding accounts * [cli] [\#2804](https://github.com/cosmos/cosmos-sdk/issues/2804) Check whether key exists before passing it on to `tx create-validator`. + * [cli] [\#2874](https://github.com/cosmos/cosmos-sdk/pull/2874) `gaiacli tx sign` takes an optional `--output-document` flag to support output redirection. * Gaia @@ -17,6 +18,7 @@ BREAKING CHANGES * [\#2752](https://github.com/cosmos/cosmos-sdk/pull/2752) Don't hardcode bondable denom. * [\#2019](https://github.com/cosmos/cosmos-sdk/issues/2019) Cap total number of signatures. Current per-transaction limit is 7, and if that is exceeded transaction is rejected. * [\#2801](https://github.com/cosmos/cosmos-sdk/pull/2801) Remove AppInit structure. + * [\#2798](https://github.com/cosmos/cosmos-sdk/issues/2798) Governance API has miss-spelled English word in JSON response ('depositer' -> 'depositor') * Tendermint @@ -67,7 +69,10 @@ IMPROVEMENTS - [types] #2776 Improve safety of `Coin` and `Coins` types. Various functions and methods will panic when a negative amount is discovered. - #2815 Gas unit fields changed from `int64` to `uint64`. - + - #2821 Codespaces are now strings + - #2779 Introduce `ValidateBasic` to the `Tx` interface and call it in the ante + handler. + * Tendermint - #2796 Update to go-amino 0.14.1 @@ -75,6 +80,7 @@ IMPROVEMENTS BUG FIXES * Gaia REST API (`gaiacli advanced rest-server`) + - [gaia-lite] #2868 Added handler for governance tally endpoit * Gaia CLI (`gaiacli`) diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index d629ec580..c09f050ed 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -300,7 +300,8 @@ func (tx *txTest) setFailOnHandler(fail bool) { } // Implements Tx -func (tx txTest) GetMsgs() []sdk.Msg { return tx.Msgs } +func (tx txTest) GetMsgs() []sdk.Msg { return tx.Msgs } +func (tx txTest) ValidateBasic() sdk.Error { return nil } const ( routeMsgCounter = "msgCounter" diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 885e4b914..001cf3d92 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -678,7 +678,7 @@ func TestDeposit(t *testing.T) { func TestVote(t *testing.T) { name, password := "test", "1234567890" addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) - cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) + cleanup, _, operAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) defer cleanup() // create SubmitProposal TX @@ -696,7 +696,7 @@ func TestVote(t *testing.T) { proposal := getProposal(t, port, proposalID) require.Equal(t, "Test", proposal.GetTitle()) - // create SubmitProposal TX + // deposit resultTx = doDeposit(t, port, seed, name, password, addr, proposalID, 5) tests.WaitForHeight(resultTx.Height+1, port) @@ -704,13 +704,27 @@ func TestVote(t *testing.T) { proposal = getProposal(t, port, proposalID) require.Equal(t, gov.StatusVotingPeriod, proposal.GetStatus()) - // create SubmitProposal TX + // vote resultTx = doVote(t, port, seed, name, password, addr, proposalID) tests.WaitForHeight(resultTx.Height+1, port) vote := getVote(t, port, proposalID, addr) require.Equal(t, proposalID, vote.ProposalID) require.Equal(t, gov.OptionYes, vote.Option) + + tally := getTally(t, port, proposalID) + require.Equal(t, sdk.ZeroDec(), tally.Yes, "tally should be 0 as the address is not bonded") + + // create bond TX + resultTx = doDelegate(t, port, seed, name, password, addr, operAddrs[0], 60) + tests.WaitForHeight(resultTx.Height+1, port) + + // vote + resultTx = doVote(t, port, seed, name, password, addr, proposalID) + tests.WaitForHeight(resultTx.Height+1, port) + + tally = getTally(t, port, proposalID) + require.Equal(t, sdk.NewDec(60), tally.Yes, "tally should be equal to the amount delegated") } func TestUnjail(t *testing.T) { @@ -816,11 +830,11 @@ func TestProposalsQuery(t *testing.T) { require.Equal(t, proposalID3, (proposals[2]).GetProposalID()) // Test query deposited by addr1 - proposals = getProposalsFilterDepositer(t, port, addrs[0]) + proposals = getProposalsFilterDepositor(t, port, addrs[0]) require.Equal(t, proposalID1, (proposals[0]).GetProposalID()) // Test query deposited by addr2 - proposals = getProposalsFilterDepositer(t, port, addrs[1]) + proposals = getProposalsFilterDepositor(t, port, addrs[1]) require.Equal(t, proposalID2, (proposals[0]).GetProposalID()) require.Equal(t, proposalID3, (proposals[1]).GetProposalID()) @@ -834,7 +848,7 @@ func TestProposalsQuery(t *testing.T) { require.Equal(t, proposalID3, (proposals[0]).GetProposalID()) // Test query voted and deposited by addr1 - proposals = getProposalsFilterVoterDepositer(t, port, addrs[0], addrs[0]) + proposals = getProposalsFilterVoterDepositor(t, port, addrs[0], addrs[0]) require.Equal(t, proposalID2, (proposals[0]).GetProposalID()) // Test query votes on Proposal 2 @@ -1301,8 +1315,8 @@ func getDeposits(t *testing.T, port string, proposalID uint64) []gov.Deposit { return deposits } -func getDeposit(t *testing.T, port string, proposalID uint64, depositerAddr sdk.AccAddress) gov.Deposit { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits/%s", proposalID, depositerAddr), nil) +func getDeposit(t *testing.T, port string, proposalID uint64, depositorAddr sdk.AccAddress) gov.Deposit { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/deposits/%s", proposalID, depositorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var deposit gov.Deposit err := cdc.UnmarshalJSON([]byte(body), &deposit) @@ -1328,6 +1342,15 @@ func getVotes(t *testing.T, port string, proposalID uint64) []gov.Vote { return votes } +func getTally(t *testing.T, port string, proposalID uint64) gov.TallyResult { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d/tally", proposalID), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var tally gov.TallyResult + err := cdc.UnmarshalJSON([]byte(body), &tally) + require.Nil(t, err) + return tally +} + func getProposalsAll(t *testing.T, port string) []gov.Proposal { res, body := Request(t, port, "GET", "/gov/proposals", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -1338,8 +1361,8 @@ func getProposalsAll(t *testing.T, port string) []gov.Proposal { return proposals } -func getProposalsFilterDepositer(t *testing.T, port string, depositerAddr sdk.AccAddress) []gov.Proposal { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositer=%s", depositerAddr), nil) +func getProposalsFilterDepositor(t *testing.T, port string, depositorAddr sdk.AccAddress) []gov.Proposal { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositor=%s", depositorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var proposals []gov.Proposal @@ -1358,8 +1381,8 @@ func getProposalsFilterVoter(t *testing.T, port string, voterAddr sdk.AccAddress return proposals } -func getProposalsFilterVoterDepositer(t *testing.T, port string, voterAddr, depositerAddr sdk.AccAddress) []gov.Proposal { - res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositer=%s&voter=%s", depositerAddr, voterAddr), nil) +func getProposalsFilterVoterDepositor(t *testing.T, port string, voterAddr, depositorAddr sdk.AccAddress) []gov.Proposal { + res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals?depositor=%s&voter=%s", depositorAddr, voterAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var proposals []gov.Proposal @@ -1421,7 +1444,7 @@ func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk // deposit on proposal jsonStr := []byte(fmt.Sprintf(`{ - "depositer": "%s", + "depositor": "%s", "amount": [{ "denom": "%s", "amount": "%d" }], "base_req": { "name": "%s", diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 920194ffa..33dac880e 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -1226,8 +1226,8 @@ paths: required: false type: string - in: query - name: depositer - description: depositer address + name: depositor + description: depositor address required: false type: string - in: query @@ -1281,7 +1281,7 @@ paths: properties: base_req: "$ref": "#/definitions/BaseReq" - depositer: + depositor: "$ref": "#/definitions/Address" amount: type: array @@ -1321,6 +1321,29 @@ paths: description: Invalid proposal id 500: description: Internal Server Error + /gov/proposals/{proposalId}/tally: + get: + summary: Get a proposal's tally result at the current time + description: Gets a proposal's tally result at the current time. If the proposal is pending deposits (i.e status 'DepositPeriod') it returns an empty tally result. + produces: + - application/json + tags: + - ICS22 + parameters: + - type: string + description: proposal id + name: proposalId + required: true + in: path + responses: + 200: + description: OK + schema: + $ref: "#/definitions/TallyResult" + 400: + description: Invalid proposal id + 500: + description: Internal Server Error /gov/proposals/{proposalId}/votes: post: summary: Vote a proposal @@ -1418,10 +1441,10 @@ paths: description: Invalid proposal id 500: description: Internal Server Error - /gov/proposals/{proposalId}/deposits/{depositer}: + /gov/proposals/{proposalId}/deposits/{depositor}: get: summary: Query deposit - description: Query deposit by proposalId and depositer address + description: Query deposit by proposalId and depositor address produces: - application/json tags: @@ -1433,8 +1456,8 @@ paths: required: true in: path - type: string - description: Bech32 depositer address - name: depositer + description: Bech32 depositor address + name: depositor required: true in: path responses: @@ -1443,7 +1466,7 @@ paths: schema: $ref: "#/definitions/Deposit" 400: - description: Invalid proposal id or depositer address + description: Invalid proposal id or depositor address 404: description: Found no deposit 500: @@ -1893,16 +1916,7 @@ definitions: proposal_status: type: string tally_result: - type: object - properties: - yes: - type: string - abstain: - type: string - no: - type: string - no_with_veto: - type: string + $ref: "#/definitions/TallyResult" submit_time: type: string total_deposit: @@ -1920,8 +1934,23 @@ definitions: "$ref": "#/definitions/Coin" proposal_id: type: integer - depositer: + depositor: "$ref": "#/definitions/Address" + TallyResult: + type: object + properties: + yes: + type: string + example: "0.0000000000" + abstain: + type: string + example: "0.0000000000" + no: + type: string + example: "0.0000000000" + no_with_veto: + type: string + example: "0.0000000000" Vote: type: object properties: diff --git a/client/utils/utils.go b/client/utils/utils.go index 46bb9799c..08b8d87f2 100644 --- a/client/utils/utils.go +++ b/client/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "bytes" "fmt" + "io" "os" "github.com/cosmos/cosmos-sdk/client/context" @@ -88,7 +89,7 @@ func CalculateGas(queryFunc func(string, common.HexBytes) ([]byte, error), cdc * // PrintUnsignedStdTx builds an unsigned StdTx and prints it to os.Stdout. // Don't perform online validation or lookups if offline is true. -func PrintUnsignedStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg, offline bool) (err error) { +func PrintUnsignedStdTx(w io.Writer, txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg, offline bool) (err error) { var stdTx auth.StdTx if offline { stdTx, err = buildUnsignedStdTxOffline(txBldr, cliCtx, msgs) @@ -100,7 +101,7 @@ func PrintUnsignedStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msg } json, err := txBldr.Codec.MarshalJSON(stdTx) if err == nil { - fmt.Printf("%s\n", json) + fmt.Fprintf(w, "%s\n", json) } return } diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 26e6fcaa3..8ad32870f 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -365,7 +365,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { require.Equal(t, " 1 - Test", proposalsQuery) deposit := executeGetDeposit(t, - fmt.Sprintf("gaiacli query gov deposit --proposal-id=1 --depositer=%s --output=json %v", + fmt.Sprintf("gaiacli query gov deposit --proposal-id=1 --depositor=%s --output=json %v", fooAddr, flags)) require.Equal(t, int64(5), deposit.Amount.AmountOf(stakeTypes.DefaultBondDenom).Int64()) @@ -394,7 +394,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { require.Equal(t, int64(15), deposits[0].Amount.AmountOf(stakeTypes.DefaultBondDenom).Int64()) deposit = executeGetDeposit(t, - fmt.Sprintf("gaiacli query gov deposit --proposal-id=1 --depositer=%s --output=json %v", + fmt.Sprintf("gaiacli query gov deposit --proposal-id=1 --depositor=%s --output=json %v", fooAddr, flags)) require.Equal(t, int64(15), deposit.Amount.AmountOf(stakeTypes.DefaultBondDenom).Int64()) diff --git a/cmd/gaia/init/gentx.go b/cmd/gaia/init/gentx.go index 096097e18..91dfbd2e1 100644 --- a/cmd/gaia/init/gentx.go +++ b/cmd/gaia/init/gentx.go @@ -6,17 +6,21 @@ import ( "os" "path/filepath" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" "github.com/cosmos/cosmos-sdk/x/stake/client/cli" stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/spf13/cobra" - "github.com/spf13/viper" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" tmcli "github.com/tendermint/tendermint/libs/cli" @@ -80,7 +84,13 @@ following delegation and commission default parameters: } // Run gaiad tx create-validator prepareFlagsForTxCreateValidator(config, nodeID, ip, genDoc.ChainID, valPubKey) - createValidatorCmd := cli.GetCmdCreateValidator(cdc) + cliCtx, txBldr, msg, err := cli.BuildCreateValidatorMsg( + context.NewCLIContext().WithCodec(cdc), + authtxb.NewTxBuilderFromCLI().WithCodec(cdc), + ) + if err != nil { + return err + } w, err := ioutil.TempFile("", "gentx") if err != nil { @@ -88,18 +98,19 @@ following delegation and commission default parameters: } unsignedGenTxFilename := w.Name() defer os.Remove(unsignedGenTxFilename) - os.Stdout = w - if err = createValidatorCmd.RunE(nil, args); err != nil { + + if err := utils.PrintUnsignedStdTx(w, txBldr, cliCtx, []sdk.Msg{msg}, true); err != nil { return err } - w.Close() prepareFlagsForTxSign() signCmd := authcmd.GetSignCommand(cdc) - if w, err = prepareOutputFile(config.RootDir, nodeID); err != nil { + + outputDocument, err := makeOutputFilepath(config.RootDir, nodeID) + if err != nil { return err } - os.Stdout = w + viper.Set("output-document", outputDocument) return signCmd.RunE(nil, []string{unsignedGenTxFilename}) }, } @@ -145,11 +156,10 @@ func prepareFlagsForTxSign() { viper.Set("offline", true) } -func prepareOutputFile(rootDir, nodeID string) (w *os.File, err error) { +func makeOutputFilepath(rootDir, nodeID string) (string, error) { writePath := filepath.Join(rootDir, "config", "gentx") - if err = common.EnsureDir(writePath, 0700); err != nil { - return + if err := common.EnsureDir(writePath, 0700); err != nil { + return "", err } - filename := filepath.Join(writePath, fmt.Sprintf("gentx-%v.json", nodeID)) - return os.Create(filename) + return filepath.Join(writePath, fmt.Sprintf("gentx-%v.json", nodeID)), nil } diff --git a/docs/gaia/gaiacli.md b/docs/gaia/gaiacli.md index 5749e1ca7..38eaa0b8b 100644 --- a/docs/gaia/gaiacli.md +++ b/docs/gaia/gaiacli.md @@ -24,10 +24,12 @@ There are three types of key representations that are used: - Derived from account keys generated by `gaiacli keys add` - Used to receive funds - e.g. `cosmos15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc` + * `cosmosvaloper` - * Used to associate a validator to it's operator - * Used to invoke staking commands - * e.g. `cosmosvaloper1carzvgq3e6y3z5kz5y6gxp3wpy3qdrv928vyah` + - Used to associate a validator to it's operator + - Used to invoke staking commands + - e.g. `cosmosvaloper1carzvgq3e6y3z5kz5y6gxp3wpy3qdrv928vyah` + - `cosmospub` - Derived from account keys generated by `gaiacli keys add` - e.g. `cosmospub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm` @@ -72,7 +74,7 @@ View the validator pubkey for your node by typing: gaiad tendermint show-validator ``` -Note that this is the Tendermint signing key, *not* the operator key you will use in delegation transactions. +Note that this is the Tendermint signing key, _not_ the operator key you will use in delegation transactions. ::: danger Warning We strongly recommend _NOT_ using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. @@ -211,7 +213,7 @@ gaiacli query stake validator #### Bond Tokens -On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator (*i.e.* delegate): +On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator (_i.e._ delegate): ```bash gaiacli tx stake delegate \ @@ -304,7 +306,7 @@ gaiacli tx stake redelegate \ --chain-id= ``` -Here you can also redelegate a specific `shares-amount` or a `shares-fraction` with the corresponding flags. +Here you can also redelegate a specific `shares-amount` or a `shares-fraction` with the corresponding flags. The redelegation will be automatically completed when the unbonding period has passed. @@ -367,6 +369,7 @@ With the `pool` command you will get the values for: ##### Query Delegations To Validator You can also query all of the delegations to a particular validator: + ```bash gaiacli query delegations-to ``` @@ -418,7 +421,7 @@ Or query all available proposals: gaiacli query gov proposals ``` -You can also query proposals filtered by `voter` or `depositer` by using the corresponding flags. +You can also query proposals filtered by `voter` or `depositor` by using the corresponding flags. #### Increase deposit @@ -447,7 +450,7 @@ You can also query a deposit submitted by a specific address: ```bash gaiacli query gov deposit \ --proposal-id= \ - --depositer= + --depositor= ``` #### Vote on a proposal diff --git a/docs/spec/governance/overview.md b/docs/spec/governance/overview.md index 53f7d7b08..a79b95190 100644 --- a/docs/spec/governance/overview.md +++ b/docs/spec/governance/overview.md @@ -42,7 +42,7 @@ If proposal's deposit does not reach `MinDeposit` before `MaxDepositPeriod`, pro There is one instance where Atom holders that deposits can be refunded: * If the proposal is accepted. -Then, deposits will automatically be refunded to their respective depositer. +Then, deposits will automatically be refunded to their respective depositor. ### Proposal types diff --git a/docs/spec/governance/state.md b/docs/spec/governance/state.md index 3858ba06b..6c2799fd0 100644 --- a/docs/spec/governance/state.md +++ b/docs/spec/governance/state.md @@ -68,8 +68,8 @@ const ( ```go type Deposit struct { - Amount sdk.Coins // Amount of coins deposited by depositer - Depositer crypto.address // Address of depositer + Amount sdk.Coins // Amount of coins deposited by depositor + Depositor crypto.address // Address of depositor } ``` @@ -185,8 +185,8 @@ And the pseudocode for the `ProposalProcessingQueue`: // proposal was accepted at the end of the voting period // refund deposits (non-voters already punished) proposal.CurrentStatus = ProposalStatusAccepted - for each (amount, depositer) in proposal.Deposits - depositer.AtomBalance += amount + for each (amount, depositor) in proposal.Deposits + depositor.AtomBalance += amount else // proposal was rejected diff --git a/types/tx_msg.go b/types/tx_msg.go index 7882b25d3..791ab9c35 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -32,9 +32,12 @@ type Msg interface { // Transactions objects must fulfill the Tx type Tx interface { - - // Gets the Msg. + // Gets the all the transaction's messages. GetMsgs() []Msg + + // ValidateBasic does a simple and lightweight validation check that doesn't + // require access to any other information. + ValidateBasic() Error } //__________________________________________________________ diff --git a/x/auth/ante.go b/x/auth/ante.go index 7ac245cf0..685d60949 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -8,7 +8,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/multisig" "github.com/tendermint/tendermint/crypto/secp256k1" ) @@ -67,28 +66,18 @@ func NewAnteHandler(am AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler { } }() - err := validateBasic(stdTx) - if err != nil { + if err := tx.ValidateBasic(); err != nil { return newCtx, err.Result(), true } // charge gas for the memo newCtx.GasMeter().ConsumeGas(memoCostPerByte*sdk.Gas(len(stdTx.GetMemo())), "memo") - // stdSigs contains the sequence number, account number, and signatures - stdSigs := stdTx.GetSignatures() // When simulating, this would just be a 0-length slice. + // stdSigs contains the sequence number, account number, and signatures. + // When simulating, this would just be a 0-length slice. + stdSigs := stdTx.GetSignatures() signerAddrs := stdTx.GetSigners() - sigCount := 0 - for i := 0; i < len(stdSigs); i++ { - sigCount += countSubKeys(stdSigs[i].PubKey) - if sigCount > txSigLimit { - return newCtx, sdk.ErrTooManySignatures(fmt.Sprintf( - "signatures: %d, limit: %d", sigCount, txSigLimit), - ).Result(), true - } - } - // create the list of all sign bytes signBytesList := getSignBytesList(newCtx.ChainID(), stdTx, stdSigs) signerAccs, res := getSignerAccs(newCtx, am, signerAddrs) @@ -129,29 +118,6 @@ func NewAnteHandler(am AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler { } } -// Validate the transaction based on things that don't depend on the context -func validateBasic(tx StdTx) (err sdk.Error) { - // Assert that there are signatures. - sigs := tx.GetSignatures() - if len(sigs) == 0 { - return sdk.ErrUnauthorized("no signers") - } - - // Assert that number of signatures is correct. - var signerAddrs = tx.GetSigners() - if len(sigs) != len(signerAddrs) { - return sdk.ErrUnauthorized("wrong number of signers") - } - - memo := tx.GetMemo() - if len(memo) > maxMemoCharacters { - return sdk.ErrMemoTooLarge( - fmt.Sprintf("maximum number of characters is %d but received %d characters", - maxMemoCharacters, len(memo))) - } - return nil -} - func getSignerAccs(ctx sdk.Context, am AccountKeeper, addrs []sdk.AccAddress) (accs []Account, res sdk.Result) { accs = make([]Account, len(addrs)) for i := 0; i < len(accs); i++ { @@ -340,15 +306,3 @@ func getSignBytesList(chainID string, stdTx StdTx, stdSigs []StdSignature) (sign } return } - -func countSubKeys(pub crypto.PubKey) int { - v, ok := pub.(*multisig.PubKeyMultisigThreshold) - if !ok { - return 1 - } - nkeys := 0 - for _, subkey := range v.PubKeys { - nkeys += countSubKeys(subkey) - } - return nkeys -} diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 9075308e1..6fc57ac16 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -3,9 +3,7 @@ package cli import ( "fmt" "io/ioutil" - - "github.com/pkg/errors" - "github.com/spf13/viper" + "os" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -13,7 +11,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" + "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/viper" "github.com/tendermint/go-amino" ) @@ -22,6 +22,7 @@ const ( flagValidateSigs = "validate-signatures" flagOffline = "offline" flagSigOnly = "signature-only" + flagOutfile = "output-document" ) // GetSignCommand returns the sign command @@ -52,6 +53,8 @@ recommended to set such parameters manually.`, cmd.Flags().Bool(flagValidateSigs, false, "Print the addresses that must sign the transaction, "+ "those who have already signed it, and make sure that signatures are in the correct order.") cmd.Flags().Bool(flagOffline, false, "Offline mode. Do not query local cache.") + cmd.Flags().String(flagOutfile, "", + "The document will be written to the given file instead of STDOUT") // Add the flags here and return the command return client.PostCommands(cmd)[0] @@ -107,7 +110,20 @@ func makeSignCmd(cdc *amino.Codec) func(cmd *cobra.Command, args []string) error if err != nil { return err } - fmt.Printf("%s\n", json) + + if viper.GetString(flagOutfile) == "" { + fmt.Printf("%s\n", json) + return + } + + fp, err := os.OpenFile( + viper.GetString(flagOutfile), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644, + ) + if err != nil { + return err + } + defer fp.Close() + fmt.Fprintf(fp, "%s\n", json) return } } diff --git a/x/auth/stdtx.go b/x/auth/stdtx.go index ba1c65b84..e8b9461fd 100644 --- a/x/auth/stdtx.go +++ b/x/auth/stdtx.go @@ -2,10 +2,12 @@ package auth import ( "encoding/json" + "fmt" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/multisig" ) var _ sdk.Tx = (*StdTx)(nil) @@ -28,11 +30,61 @@ func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdT } } -//nolint +// GetMsgs returns the all the transaction's messages. func (tx StdTx) GetMsgs() []sdk.Msg { return tx.Msgs } +// ValidateBasic does a simple and lightweight validation check that doesn't +// require access to any other information. +func (tx StdTx) ValidateBasic() sdk.Error { + stdSigs := tx.GetSignatures() + + if !tx.Fee.Amount.IsNotNegative() { + return sdk.ErrInsufficientFee(fmt.Sprintf("invalid fee %s amount provided", tx.Fee.Amount)) + } + if len(stdSigs) == 0 { + return sdk.ErrUnauthorized("no signers") + } + if len(stdSigs) != len(tx.GetSigners()) { + return sdk.ErrUnauthorized("wrong number of signers") + } + if len(tx.GetMemo()) > maxMemoCharacters { + return sdk.ErrMemoTooLarge( + fmt.Sprintf( + "maximum number of characters is %d but received %d characters", + maxMemoCharacters, len(tx.GetMemo()), + ), + ) + } + + sigCount := 0 + for i := 0; i < len(stdSigs); i++ { + sigCount += countSubKeys(stdSigs[i].PubKey) + if sigCount > txSigLimit { + return sdk.ErrTooManySignatures( + fmt.Sprintf("signatures: %d, limit: %d", sigCount, txSigLimit), + ) + } + } + + return nil +} + +func countSubKeys(pub crypto.PubKey) int { + v, ok := pub.(*multisig.PubKeyMultisigThreshold) + if !ok { + return 1 + } + + numKeys := 0 + for _, subkey := range v.PubKeys { + numKeys += countSubKeys(subkey) + } + + return numKeys +} + // GetSigners returns the addresses that must sign the transaction. -// Addresses are returned in a determistic order. +// Addresses are returned in a deterministic order. // They are accumulated from the GetSigners method for each Msg // in the order they appear in tx.GetMsgs(). // Duplicate addresses will be omitted. diff --git a/x/auth/stdtx_test.go b/x/auth/stdtx_test.go index 26bd79245..a3267ac19 100644 --- a/x/auth/stdtx_test.go +++ b/x/auth/stdtx_test.go @@ -2,11 +2,15 @@ package auth import ( "fmt" + "strings" "testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/libs/log" ) var ( @@ -51,3 +55,75 @@ func TestStdSignBytes(t *testing.T) { require.Equal(t, tc.want, got, "Got unexpected result on test case i: %d", i) } } + +func TestTxValidateBasic(t *testing.T) { + ctx := sdk.NewContext(nil, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) + + // keys and addresses + priv1, addr1 := privAndAddr() + priv2, addr2 := privAndAddr() + priv3, addr3 := privAndAddr() + priv4, addr4 := privAndAddr() + priv5, addr5 := privAndAddr() + priv6, addr6 := privAndAddr() + priv7, addr7 := privAndAddr() + priv8, addr8 := privAndAddr() + + // msg and signatures + msg1 := newTestMsg(addr1, addr2) + fee := newStdFee() + + msgs := []sdk.Msg{msg1} + + // require to fail validation upon invalid fee + badFee := newStdFee() + badFee.Amount[0].Amount = sdk.NewInt(-5) + tx := newTestTx(ctx, nil, nil, nil, nil, badFee) + + err := tx.ValidateBasic() + require.Error(t, err) + require.Equal(t, sdk.CodeInsufficientFee, err.Result().Code) + + // require to fail validation when no signatures exist + privs, accNums, seqs := []crypto.PrivKey{}, []int64{}, []int64{} + tx = newTestTx(ctx, msgs, privs, accNums, seqs, fee) + + err = tx.ValidateBasic() + require.Error(t, err) + require.Equal(t, sdk.CodeUnauthorized, err.Result().Code) + + // require to fail validation when signatures do not match expected signers + privs, accNums, seqs = []crypto.PrivKey{priv1}, []int64{0, 1}, []int64{0, 0} + tx = newTestTx(ctx, msgs, privs, accNums, seqs, fee) + + err = tx.ValidateBasic() + require.Error(t, err) + require.Equal(t, sdk.CodeUnauthorized, err.Result().Code) + + // require to fail validation when memo is too large + badMemo := strings.Repeat("bad memo", 50) + privs, accNums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{0, 0} + tx = newTestTxWithMemo(ctx, msgs, privs, accNums, seqs, fee, badMemo) + + err = tx.ValidateBasic() + require.Error(t, err) + require.Equal(t, sdk.CodeMemoTooLarge, err.Result().Code) + + // require to fail validation when there are too many signatures + privs = []crypto.PrivKey{priv1, priv2, priv3, priv4, priv5, priv6, priv7, priv8} + accNums, seqs = []int64{0, 0, 0, 0, 0, 0, 0, 0}, []int64{0, 0, 0, 0, 0, 0, 0, 0} + badMsg := newTestMsg(addr1, addr2, addr3, addr4, addr5, addr6, addr7, addr8) + badMsgs := []sdk.Msg{badMsg} + tx = newTestTx(ctx, badMsgs, privs, accNums, seqs, fee) + + err = tx.ValidateBasic() + require.Error(t, err) + require.Equal(t, sdk.CodeTooManySignatures, err.Result().Code) + + // require to pass when above criteria are matched + privs, accNums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{0, 0} + tx = newTestTx(ctx, msgs, privs, accNums, seqs, fee) + + err = tx.ValidateBasic() + require.NoError(t, err) +} diff --git a/x/bank/client/cli/sendtx.go b/x/bank/client/cli/sendtx.go index 29a101cf7..1a7c444af 100644 --- a/x/bank/client/cli/sendtx.go +++ b/x/bank/client/cli/sendtx.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" bankClient "github.com/cosmos/cosmos-sdk/x/bank/client" + "os" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -66,7 +67,7 @@ func SendTxCmd(cdc *codec.Codec) *cobra.Command { // build and sign the transaction, then broadcast to Tendermint msg := bankClient.CreateMsg(from, to, coins) if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg}) diff --git a/x/gov/client/cli/query.go b/x/gov/client/cli/query.go index 227f278a9..b301c3b1b 100644 --- a/x/gov/client/cli/query.go +++ b/x/gov/client/cli/query.go @@ -21,10 +21,7 @@ func GetCmdQueryProposal(queryRoute string, cdc *codec.Codec) *cobra.Command { cliCtx := context.NewCLIContext().WithCodec(cdc) proposalID := uint64(viper.GetInt64(flagProposalID)) - params := gov.QueryProposalParams{ - ProposalID: proposalID, - } - + params := gov.NewQueryProposalParams(proposalID) bz, err := cdc.MarshalJSON(params) if err != nil { return err @@ -51,21 +48,23 @@ func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command { Use: "proposals", Short: "Query proposals with optional filters", RunE: func(cmd *cobra.Command, args []string) error { - bechDepositerAddr := viper.GetString(flagDepositer) + bechDepositorAddr := viper.GetString(flagDepositor) bechVoterAddr := viper.GetString(flagVoter) strProposalStatus := viper.GetString(flagStatus) numLimit := uint64(viper.GetInt64(flagNumLimit)) - params := gov.QueryProposalsParams{ - Limit: numLimit, - } + var depositorAddr sdk.AccAddress + var voterAddr sdk.AccAddress + var proposalStatus gov.ProposalStatus - if len(bechDepositerAddr) != 0 { - depositerAddr, err := sdk.AccAddressFromBech32(bechDepositerAddr) + params := gov.NewQueryProposalsParams(proposalStatus, numLimit, voterAddr, depositorAddr) + + if len(bechDepositorAddr) != 0 { + depositorAddr, err := sdk.AccAddressFromBech32(bechDepositorAddr) if err != nil { return err } - params.Depositer = depositerAddr + params.Depositor = depositorAddr } if len(bechVoterAddr) != 0 { @@ -116,7 +115,7 @@ func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command { } cmd.Flags().String(flagNumLimit, "", "(optional) limit to latest [number] proposals. Defaults to all proposals") - cmd.Flags().String(flagDepositer, "", "(optional) filter by proposals deposited on by depositer") + cmd.Flags().String(flagDepositor, "", "(optional) filter by proposals deposited on by depositor") cmd.Flags().String(flagVoter, "", "(optional) filter by proposals voted on by voted") cmd.Flags().String(flagStatus, "", "(optional) filter proposals by proposal status, status: deposit_period/voting_period/passed/rejected") @@ -138,10 +137,7 @@ func GetCmdQueryVote(queryRoute string, cdc *codec.Codec) *cobra.Command { return err } - params := gov.QueryVoteParams{ - Voter: voterAddr, - ProposalID: proposalID, - } + params := gov.NewQueryVoteParams(proposalID, voterAddr) bz, err := cdc.MarshalJSON(params) if err != nil { return err @@ -172,9 +168,7 @@ func GetCmdQueryVotes(queryRoute string, cdc *codec.Codec) *cobra.Command { cliCtx := context.NewCLIContext().WithCodec(cdc) proposalID := uint64(viper.GetInt64(flagProposalID)) - params := gov.QueryVotesParams{ - ProposalID: proposalID, - } + params := gov.NewQueryProposalParams(proposalID) bz, err := cdc.MarshalJSON(params) if err != nil { return err @@ -205,15 +199,12 @@ func GetCmdQueryDeposit(queryRoute string, cdc *codec.Codec) *cobra.Command { cliCtx := context.NewCLIContext().WithCodec(cdc) proposalID := uint64(viper.GetInt64(flagProposalID)) - depositerAddr, err := sdk.AccAddressFromBech32(viper.GetString(flagDepositer)) + depositorAddr, err := sdk.AccAddressFromBech32(viper.GetString(flagDepositor)) if err != nil { return err } - params := gov.QueryDepositParams{ - Depositer: depositerAddr, - ProposalID: proposalID, - } + params := gov.NewQueryDepositParams(proposalID, depositorAddr) bz, err := cdc.MarshalJSON(params) if err != nil { return err @@ -230,7 +221,7 @@ func GetCmdQueryDeposit(queryRoute string, cdc *codec.Codec) *cobra.Command { } cmd.Flags().String(flagProposalID, "", "proposalID of proposal deposited on") - cmd.Flags().String(flagDepositer, "", "bech32 depositer address") + cmd.Flags().String(flagDepositor, "", "bech32 depositor address") return cmd } @@ -244,9 +235,7 @@ func GetCmdQueryDeposits(queryRoute string, cdc *codec.Codec) *cobra.Command { cliCtx := context.NewCLIContext().WithCodec(cdc) proposalID := uint64(viper.GetInt64(flagProposalID)) - params := gov.QueryDepositsParams{ - ProposalID: proposalID, - } + params := gov.NewQueryProposalParams(proposalID) bz, err := cdc.MarshalJSON(params) if err != nil { return err @@ -276,9 +265,7 @@ func GetCmdQueryTally(queryRoute string, cdc *codec.Codec) *cobra.Command { cliCtx := context.NewCLIContext().WithCodec(cdc) proposalID := uint64(viper.GetInt64(flagProposalID)) - params := gov.QueryTallyParams{ - ProposalID: proposalID, - } + params := gov.NewQueryProposalParams(proposalID) bz, err := cdc.MarshalJSON(params) if err != nil { return err diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index e804863d1..000aef68d 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "os" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/utils" @@ -27,7 +28,7 @@ const ( flagDeposit = "deposit" flagVoter = "voter" flagOption = "option" - flagDepositer = "depositer" + flagDepositor = "depositor" flagStatus = "status" flagNumLimit = "limit" flagProposal = "proposal" @@ -103,7 +104,7 @@ $ gaiacli gov submit-proposal --title="Test Proposal" --description="My awesome } if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } // Build and sign the transaction, then broadcast to Tendermint @@ -164,7 +165,7 @@ func GetCmdDeposit(cdc *codec.Codec) *cobra.Command { WithCodec(cdc). WithAccountDecoder(cdc) - depositerAddr, err := cliCtx.GetFromAddress() + depositorAddr, err := cliCtx.GetFromAddress() if err != nil { return err } @@ -176,14 +177,14 @@ func GetCmdDeposit(cdc *codec.Codec) *cobra.Command { return err } - msg := gov.NewMsgDeposit(depositerAddr, proposalID, amount) + msg := gov.NewMsgDeposit(depositorAddr, proposalID, amount) err = msg.ValidateBasic() if err != nil { return err } if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } // Build and sign the transaction, then broadcast to a Tendermint @@ -229,7 +230,7 @@ func GetCmdVote(cdc *codec.Codec) *cobra.Command { } if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]", diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index c000a34d8..72abdb214 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -20,7 +20,7 @@ import ( const ( RestParamsType = "type" RestProposalID = "proposal-id" - RestDepositer = "depositer" + RestDepositor = "depositor" RestVoter = "voter" RestProposalStatus = "status" RestNumLimit = "limit" @@ -41,7 +41,8 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) r.HandleFunc("/gov/proposals", queryProposalsWithParameterFn(cdc, cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}", RestProposalID), queryProposalHandlerFn(cdc, cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/deposits", RestProposalID), queryDepositsHandlerFn(cdc, cliCtx)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/deposits/{%s}", RestProposalID, RestDepositer), queryDepositHandlerFn(cdc, cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/deposits/{%s}", RestProposalID, RestDepositor), queryDepositHandlerFn(cdc, cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/tally", RestProposalID), queryTallyOnProposalHandlerFn(cdc, cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes", RestProposalID), queryVotesOnProposalHandlerFn(cdc, cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes/{%s}", RestProposalID, RestVoter), queryVoteHandlerFn(cdc, cliCtx)).Methods("GET") } @@ -57,7 +58,7 @@ type postProposalReq struct { type depositReq struct { BaseReq utils.BaseReq `json:"base_req"` - Depositer sdk.AccAddress `json:"depositer"` // Address of the depositer + Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit } @@ -127,7 +128,7 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF } // create the message - msg := gov.NewMsgDeposit(req.Depositer, proposalID, req.Amount) + msg := gov.NewMsgDeposit(req.Depositor, proposalID, req.Amount) err = msg.ValidateBasic() if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) @@ -244,9 +245,7 @@ func queryDepositsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha return } - params := gov.QueryDepositsParams{ - ProposalID: proposalID, - } + params := gov.NewQueryProposalParams(proposalID) bz, err := cdc.MarshalJSON(params) if err != nil { @@ -268,7 +267,7 @@ func queryDepositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) strProposalID := vars[RestProposalID] - bechDepositerAddr := vars[RestDepositer] + bechDepositorAddr := vars[RestDepositor] if len(strProposalID) == 0 { err := errors.New("proposalId required but not specified") @@ -281,13 +280,13 @@ func queryDepositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han return } - if len(bechDepositerAddr) == 0 { - err := errors.New("depositer address required but not specified") + if len(bechDepositorAddr) == 0 { + err := errors.New("depositor address required but not specified") utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - depositerAddr, err := sdk.AccAddressFromBech32(bechDepositerAddr) + depositorAddr, err := sdk.AccAddressFromBech32(bechDepositorAddr) if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return @@ -295,7 +294,7 @@ func queryDepositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han params := gov.QueryDepositParams{ ProposalID: proposalID, - Depositer: depositerAddr, + Depositor: depositorAddr, } bz, err := cdc.MarshalJSON(params) @@ -319,7 +318,7 @@ func queryDepositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han utils.WriteErrorResponse(w, http.StatusNotFound, err.Error()) return } - err = errors.Errorf("depositer [%s] did not deposit on proposalID [%d]", bechDepositerAddr, proposalID) + err = errors.Errorf("depositor [%s] did not deposit on proposalID [%d]", bechDepositorAddr, proposalID) utils.WriteErrorResponse(w, http.StatusNotFound, err.Error()) return } @@ -412,9 +411,8 @@ func queryVotesOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) return } - params := gov.QueryVotesParams{ - ProposalID: proposalID, - } + params := gov.NewQueryProposalParams(proposalID) + bz, err := cdc.MarshalJSON(params) if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) @@ -435,7 +433,7 @@ func queryVotesOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) func queryProposalsWithParameterFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { bechVoterAddr := r.URL.Query().Get(RestVoter) - bechDepositerAddr := r.URL.Query().Get(RestDepositer) + bechDepositorAddr := r.URL.Query().Get(RestDepositor) strProposalStatus := r.URL.Query().Get(RestProposalStatus) strNumLimit := r.URL.Query().Get(RestNumLimit) @@ -450,13 +448,13 @@ func queryProposalsWithParameterFn(cdc *codec.Codec, cliCtx context.CLIContext) params.Voter = voterAddr } - if len(bechDepositerAddr) != 0 { - depositerAddr, err := sdk.AccAddressFromBech32(bechDepositerAddr) + if len(bechDepositorAddr) != 0 { + depositorAddr, err := sdk.AccAddressFromBech32(bechDepositorAddr) if err != nil { utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } - params.Depositer = depositerAddr + params.Depositor = depositorAddr } if len(strProposalStatus) != 0 { @@ -498,10 +496,8 @@ func queryTallyOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) strProposalID := vars[RestProposalID] if len(strProposalID) == 0 { - w.WriteHeader(http.StatusBadRequest) err := errors.New("proposalId required but not specified") - w.Write([]byte(err.Error())) - + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } @@ -510,20 +506,17 @@ func queryTallyOnProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) return } - params := gov.QueryTallyParams{ - ProposalID: proposalID, - } + params := gov.NewQueryProposalParams(proposalID) + bz, err := cdc.MarshalJSON(params) if err != nil { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } res, err := cliCtx.QueryWithData("custom/gov/tally", bz) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } diff --git a/x/gov/depositsvotes.go b/x/gov/depositsvotes.go index 7a6b043e6..8e22f245d 100644 --- a/x/gov/depositsvotes.go +++ b/x/gov/depositsvotes.go @@ -28,14 +28,14 @@ func (voteA Vote) Empty() bool { // Deposit type Deposit struct { - Depositer sdk.AccAddress `json:"depositer"` // Address of the depositer + Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor ProposalID uint64 `json:"proposal_id"` // proposalID of the proposal Amount sdk.Coins `json:"amount"` // Deposit amount } // Returns whether 2 deposits are equal func (depositA Deposit) Equals(depositB Deposit) bool { - return depositA.Depositer.Equals(depositB.Depositer) && depositA.ProposalID == depositB.ProposalID && depositA.Amount.IsEqual(depositB.Amount) + return depositA.Depositor.Equals(depositB.Depositor) && depositA.ProposalID == depositB.ProposalID && depositA.Amount.IsEqual(depositB.Amount) } // Returns whether a deposit is empty diff --git a/x/gov/genesis.go b/x/gov/genesis.go index e134a4a78..2096fc2ec 100644 --- a/x/gov/genesis.go +++ b/x/gov/genesis.go @@ -69,7 +69,7 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { k.setVotingParams(ctx, data.VotingParams) k.setTallyParams(ctx, data.TallyParams) for _, deposit := range data.Deposits { - k.setDeposit(ctx, deposit.ProposalID, deposit.Deposit.Depositer, deposit.Deposit) + k.setDeposit(ctx, deposit.ProposalID, deposit.Deposit.Depositor, deposit.Deposit) } for _, vote := range data.Votes { k.setVote(ctx, vote.ProposalID, vote.Vote.Voter, vote.Vote) diff --git a/x/gov/handler.go b/x/gov/handler.go index 180f7a21a..9516710a9 100644 --- a/x/gov/handler.go +++ b/x/gov/handler.go @@ -53,7 +53,7 @@ func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitPropos func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) sdk.Result { - err, votingStarted := keeper.AddDeposit(ctx, msg.ProposalID, msg.Depositer, msg.Amount) + err, votingStarted := keeper.AddDeposit(ctx, msg.ProposalID, msg.Depositor, msg.Amount) if err != nil { return err.Result() } @@ -63,7 +63,7 @@ func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) sdk.Result // TODO: Add tag for if voting period started resTags := sdk.NewTags( tags.Action, tags.ActionDeposit, - tags.Depositer, []byte(msg.Depositer.String()), + tags.Depositor, []byte(msg.Depositor.String()), tags.ProposalID, proposalIDBytes, ) diff --git a/x/gov/keeper.go b/x/gov/keeper.go index 4f370ef53..0a3c8e106 100644 --- a/x/gov/keeper.go +++ b/x/gov/keeper.go @@ -139,7 +139,7 @@ func (keeper Keeper) DeleteProposal(ctx sdk.Context, proposalID uint64) { } // Get Proposal from store by ProposalID -func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, voterAddr sdk.AccAddress, depositerAddr sdk.AccAddress, status ProposalStatus, numLatest uint64) []Proposal { +func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, voterAddr sdk.AccAddress, depositorAddr sdk.AccAddress, status ProposalStatus, numLatest uint64) []Proposal { maxProposalID, err := keeper.peekCurrentProposalID(ctx) if err != nil { @@ -160,8 +160,8 @@ func (keeper Keeper) GetProposalsFiltered(ctx sdk.Context, voterAddr sdk.AccAddr } } - if depositerAddr != nil && len(depositerAddr) != 0 { - _, found := keeper.GetDeposit(ctx, proposalID, depositerAddr) + if depositorAddr != nil && len(depositorAddr) != 0 { + _, found := keeper.GetDeposit(ctx, proposalID, depositorAddr) if !found { continue } @@ -340,10 +340,10 @@ func (keeper Keeper) deleteVote(ctx sdk.Context, proposalID uint64, voterAddr sd // ===================================================== // Deposits -// Gets the deposit of a specific depositer on a specific proposal -func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositerAddr sdk.AccAddress) (Deposit, bool) { +// Gets the deposit of a specific depositor on a specific proposal +func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) (Deposit, bool) { store := ctx.KVStore(keeper.storeKey) - bz := store.Get(KeyDeposit(proposalID, depositerAddr)) + bz := store.Get(KeyDeposit(proposalID, depositorAddr)) if bz == nil { return Deposit{}, false } @@ -352,15 +352,15 @@ func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositerAdd return deposit, true } -func (keeper Keeper) setDeposit(ctx sdk.Context, proposalID uint64, depositerAddr sdk.AccAddress, deposit Deposit) { +func (keeper Keeper) setDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, deposit Deposit) { store := ctx.KVStore(keeper.storeKey) bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(deposit) - store.Set(KeyDeposit(proposalID, depositerAddr), bz) + store.Set(KeyDeposit(proposalID, depositorAddr), bz) } -// Adds or updates a deposit of a specific depositer on a specific proposal +// Adds or updates a deposit of a specific depositor on a specific proposal // Activates voting period when appropriate -func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositerAddr sdk.AccAddress, depositAmount sdk.Coins) (sdk.Error, bool) { +func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (sdk.Error, bool) { // Checks to see if proposal exists proposal := keeper.GetProposal(ctx, proposalID) if proposal == nil { @@ -372,8 +372,8 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositerAdd return ErrAlreadyFinishedProposal(keeper.codespace, proposalID), false } - // Send coins from depositer's account to DepositedCoinsAccAddr account - _, err := keeper.ck.SendCoins(ctx, depositerAddr, DepositedCoinsAccAddr, depositAmount) + // Send coins from depositor's account to DepositedCoinsAccAddr account + _, err := keeper.ck.SendCoins(ctx, depositorAddr, DepositedCoinsAccAddr, depositAmount) if err != nil { return err, false } @@ -391,13 +391,13 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositerAdd } // Add or update deposit object - currDeposit, found := keeper.GetDeposit(ctx, proposalID, depositerAddr) + currDeposit, found := keeper.GetDeposit(ctx, proposalID, depositorAddr) if !found { - newDeposit := Deposit{depositerAddr, proposalID, depositAmount} - keeper.setDeposit(ctx, proposalID, depositerAddr, newDeposit) + newDeposit := Deposit{depositorAddr, proposalID, depositAmount} + keeper.setDeposit(ctx, proposalID, depositorAddr, newDeposit) } else { currDeposit.Amount = currDeposit.Amount.Plus(depositAmount) - keeper.setDeposit(ctx, proposalID, depositerAddr, currDeposit) + keeper.setDeposit(ctx, proposalID, depositorAddr, currDeposit) } return nil, activatedVotingPeriod @@ -418,7 +418,7 @@ func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID uint64) { deposit := &Deposit{} keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), deposit) - _, err := keeper.ck.SendCoins(ctx, DepositedCoinsAccAddr, deposit.Depositer, deposit.Amount) + _, err := keeper.ck.SendCoins(ctx, DepositedCoinsAccAddr, deposit.Depositor, deposit.Amount) if err != nil { panic("should not happen") } diff --git a/x/gov/keeper_keys.go b/x/gov/keeper_keys.go index 8a3324fd1..b1a5d7761 100644 --- a/x/gov/keeper_keys.go +++ b/x/gov/keeper_keys.go @@ -25,8 +25,8 @@ func KeyProposal(proposalID uint64) []byte { } // Key for getting a specific deposit from the store -func KeyDeposit(proposalID uint64, depositerAddr sdk.AccAddress) []byte { - return []byte(fmt.Sprintf("deposits:%d:%d", proposalID, depositerAddr)) +func KeyDeposit(proposalID uint64, depositorAddr sdk.AccAddress) []byte { + return []byte(fmt.Sprintf("deposits:%d:%d", proposalID, depositorAddr)) } // Key for getting a specific vote from the store diff --git a/x/gov/keeper_test.go b/x/gov/keeper_test.go index 23199472b..83702920e 100644 --- a/x/gov/keeper_test.go +++ b/x/gov/keeper_test.go @@ -93,7 +93,7 @@ func TestDeposits(t *testing.T) { deposit, found = keeper.GetDeposit(ctx, proposalID, addrs[0]) require.True(t, found) require.Equal(t, fourSteak, deposit.Amount) - require.Equal(t, addrs[0], deposit.Depositer) + require.Equal(t, addrs[0], deposit.Depositor) require.Equal(t, fourSteak, keeper.GetProposal(ctx, proposalID).GetTotalDeposit()) require.Equal(t, addr0Initial.Minus(fourSteak), keeper.ck.GetCoins(ctx, addrs[0])) @@ -104,7 +104,7 @@ func TestDeposits(t *testing.T) { deposit, found = keeper.GetDeposit(ctx, proposalID, addrs[0]) require.True(t, found) require.Equal(t, fourSteak.Plus(fiveSteak), deposit.Amount) - require.Equal(t, addrs[0], deposit.Depositer) + require.Equal(t, addrs[0], deposit.Depositor) require.Equal(t, fourSteak.Plus(fiveSteak), keeper.GetProposal(ctx, proposalID).GetTotalDeposit()) require.Equal(t, addr0Initial.Minus(fourSteak).Minus(fiveSteak), keeper.ck.GetCoins(ctx, addrs[0])) @@ -114,7 +114,7 @@ func TestDeposits(t *testing.T) { require.True(t, votingStarted) deposit, found = keeper.GetDeposit(ctx, proposalID, addrs[1]) require.True(t, found) - require.Equal(t, addrs[1], deposit.Depositer) + require.Equal(t, addrs[1], deposit.Depositor) require.Equal(t, fourSteak, deposit.Amount) require.Equal(t, fourSteak.Plus(fiveSteak).Plus(fourSteak), keeper.GetProposal(ctx, proposalID).GetTotalDeposit()) require.Equal(t, addr1Initial.Minus(fourSteak), keeper.ck.GetCoins(ctx, addrs[1])) @@ -126,11 +126,11 @@ func TestDeposits(t *testing.T) { depositsIterator := keeper.GetDeposits(ctx, proposalID) require.True(t, depositsIterator.Valid()) keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit) - require.Equal(t, addrs[0], deposit.Depositer) + require.Equal(t, addrs[0], deposit.Depositor) require.Equal(t, fourSteak.Plus(fiveSteak), deposit.Amount) depositsIterator.Next() keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit) - require.Equal(t, addrs[1], deposit.Depositer) + require.Equal(t, addrs[1], deposit.Depositor) require.Equal(t, fourSteak, deposit.Amount) depositsIterator.Next() require.False(t, depositsIterator.Valid()) diff --git a/x/gov/msgs.go b/x/gov/msgs.go index b8325d81c..6465b2a2d 100644 --- a/x/gov/msgs.go +++ b/x/gov/msgs.go @@ -85,14 +85,14 @@ func (msg MsgSubmitProposal) GetSigners() []sdk.AccAddress { // MsgDeposit type MsgDeposit struct { ProposalID uint64 `json:"proposal_id"` // ID of the proposal - Depositer sdk.AccAddress `json:"depositer"` // Address of the depositer + Depositor sdk.AccAddress `json:"depositor"` // Address of the depositor Amount sdk.Coins `json:"amount"` // Coins to add to the proposal's deposit } -func NewMsgDeposit(depositer sdk.AccAddress, proposalID uint64, amount sdk.Coins) MsgDeposit { +func NewMsgDeposit(depositor sdk.AccAddress, proposalID uint64, amount sdk.Coins) MsgDeposit { return MsgDeposit{ ProposalID: proposalID, - Depositer: depositer, + Depositor: depositor, Amount: amount, } } @@ -104,8 +104,8 @@ func (msg MsgDeposit) Type() string { return "deposit" } // Implements Msg. func (msg MsgDeposit) ValidateBasic() sdk.Error { - if len(msg.Depositer) == 0 { - return sdk.ErrInvalidAddress(msg.Depositer.String()) + if len(msg.Depositor) == 0 { + return sdk.ErrInvalidAddress(msg.Depositor.String()) } if !msg.Amount.IsValid() { return sdk.ErrInvalidCoins(msg.Amount.String()) @@ -120,7 +120,7 @@ func (msg MsgDeposit) ValidateBasic() sdk.Error { } func (msg MsgDeposit) String() string { - return fmt.Sprintf("MsgDeposit{%s=>%v: %v}", msg.Depositer, msg.ProposalID, msg.Amount) + return fmt.Sprintf("MsgDeposit{%s=>%v: %v}", msg.Depositor, msg.ProposalID, msg.Amount) } // Implements Msg. @@ -139,7 +139,7 @@ func (msg MsgDeposit) GetSignBytes() []byte { // Implements Msg. func (msg MsgDeposit) GetSigners() []sdk.AccAddress { - return []sdk.AccAddress{msg.Depositer} + return []sdk.AccAddress{msg.Depositor} } //----------------------------------------------------------- diff --git a/x/gov/msgs_test.go b/x/gov/msgs_test.go index 4a661985c..36bc10a6a 100644 --- a/x/gov/msgs_test.go +++ b/x/gov/msgs_test.go @@ -57,7 +57,7 @@ func TestMsgDeposit(t *testing.T) { _, addrs, _, _ := mock.CreateGenAccounts(1, sdk.Coins{}) tests := []struct { proposalID uint64 - depositerAddr sdk.AccAddress + depositorAddr sdk.AccAddress depositAmount sdk.Coins expectPass bool }{ @@ -68,7 +68,7 @@ func TestMsgDeposit(t *testing.T) { } for i, tc := range tests { - msg := NewMsgDeposit(tc.depositerAddr, tc.proposalID, tc.depositAmount) + msg := NewMsgDeposit(tc.depositorAddr, tc.proposalID, tc.depositAmount) if tc.expectPass { require.NoError(t, msg.ValidateBasic(), "test: %v", i) } else { diff --git a/x/gov/querier.go b/x/gov/querier.go index 171ab469d..cde85bf94 100644 --- a/x/gov/querier.go +++ b/x/gov/querier.go @@ -25,7 +25,7 @@ const ( ) func NewQuerier(keeper Keeper) sdk.Querier { - return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) { switch path[0] { case QueryParams: return queryParams(ctx, path[1:], req, keeper) @@ -49,42 +49,53 @@ func NewQuerier(keeper Keeper) sdk.Querier { } } -func queryParams(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { +func queryParams(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { switch path[0] { case ParamDeposit: - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, keeper.GetDepositParams(ctx)) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + bz, err := codec.MarshalJSONIndent(keeper.cdc, keeper.GetDepositParams(ctx)) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil case ParamVoting: - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, keeper.GetVotingParams(ctx)) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + bz, err := codec.MarshalJSONIndent(keeper.cdc, keeper.GetVotingParams(ctx)) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil case ParamTallying: - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, keeper.GetTallyParams(ctx)) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + bz, err := codec.MarshalJSONIndent(keeper.cdc, keeper.GetTallyParams(ctx)) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil default: - return res, sdk.ErrUnknownRequest(fmt.Sprintf("%s is not a valid query request path", req.Path)) + return nil, sdk.ErrUnknownRequest(fmt.Sprintf("%s is not a valid query request path", req.Path)) } } -// Params for query 'custom/gov/proposal' +// Params for queries: +// - 'custom/gov/proposal' +// - 'custom/gov/deposits' +// - 'custom/gov/tally' +// - 'custom/gov/votes' type QueryProposalParams struct { ProposalID uint64 } +// creates a new instance of QueryProposalParams +func NewQueryProposalParams(proposalID uint64) QueryProposalParams { + return QueryProposalParams{ + ProposalID: proposalID, + } +} + // nolint: unparam -func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { +func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { var params QueryProposalParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err2.Error())) + err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) } proposal := keeper.GetProposal(ctx, params.ProposalID) @@ -92,9 +103,9 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper return nil, ErrUnknownProposal(DefaultCodespace, params.ProposalID) } - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, proposal) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + bz, err := codec.MarshalJSONIndent(keeper.cdc, proposal) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil } @@ -102,21 +113,29 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper // Params for query 'custom/gov/deposit' type QueryDepositParams struct { ProposalID uint64 - Depositer sdk.AccAddress + Depositor sdk.AccAddress +} + +// creates a new instance of QueryDepositParams +func NewQueryDepositParams(proposalID uint64, depositor sdk.AccAddress) QueryDepositParams { + return QueryDepositParams{ + ProposalID: proposalID, + Depositor: depositor, + } } // nolint: unparam -func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { +func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { var params QueryDepositParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err2.Error())) + err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) } - deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositer) - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, deposit) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositor) + bz, err := codec.MarshalJSONIndent(keeper.cdc, deposit) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil } @@ -127,33 +146,36 @@ type QueryVoteParams struct { Voter sdk.AccAddress } +// creates a new instance of QueryVoteParams +func NewQueryVoteParams(proposalID uint64, voter sdk.AccAddress) QueryVoteParams { + return QueryVoteParams{ + ProposalID: proposalID, + Voter: voter, + } +} + // nolint: unparam -func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { +func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { var params QueryVoteParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err2.Error())) + err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) } vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter) - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, vote) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + bz, err := codec.MarshalJSONIndent(keeper.cdc, vote) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil } -// Params for query 'custom/gov/deposits' -type QueryDepositsParams struct { - ProposalID uint64 -} - // nolint: unparam -func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { - var params QueryDepositsParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err2.Error())) +func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { + var params QueryProposalParams + err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) } var deposits []Deposit @@ -164,80 +186,19 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper deposits = append(deposits, deposit) } - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, deposits) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + bz, err := codec.MarshalJSONIndent(keeper.cdc, deposits) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil } -// Params for query 'custom/gov/votes' -type QueryVotesParams struct { - ProposalID uint64 -} - // nolint: unparam -func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { - var params QueryVotesParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - - if err2 != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err2.Error())) - } - - var votes []Vote - votesIterator := keeper.GetVotes(ctx, params.ProposalID) - for ; votesIterator.Valid(); votesIterator.Next() { - vote := Vote{} - keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote) - votes = append(votes, vote) - } - - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, votes) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) - } - return bz, nil -} - -// Params for query 'custom/gov/proposals' -type QueryProposalsParams struct { - Voter sdk.AccAddress - Depositer sdk.AccAddress - ProposalStatus ProposalStatus - Limit uint64 -} - -// nolint: unparam -func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { - var params QueryProposalsParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err2.Error())) - } - - proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.Limit) - - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, proposals) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) - } - return bz, nil -} - -// Params for query 'custom/gov/tally' -type QueryTallyParams struct { - ProposalID uint64 -} - -// nolint: unparam -func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { - // TODO: Dependant on #1914 - - var params QueryTallyParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err2.Error())) +func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { + var params QueryProposalParams + err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) } proposalID := params.ProposalID @@ -254,12 +215,72 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke } else if proposal.GetStatus() == StatusPassed || proposal.GetStatus() == StatusRejected { tallyResult = proposal.GetTallyResult() } else { + // proposal is in voting period _, tallyResult = tally(ctx, keeper, proposal) } - bz, err2 := codec.MarshalJSONIndent(keeper.cdc, tallyResult) - if err2 != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err2.Error())) + bz, err := codec.MarshalJSONIndent(keeper.cdc, tallyResult) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + return bz, nil +} + +// nolint: unparam +func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { + var params QueryProposalParams + err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + + if err != nil { + return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + } + + var votes []Vote + votesIterator := keeper.GetVotes(ctx, params.ProposalID) + for ; votesIterator.Valid(); votesIterator.Next() { + vote := Vote{} + keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote) + votes = append(votes, vote) + } + + bz, err := codec.MarshalJSONIndent(keeper.cdc, votes) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) + } + return bz, nil +} + +// Params for query 'custom/gov/proposals' +type QueryProposalsParams struct { + Voter sdk.AccAddress + Depositor sdk.AccAddress + ProposalStatus ProposalStatus + Limit uint64 +} + +// creates a new instance of QueryProposalsParams +func NewQueryProposalsParams(status ProposalStatus, limit uint64, voter, depositor sdk.AccAddress) QueryProposalsParams { + return QueryProposalsParams{ + Voter: voter, + Depositor: depositor, + ProposalStatus: status, + Limit: limit, + } +} + +// nolint: unparam +func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { + var params QueryProposalsParams + err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error())) + } + + proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositor, params.ProposalStatus, params.Limit) + + bz, err := codec.MarshalJSONIndent(keeper.cdc, proposals) + if err != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error())) } return bz, nil } diff --git a/x/gov/querier_test.go b/x/gov/querier_test.go index eee58d2ac..9ee71323e 100644 --- a/x/gov/querier_test.go +++ b/x/gov/querier_test.go @@ -56,9 +56,7 @@ func getQueriedParams(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier s func getQueriedProposal(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) Proposal { query := abci.RequestQuery{ Path: strings.Join([]string{"custom", "gov", QueryProposal}, "/"), - Data: cdc.MustMarshalJSON(QueryProposalParams{ - ProposalID: proposalID, - }), + Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), } bz, err := querier(ctx, []string{QueryProposal}, query) @@ -71,15 +69,10 @@ func getQueriedProposal(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier return proposal } -func getQueriedProposals(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, depositer, voter sdk.AccAddress, status ProposalStatus, limit uint64) []Proposal { +func getQueriedProposals(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, depositor, voter sdk.AccAddress, status ProposalStatus, limit uint64) []Proposal { query := abci.RequestQuery{ Path: strings.Join([]string{"custom", "gov", QueryProposals}, "/"), - Data: cdc.MustMarshalJSON(QueryProposalsParams{ - Voter: voter, - Depositer: depositer, - ProposalStatus: status, - Limit: limit, - }), + Data: cdc.MustMarshalJSON(NewQueryProposalsParams(status, limit, voter, depositor)), } bz, err := querier(ctx, []string{QueryProposal}, query) @@ -92,13 +85,10 @@ func getQueriedProposals(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querie return proposals } -func getQueriedDeposit(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64, depositer sdk.AccAddress) Deposit { +func getQueriedDeposit(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64, depositor sdk.AccAddress) Deposit { query := abci.RequestQuery{ Path: strings.Join([]string{"custom", "gov", QueryDeposit}, "/"), - Data: cdc.MustMarshalJSON(QueryDepositParams{ - ProposalID: proposalID, - Depositer: depositer, - }), + Data: cdc.MustMarshalJSON(NewQueryDepositParams(proposalID, depositor)), } bz, err := querier(ctx, []string{QueryDeposits}, query) @@ -114,9 +104,7 @@ func getQueriedDeposit(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier func getQueriedDeposits(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) []Deposit { query := abci.RequestQuery{ Path: strings.Join([]string{"custom", "gov", QueryDeposits}, "/"), - Data: cdc.MustMarshalJSON(QueryDepositsParams{ - ProposalID: proposalID, - }), + Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), } bz, err := querier(ctx, []string{QueryDeposits}, query) @@ -132,10 +120,7 @@ func getQueriedDeposits(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier func getQueriedVote(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64, voter sdk.AccAddress) Vote { query := abci.RequestQuery{ Path: strings.Join([]string{"custom", "gov", QueryVote}, "/"), - Data: cdc.MustMarshalJSON(QueryVoteParams{ - ProposalID: proposalID, - Voter: voter, - }), + Data: cdc.MustMarshalJSON(NewQueryVoteParams(proposalID, voter)), } bz, err := querier(ctx, []string{QueryVote}, query) @@ -151,9 +136,7 @@ func getQueriedVote(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk func getQueriedVotes(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) []Vote { query := abci.RequestQuery{ Path: strings.Join([]string{"custom", "gov", QueryVote}, "/"), - Data: cdc.MustMarshalJSON(QueryVotesParams{ - ProposalID: proposalID, - }), + Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), } bz, err := querier(ctx, []string{QueryVotes}, query) @@ -169,9 +152,7 @@ func getQueriedVotes(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sd func getQueriedTally(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, proposalID uint64) TallyResult { query := abci.RequestQuery{ Path: strings.Join([]string{"custom", "gov", QueryTally}, "/"), - Data: cdc.MustMarshalJSON(QueryTallyParams{ - ProposalID: proposalID, - }), + Data: cdc.MustMarshalJSON(NewQueryProposalParams(proposalID)), } bz, err := querier(ctx, []string{QueryTally}, query) diff --git a/x/gov/tags/tags.go b/x/gov/tags/tags.go index 2eded1901..954acc5ed 100644 --- a/x/gov/tags/tags.go +++ b/x/gov/tags/tags.go @@ -17,6 +17,6 @@ var ( Proposer = "proposer" ProposalID = "proposal-id" VotingPeriodStart = "voting-period-start" - Depositer = "depositer" + Depositor = "depositor" Voter = "voter" ) diff --git a/x/ibc/client/cli/ibctx.go b/x/ibc/client/cli/ibctx.go index e8b107d9a..afe3824fc 100644 --- a/x/ibc/client/cli/ibctx.go +++ b/x/ibc/client/cli/ibctx.go @@ -2,6 +2,7 @@ package cli import ( "encoding/hex" + "os" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -41,7 +42,7 @@ func IBCTransferCmd(cdc *codec.Codec) *cobra.Command { return err } if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg}) diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index 7124b3544..513710ce4 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" "github.com/cosmos/cosmos-sdk/x/slashing" + "os" "github.com/spf13/cobra" ) @@ -30,7 +31,7 @@ func GetCmdUnjail(cdc *codec.Codec) *cobra.Command { msg := slashing.NewMsgUnjail(sdk.ValAddress(valAddr)) if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg}) }, diff --git a/x/stake/client/cli/tx.go b/x/stake/client/cli/tx.go index 09b235abb..f730e017f 100644 --- a/x/stake/client/cli/tx.go +++ b/x/stake/client/cli/tx.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "os" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -26,76 +27,13 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command { WithCodec(cdc). WithAccountDecoder(cdc) - amounstStr := viper.GetString(FlagAmount) - if amounstStr == "" { - return fmt.Errorf("Must specify amount to stake using --amount") - } - amount, err := sdk.ParseCoin(amounstStr) + cliCtx, txBldr, msg, err := BuildCreateValidatorMsg(cliCtx, txBldr) if err != nil { return err } - valAddr, err := cliCtx.GetFromAddress() - if err != nil { - return err - } - - pkStr := viper.GetString(FlagPubKey) - if len(pkStr) == 0 { - return fmt.Errorf("must use --pubkey flag") - } - - pk, err := sdk.GetConsPubKeyBech32(pkStr) - if err != nil { - return err - } - - if viper.GetString(FlagMoniker) == "" { - return fmt.Errorf("please enter a moniker for the validator using --moniker") - } - - description := stake.Description{ - Moniker: viper.GetString(FlagMoniker), - Identity: viper.GetString(FlagIdentity), - Website: viper.GetString(FlagWebsite), - Details: viper.GetString(FlagDetails), - } - - // get the initial validator commission parameters - rateStr := viper.GetString(FlagCommissionRate) - maxRateStr := viper.GetString(FlagCommissionMaxRate) - maxChangeRateStr := viper.GetString(FlagCommissionMaxChangeRate) - commissionMsg, err := buildCommissionMsg(rateStr, maxRateStr, maxChangeRateStr) - if err != nil { - return err - } - - var msg sdk.Msg - if viper.GetString(FlagAddressDelegator) != "" { - delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator)) - if err != nil { - return err - } - - msg = stake.NewMsgCreateValidatorOnBehalfOf( - delAddr, sdk.ValAddress(valAddr), pk, amount, description, commissionMsg, - ) - } else { - msg = stake.NewMsgCreateValidator( - sdk.ValAddress(valAddr), pk, amount, description, commissionMsg, - ) - } - - if viper.GetBool(FlagGenesisFormat) { - ip := viper.GetString(FlagIP) - nodeID := viper.GetString(FlagNodeID) - if nodeID != "" && ip != "" { - txBldr = txBldr.WithMemo(fmt.Sprintf("%s@%s:26656", nodeID, ip)) - } - } - if viper.GetBool(FlagGenesisFormat) || cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, true) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, true) } // build and sign the transaction, then broadcast to Tendermint @@ -112,6 +50,9 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command { cmd.Flags().String(FlagIP, "", fmt.Sprintf("Node's public IP. It takes effect only when used in combination with --%s", FlagGenesisFormat)) cmd.Flags().String(FlagNodeID, "", "Node's ID") cmd.MarkFlagRequired(client.FlagFrom) + cmd.MarkFlagRequired(FlagAmount) + cmd.MarkFlagRequired(FlagPubKey) + cmd.MarkFlagRequired(FlagMoniker) return cmd } @@ -154,7 +95,7 @@ func GetCmdEditValidator(cdc *codec.Codec) *cobra.Command { msg := stake.NewMsgEditValidator(sdk.ValAddress(valAddr), description, newRate) if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } // build and sign the transaction, then broadcast to Tendermint @@ -197,7 +138,7 @@ func GetCmdDelegate(cdc *codec.Codec) *cobra.Command { msg := stake.NewMsgDelegate(delAddr, valAddr, amount) if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } // build and sign the transaction, then broadcast to Tendermint return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg}) @@ -252,7 +193,7 @@ func GetCmdRedelegate(storeName string, cdc *codec.Codec) *cobra.Command { msg := stake.NewMsgBeginRedelegate(delAddr, valSrcAddr, valDstAddr, sharesAmount) if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } // build and sign the transaction, then broadcast to Tendermint return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg}) @@ -300,7 +241,7 @@ func GetCmdUnbond(storeName string, cdc *codec.Codec) *cobra.Command { msg := stake.NewMsgBeginUnbonding(delAddr, valAddr, sharesAmount) if cliCtx.GenerateOnly { - return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false) + return utils.PrintUnsignedStdTx(os.Stdout, txBldr, cliCtx, []sdk.Msg{msg}, false) } // build and sign the transaction, then broadcast to Tendermint return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg}) @@ -312,3 +253,64 @@ func GetCmdUnbond(storeName string, cdc *codec.Codec) *cobra.Command { return cmd } + +// BuildCreateValidatorMsg makes a new MsgCreateValidator. +func BuildCreateValidatorMsg(cliCtx context.CLIContext, txBldr authtxb.TxBuilder) (context.CLIContext, authtxb.TxBuilder, sdk.Msg, error) { + amounstStr := viper.GetString(FlagAmount) + amount, err := sdk.ParseCoin(amounstStr) + if err != nil { + return cliCtx, txBldr, nil, err + } + + valAddr, err := cliCtx.GetFromAddress() + if err != nil { + return cliCtx, txBldr, nil, err + } + + pkStr := viper.GetString(FlagPubKey) + pk, err := sdk.GetConsPubKeyBech32(pkStr) + if err != nil { + return cliCtx, txBldr, nil, err + } + + description := stake.NewDescription( + viper.GetString(FlagMoniker), + viper.GetString(FlagIdentity), + viper.GetString(FlagWebsite), + viper.GetString(FlagDetails), + ) + + // get the initial validator commission parameters + rateStr := viper.GetString(FlagCommissionRate) + maxRateStr := viper.GetString(FlagCommissionMaxRate) + maxChangeRateStr := viper.GetString(FlagCommissionMaxChangeRate) + commissionMsg, err := buildCommissionMsg(rateStr, maxRateStr, maxChangeRateStr) + if err != nil { + return cliCtx, txBldr, nil, err + } + + var msg sdk.Msg + if viper.GetString(FlagAddressDelegator) != "" { + delAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator)) + if err != nil { + return cliCtx, txBldr, nil, err + } + + msg = stake.NewMsgCreateValidatorOnBehalfOf( + delAddr, sdk.ValAddress(valAddr), pk, amount, description, commissionMsg, + ) + } else { + msg = stake.NewMsgCreateValidator( + sdk.ValAddress(valAddr), pk, amount, description, commissionMsg, + ) + } + + if viper.GetBool(FlagGenesisFormat) { + ip := viper.GetString(FlagIP) + nodeID := viper.GetString(FlagNodeID) + if nodeID != "" && ip != "" { + txBldr = txBldr.WithMemo(fmt.Sprintf("%s@%s:26656", nodeID, ip)) + } + } + return cliCtx, txBldr, msg, nil +} diff --git a/x/stake/querier/queryable.go b/x/stake/querier/querier.go similarity index 100% rename from x/stake/querier/queryable.go rename to x/stake/querier/querier.go diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/querier_test.go similarity index 100% rename from x/stake/querier/queryable_test.go rename to x/stake/querier/querier_test.go