Add fees and memo to REST, updated CLI to receive coins as fees (#3069)

This commit is contained in:
Federico Kunze 2018-12-19 21:26:33 -03:00 committed by Jack Zampolin
parent c9ef680f67
commit f02f7aa5a0
24 changed files with 461 additions and 397 deletions

View File

@ -3,11 +3,13 @@
BREAKING CHANGES
* Gaia REST API (`gaiacli advanced rest-server`)
* [gaia-lite] [\#2182] Renamed and merged all redelegations endpoints into `/stake/redelegations`
* Gaia CLI (`gaiacli`)
* [\#810](https://github.com/cosmos/cosmos-sdk/issues/810) Don't fallback to any default values for chain ID.
- Users need to supply chain ID either via config file or the `--chain-id` flag.
- Change `chain_id` and `trust_node` in `gaiacli` configuration to `chain-id` and `trust-node` respectively.
* Users need to supply chain ID either via config file or the `--chain-id` flag.
* Change `chain_id` and `trust_node` in `gaiacli` configuration to `chain-id` and `trust-node` respectively.
* [\#3069](https://github.com/cosmos/cosmos-sdk/pull/3069) `--fee` flag renamed to `--fees` to support multiple coins
* [\#3156](https://github.com/cosmos/cosmos-sdk/pull/3156) Remove unimplemented `gaiacli init` command
* Gaia
@ -22,14 +24,13 @@ BREAKING CHANGES
FEATURES
* Gaia REST API (`gaiacli advanced rest-server`)
* [gaia-lite] [\#2182] Added LCD endpoint for querying redelegations
* [gov] [\#2479](https://github.com/cosmos/cosmos-sdk/issues/2479) Added governance parameter
query REST endpoints.
* [\#3067](https://github.com/cosmos/cosmos-sdk/issues/3067) Add support for fees on transactions
* [\#3069](https://github.com/cosmos/cosmos-sdk/pull/3069) Add a custom memo on transactions
* Gaia CLI (`gaiacli`)
* \#2399 Implement `params` command to query slashing parameters.
* Gaia
* [\#2182] [x/stake] Added querier for querying a single redelegation
* SDK

View File

@ -1,6 +1,7 @@
package client
import (
"errors"
"fmt"
"strconv"
@ -29,7 +30,7 @@ const (
FlagAccountNumber = "account-number"
FlagSequence = "sequence"
FlagMemo = "memo"
FlagFee = "fee"
FlagFees = "fees"
FlagAsync = "async"
FlagJson = "json"
FlagPrintResponse = "print-response"
@ -78,7 +79,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
c.Flags().Uint64(FlagAccountNumber, 0, "AccountNumber number to sign the tx")
c.Flags().Uint64(FlagSequence, 0, "Sequence number to sign the tx")
c.Flags().String(FlagMemo, "", "Memo to send along with transaction")
c.Flags().String(FlagFee, "", "Fee to pay along with transaction")
c.Flags().String(FlagFees, "", "Fees to pay along with transaction; eg: 10stake,1atom")
c.Flags().String(FlagChainID, "", "Chain ID of tendermint node")
c.Flags().String(FlagNode, "tcp://localhost:26657", "<host>:<port> to tendermint rpc interface for this chain")
c.Flags().Bool(FlagUseLedger, false, "Use a connected Ledger device")
@ -135,7 +136,7 @@ func (v *GasSetting) Type() string { return "string" }
// Set parses and sets the value of the --gas flag.
func (v *GasSetting) Set(s string) (err error) {
v.Simulate, v.Gas, err = ReadGasFlag(s)
v.Simulate, v.Gas, err = ParseGas(s)
return
}
@ -146,17 +147,17 @@ func (v *GasSetting) String() string {
return strconv.FormatUint(v.Gas, 10)
}
// ParseGasFlag parses the value of the --gas flag.
func ReadGasFlag(s string) (simulate bool, gas uint64, err error) {
switch s {
// ParseGas parses the value of the gas option.
func ParseGas(gasStr string) (simulateAndExecute bool, gas uint64, err error) {
switch gasStr {
case "":
gas = DefaultGasLimit
case GasFlagSimulate:
simulate = true
simulateAndExecute = true
default:
gas, err = strconv.ParseUint(s, 10, 64)
gas, err = strconv.ParseUint(gasStr, 10, 64)
if err != nil {
err = fmt.Errorf("gas must be either integer or %q", GasFlagSimulate)
err = errors.New("gas must be a positive integer")
return
}
}

View File

@ -35,10 +35,13 @@ const (
name1 = "test1"
name2 = "test2"
name3 = "test3"
memo = "LCD test tx"
pw = app.DefaultKeyPass
altPw = "12345678901"
)
var fees = sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 5)}
func init() {
mintkey.BcryptSecurityParameter = 1
version.Version = os.Getenv("VERSION")
@ -160,7 +163,7 @@ func TestCoinSend(t *testing.T) {
initialBalance := acc.GetCoins()
// create TX
receiveAddr, resultTx := doTransfer(t, port, seed, name1, pw, addr)
receiveAddr, resultTx := doTransfer(t, port, seed, name1, memo, pw, addr, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
@ -170,44 +173,52 @@ func TestCoinSend(t *testing.T) {
// query sender
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
mycoins := coins[0]
expectedBalance := initialBalance[0].Minus(fees[0])
require.Equal(t, stakeTypes.DefaultBondDenom, mycoins.Denom)
require.Equal(t, initialBalance[0].Amount.SubRaw(1), mycoins.Amount)
require.Equal(t, stakeTypes.DefaultBondDenom, coins[0].Denom)
require.Equal(t, expectedBalance.Amount.SubRaw(1), coins[0].Amount)
expectedBalance = coins[0]
// query receiver
acc = getAccount(t, port, receiveAddr)
coins = acc.GetCoins()
mycoins = coins[0]
require.Equal(t, stakeTypes.DefaultBondDenom, mycoins.Denom)
require.Equal(t, int64(1), mycoins.Amount.Int64())
acc2 := getAccount(t, port, receiveAddr)
coins2 := acc2.GetCoins()
require.Equal(t, stakeTypes.DefaultBondDenom, coins2[0].Denom)
require.Equal(t, int64(1), coins2[0].Amount.Int64())
// test failure with too little gas
res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "100", 0, false, false)
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "100", 0, false, false, fees)
require.Equal(t, http.StatusInternalServerError, res.StatusCode, body)
require.Nil(t, err)
// test failure with negative gas
res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "-200", 0, false, false)
// test failure with negative adjustment
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "10000", -0.1, true, false, fees)
require.Equal(t, http.StatusBadRequest, res.StatusCode, body)
// test failure with 0 gas
res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "0", 0, false, false)
require.Equal(t, http.StatusInternalServerError, res.StatusCode, body)
// test failure with wrong adjustment
res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "simulate", 0.1, false, false)
require.Equal(t, http.StatusInternalServerError, res.StatusCode, body)
// run simulation and test success with estimated gas
res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, "", 0, true, false)
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "10000", 1.0, true, false, fees)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var responseBody struct {
GasEstimate int64 `json:"gas_estimate"`
}
require.Nil(t, json.Unmarshal([]byte(body), &responseBody))
res, body, _ = doTransferWithGas(t, port, seed, name1, pw, addr, fmt.Sprintf("%v", responseBody.GasEstimate), 0, false, false)
acc = getAccount(t, port, addr)
require.Equal(t, expectedBalance.Amount, acc.GetCoins().AmountOf(stakeTypes.DefaultBondDenom))
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr,
fmt.Sprintf("%d", responseBody.GasEstimate), 1.0, false, false, fees)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err = cdc.UnmarshalJSON([]byte(body), &resultTx)
require.Nil(t, err)
tests.WaitForHeight(resultTx.Height+1, port)
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
acc = getAccount(t, port, addr)
expectedBalance = expectedBalance.Minus(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(1), acc.GetCoins().AmountOf(stakeTypes.DefaultBondDenom))
}
func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
@ -217,7 +228,7 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
acc := getAccount(t, port, addr)
// generate TX
res, body, _ := doTransferWithGas(t, port, seed, name1, pw, addr, "simulate", 0, false, true)
res, body, _ := doTransferWithGas(t, port, seed, name1, memo, "", addr, "200000", 1, false, true, fees)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var msg auth.StdTx
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &msg))
@ -225,7 +236,9 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
require.Equal(t, msg.Msgs[0].Route(), "bank")
require.Equal(t, msg.Msgs[0].GetSigners(), []sdk.AccAddress{addr})
require.Equal(t, 0, len(msg.Signatures))
gasEstimate := msg.Fee.Gas
require.Equal(t, memo, msg.Memo)
gasEstimate := int64(msg.Fee.Gas)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
@ -265,8 +278,7 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &resultTx))
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
require.Equal(t, gasEstimate, uint64(resultTx.DeliverTx.GasWanted))
require.Equal(t, gasEstimate, uint64(resultTx.DeliverTx.GasUsed))
require.Equal(t, gasEstimate, resultTx.DeliverTx.GasWanted)
}
func TestTxs(t *testing.T) {
@ -290,7 +302,7 @@ func TestTxs(t *testing.T) {
require.Equal(t, emptyTxs, txs)
// create tx
receiveAddr, resultTx := doTransfer(t, port, seed, name1, pw, addr)
receiveAddr, resultTx := doTransfer(t, port, seed, name1, memo, pw, addr, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx is queryable
@ -301,6 +313,7 @@ func TestTxs(t *testing.T) {
txs = getTransactions(t, port, fmt.Sprintf("sender=%s", addr.String()))
require.Len(t, txs, 1)
require.Equal(t, resultTx.Height, txs[0].Height)
fmt.Println(txs[0])
// query recipient
txs = getTransactions(t, port, fmt.Sprintf("recipient=%s", receiveAddr.String()))
@ -371,8 +384,11 @@ func TestBonding(t *testing.T) {
amt := sdk.NewDec(60)
validator := getValidator(t, port, operAddrs[0])
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create bond TX
resultTx := doDelegate(t, port, name1, pw, addr, operAddrs[0], 60)
resultTx := doDelegate(t, port, name1, pw, addr, operAddrs[0], 60, fees)
tests.WaitForHeight(resultTx.Height+1, port)
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
@ -386,10 +402,12 @@ func TestBonding(t *testing.T) {
require.Len(t, txs, 1)
require.Equal(t, resultTx.Height, txs[0].Height)
acc := getAccount(t, port, addr)
// verify balance
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
require.Equal(t, int64(40), coins.AmountOf(stakeTypes.DefaultBondDenom).Int64())
expectedBalance := initialBalance[0].Minus(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(60), coins.AmountOf(stakeTypes.DefaultBondDenom))
expectedBalance = coins[0]
// query delegation
bond := getDelegation(t, port, addr, operAddrs[0])
@ -412,7 +430,7 @@ func TestBonding(t *testing.T) {
require.Equal(t, operAddrs[0], bondedValidator.OperatorAddr)
// testing unbonding
resultTx = doBeginUnbonding(t, port, name1, pw, addr, operAddrs[0], 30)
resultTx = doBeginUnbonding(t, port, name1, pw, addr, operAddrs[0], 30, fees)
tests.WaitForHeight(resultTx.Height+1, port)
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
@ -421,7 +439,13 @@ func TestBonding(t *testing.T) {
// sender should have not received any coins as the unbonding has only just begun
acc = getAccount(t, port, addr)
coins = acc.GetCoins()
require.Equal(t, int64(40), coins.AmountOf(stakeTypes.DefaultBondDenom).Int64())
expectedBalance = expectedBalance.Minus(fees[0])
require.True(t,
expectedBalance.Amount.LT(coins.AmountOf(stakeTypes.DefaultBondDenom)) ||
expectedBalance.Amount.Equal(coins.AmountOf(stakeTypes.DefaultBondDenom)),
"should get tokens back from automatic withdrawal after an unbonding delegation",
)
expectedBalance = coins[0]
// query tx
txs = getTransactions(t, port,
@ -432,15 +456,24 @@ func TestBonding(t *testing.T) {
require.Equal(t, resultTx.Height, txs[0].Height)
unbonding := getUndelegation(t, port, addr, operAddrs[0])
require.Equal(t, "30", unbonding.Balance.Amount.String())
require.Equal(t, int64(30), unbonding.Balance.Amount.Int64())
// test redelegation
resultTx = doBeginRedelegation(t, port, name1, pw, addr, operAddrs[0], operAddrs[1], 30)
resultTx = doBeginRedelegation(t, port, name1, pw, addr, operAddrs[0], operAddrs[1], 30, fees)
tests.WaitForHeight(resultTx.Height+1, port)
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// verify balance after paying fees
acc = getAccount(t, port, addr)
expectedBalance = expectedBalance.Minus(fees[0])
require.True(t,
expectedBalance.Amount.LT(coins.AmountOf(stakeTypes.DefaultBondDenom)) ||
expectedBalance.Amount.Equal(coins.AmountOf(stakeTypes.DefaultBondDenom)),
"should get tokens back from automatic withdrawal after an unbonding delegation",
)
// query tx
txs = getTransactions(t, port,
fmt.Sprintf("action=begin_redelegate&delegator=%s", addr),
@ -497,8 +530,11 @@ func TestSubmitProposal(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create SubmitProposal TX
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5)
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
@ -508,6 +544,11 @@ func TestSubmitProposal(t *testing.T) {
var proposalID uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID)
// verify balance
acc = getAccount(t, port, addr)
expectedBalance := initialBalance[0].Minus(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(5), acc.GetCoins().AmountOf(stakeTypes.DefaultBondDenom))
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
@ -523,8 +564,11 @@ func TestDeposit(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create SubmitProposal TX
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5)
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
@ -534,14 +578,26 @@ func TestDeposit(t *testing.T) {
var proposalID uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID)
// verify balance
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
expectedBalance := initialBalance[0].Minus(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(5), coins.AmountOf(stakeTypes.DefaultBondDenom))
expectedBalance = coins[0]
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
// create SubmitProposal TX
resultTx = doDeposit(t, port, seed, name1, pw, addr, proposalID, 5)
resultTx = doDeposit(t, port, seed, name1, pw, addr, proposalID, 5, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// verify balance after deposit and fee
acc = getAccount(t, port, addr)
expectedBalance = expectedBalance.Minus(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(5), acc.GetCoins().AmountOf(stakeTypes.DefaultBondDenom))
// query tx
txs := getTransactions(t, port, fmt.Sprintf("action=deposit&depositor=%s", addr))
require.Len(t, txs, 1)
@ -561,8 +617,11 @@ func TestVote(t *testing.T) {
cleanup, _, operAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create SubmitProposal TX
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 5)
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, 10, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
@ -572,22 +631,29 @@ func TestVote(t *testing.T) {
var proposalID uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID)
// verify balance
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
expectedBalance := initialBalance[0].Minus(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(10), coins.AmountOf(stakeTypes.DefaultBondDenom))
expectedBalance = coins[0]
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
// deposit
resultTx = doDeposit(t, port, seed, name1, pw, addr, proposalID, 5)
tests.WaitForHeight(resultTx.Height+1, port)
// query proposal
proposal = getProposal(t, port, proposalID)
require.Equal(t, gov.StatusVotingPeriod, proposal.GetStatus())
// vote
resultTx = doVote(t, port, seed, name1, pw, addr, proposalID)
resultTx = doVote(t, port, seed, name1, pw, addr, proposalID, "Yes", fees)
tests.WaitForHeight(resultTx.Height+1, port)
// verify balance after vote and fee
acc = getAccount(t, port, addr)
coins = acc.GetCoins()
expectedBalance = expectedBalance.Minus(fees[0])
require.Equal(t, expectedBalance.Amount, coins.AmountOf(stakeTypes.DefaultBondDenom))
expectedBalance = coins[0]
// query tx
txs := getTransactions(t, port, fmt.Sprintf("action=vote&voter=%s", addr))
require.Len(t, txs, 1)
@ -601,15 +667,31 @@ func TestVote(t *testing.T) {
require.Equal(t, sdk.ZeroDec(), tally.Yes, "tally should be 0 as the address is not bonded")
// create bond TX
resultTx = doDelegate(t, port, name1, pw, addr, operAddrs[0], 60)
resultTx = doDelegate(t, port, name1, pw, addr, operAddrs[0], 60, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// vote
resultTx = doVote(t, port, seed, name1, pw, addr, proposalID)
tests.WaitForHeight(resultTx.Height+1, port)
// verify balance
acc = getAccount(t, port, addr)
coins = acc.GetCoins()
expectedBalance = expectedBalance.Minus(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(60), coins.AmountOf(stakeTypes.DefaultBondDenom))
expectedBalance = coins[0]
tally = getTally(t, port, proposalID)
require.Equal(t, sdk.NewDec(60), tally.Yes, "tally should be equal to the amount delegated")
// change vote option
resultTx = doVote(t, port, seed, name1, pw, addr, proposalID, "No", fees)
tests.WaitForHeight(resultTx.Height+1, port)
// verify balance
acc = getAccount(t, port, addr)
expectedBalance = expectedBalance.Minus(fees[0])
require.Equal(t, expectedBalance.Amount, acc.GetCoins().AmountOf(stakeTypes.DefaultBondDenom))
tally = getTally(t, port, proposalID)
require.Equal(t, sdk.ZeroDec(), tally.Yes, "tally should be 0 the user changed the option")
require.Equal(t, sdk.NewDec(60), tally.No, "tally should be equal to the amount delegated")
}
func TestUnjail(t *testing.T) {
@ -639,27 +721,27 @@ func TestProposalsQuery(t *testing.T) {
getTallyingParam(t, port)
// Addr1 proposes (and deposits) proposals #1 and #2
resultTx := doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit)
resultTx := doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit, fees)
var proposalID1 uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID1)
tests.WaitForHeight(resultTx.Height+1, port)
resultTx = doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit)
resultTx = doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit, fees)
var proposalID2 uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID2)
tests.WaitForHeight(resultTx.Height+1, port)
// Addr2 proposes (and deposits) proposals #3
resultTx = doSubmitProposal(t, port, seeds[1], names[1], passwords[1], addrs[1], halfMinDeposit)
resultTx = doSubmitProposal(t, port, seeds[1], names[1], passwords[1], addrs[1], halfMinDeposit, fees)
var proposalID3 uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID3)
tests.WaitForHeight(resultTx.Height+1, port)
// Addr2 deposits on proposals #2 & #3
resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID2, halfMinDeposit)
resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID2, halfMinDeposit, fees)
tests.WaitForHeight(resultTx.Height+1, port)
resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3, halfMinDeposit)
resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3, halfMinDeposit, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check deposits match proposal and individual deposits
@ -681,7 +763,7 @@ func TestProposalsQuery(t *testing.T) {
require.Equal(t, deposit, deposits[0])
// increasing the amount of the deposit should update the existing one
resultTx = doDeposit(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID1, 1)
resultTx = doDeposit(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID1, 1, fees)
tests.WaitForHeight(resultTx.Height+1, port)
deposits = getDeposits(t, port, proposalID1)
@ -699,13 +781,13 @@ func TestProposalsQuery(t *testing.T) {
require.Equal(t, proposalID3, proposals[1].GetProposalID())
// Addr1 votes on proposals #2 & #3
resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID2)
resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID2, "Yes", fees)
tests.WaitForHeight(resultTx.Height+1, port)
resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID3)
resultTx = doVote(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID3, "Yes", fees)
tests.WaitForHeight(resultTx.Height+1, port)
// Addr2 votes on proposal #3
resultTx = doVote(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3)
resultTx = doVote(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3, "Yes", fees)
tests.WaitForHeight(resultTx.Height+1, port)
// Test query all proposals

View File

@ -834,7 +834,7 @@ paths:
items:
$ref: "#/definitions/Redelegation"
500:
description: Internal Server Error
description: Internal Server Error
/stake/delegators/{delegatorAddr}/redelegations:
parameters:
- in: path
@ -2199,23 +2199,32 @@ definitions:
properties:
name:
type: string
example: "my_name"
password:
type: string
example: "12345678"
memo:
type: string
example: "Sent via Cosmos Voyager 🚀"
chain_id:
type: string
example: "Cosmos-Hub"
account_number:
type: string
example: "0"
sequence:
type: string
example: "0"
example: "1"
gas:
type: string
example: "200000"
gas_adjustment:
type: string
example: "1.2"
fees:
type: array
items:
$ref: "#/definitions/Coin"
generate_only:
type: boolean
example: false

View File

@ -678,8 +678,8 @@ type broadcastReq struct {
// GET /bank/balances/{address} Get the account balances
// POST /bank/accounts/{address}/transfers Send coins (build -> sign -> send)
func doTransfer(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) {
res, body, receiveAddr := doTransferWithGas(t, port, seed, name, password, addr, "", 0, false, false)
func doTransfer(t *testing.T, port, seed, name, memo, password string, addr sdk.AccAddress, fees sdk.Coins) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) {
res, body, receiveAddr := doTransferWithGas(t, port, seed, name, memo, password, addr, "", 1.0, false, false, fees)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err := cdc.UnmarshalJSON([]byte(body), &resultTx)
@ -688,8 +688,8 @@ func doTransfer(t *testing.T, port, seed, name, password string, addr sdk.AccAdd
return receiveAddr, resultTx
}
func doTransferWithGas(t *testing.T, port, seed, name, password string, addr sdk.AccAddress, gas string,
gasAdjustment float64, simulate, generateOnly bool) (
func doTransferWithGas(t *testing.T, port, seed, name, memo, password string, addr sdk.AccAddress, gas string,
gasAdjustment float64, simulate, generateOnly bool, fees sdk.Coins) (
res *http.Response, body string, receiveAddr sdk.AccAddress) {
// create receive address
@ -703,25 +703,14 @@ func doTransferWithGas(t *testing.T, port, seed, name, password string, addr sdk
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := utils.NewBaseReq(name, password, memo, chainID, gas,
fmt.Sprintf("%f", gasAdjustment), accnum, sequence, fees,
generateOnly, simulate,
)
sr := sendReq{
Amount: sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 1)},
BaseReq: utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: accnum,
Sequence: sequence,
Simulate: simulate,
GenerateOnly: generateOnly,
},
}
if len(gas) != 0 {
sr.BaseReq.Gas = gas
}
if gasAdjustment > 0 {
sr.BaseReq.GasAdjustment = fmt.Sprintf("%f", gasAdjustment)
Amount: sdk.Coins{sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, 1)},
BaseReq: baseReq,
}
req, err := cdc.MarshalJSON(sr)
@ -742,32 +731,28 @@ type sendReq struct {
// POST /stake/delegators/{delegatorAddr}/delegations Submit delegation
func doDelegate(t *testing.T, port, name, password string,
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
acc := getAccount(t, port, delAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
ed := msgDelegationsInput{
BaseReq: utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: accnum,
Sequence: sequence,
},
baseReq := utils.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, false, false)
msg := msgDelegationsInput{
BaseReq: baseReq,
DelegatorAddr: delAddr,
ValidatorAddr: valAddr,
Delegation: sdk.NewInt64Coin(stakeTypes.DefaultBondDenom, amount),
}
req, err := cdc.MarshalJSON(ed)
req, err := cdc.MarshalJSON(msg)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr.String()), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results ctypes.ResultBroadcastTxCommit
err = cdc.UnmarshalJSON([]byte(body), &results)
var result ctypes.ResultBroadcastTxCommit
err = cdc.UnmarshalJSON([]byte(body), &result)
require.Nil(t, err)
return results
return result
}
type msgDelegationsInput struct {
@ -779,35 +764,30 @@ type msgDelegationsInput struct {
// POST /stake/delegators/{delegatorAddr}/delegations Submit delegation
func doBeginUnbonding(t *testing.T, port, name, password string,
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
acc := getAccount(t, port, delAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
ed := msgBeginUnbondingInput{
BaseReq: utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: accnum,
Sequence: sequence,
},
baseReq := utils.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, false, false)
msg := msgBeginUnbondingInput{
BaseReq: baseReq,
DelegatorAddr: delAddr,
ValidatorAddr: valAddr,
SharesAmount: sdk.NewDec(amount),
}
req, err := cdc.MarshalJSON(ed)
req, err := cdc.MarshalJSON(msg)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations", delAddr), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results ctypes.ResultBroadcastTxCommit
err = cdc.UnmarshalJSON([]byte(body), &results)
var result ctypes.ResultBroadcastTxCommit
err = cdc.UnmarshalJSON([]byte(body), &result)
require.Nil(t, err)
return results
return result
}
type msgBeginUnbondingInput struct {
@ -819,37 +799,33 @@ type msgBeginUnbondingInput struct {
// POST /stake/delegators/{delegatorAddr}/delegations Submit delegation
func doBeginRedelegation(t *testing.T, port, name, password string,
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount int64, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
acc := getAccount(t, port, delAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
ed := msgBeginRedelegateInput{
BaseReq: utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: accnum,
Sequence: sequence,
},
baseReq := utils.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, false, false)
msg := msgBeginRedelegateInput{
BaseReq: baseReq,
DelegatorAddr: delAddr,
ValidatorSrcAddr: valSrcAddr,
ValidatorDstAddr: valDstAddr,
SharesAmount: sdk.NewDec(amount),
}
req, err := cdc.MarshalJSON(ed)
req, err := cdc.MarshalJSON(msg)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/redelegations", delAddr), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results ctypes.ResultBroadcastTxCommit
err = cdc.UnmarshalJSON([]byte(body), &results)
var result ctypes.ResultBroadcastTxCommit
err = cdc.UnmarshalJSON([]byte(body), &result)
require.Nil(t, err)
return results
return result
}
type msgBeginRedelegateInput struct {
@ -1051,26 +1027,20 @@ func getStakeParams(t *testing.T, port string) stake.Params {
// ICS 22 - Gov
// ----------------------------------------------------------------------
// POST /gov/proposals Submit a proposal
func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, amount int64, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := utils.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, false, false)
pr := postProposalReq{
Title: "Test",
Description: "test",
ProposalType: "Text",
Proposer: proposerAddr,
InitialDeposit: sdk.Coins{sdk.NewCoin(stakeTypes.DefaultBondDenom, sdk.NewInt(amount))},
BaseReq: utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: accnum,
Sequence: sequence,
},
BaseReq: baseReq,
}
req, err := cdc.MarshalJSON(pr)
@ -1152,23 +1122,18 @@ func getProposalsFilterStatus(t *testing.T, port string, status gov.ProposalStat
}
// POST /gov/proposals/{proposalId}/deposits Deposit tokens to a proposal
func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64, amount int64, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := utils.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, false, false)
dr := depositReq{
Depositor: proposerAddr,
Amount: sdk.Coins{sdk.NewCoin(stakeTypes.DefaultBondDenom, sdk.NewInt(amount))},
BaseReq: utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: accnum,
Sequence: sequence,
},
BaseReq: baseReq,
}
req, err := cdc.MarshalJSON(dr)
@ -1211,23 +1176,18 @@ func getTally(t *testing.T, port string, proposalID uint64) gov.TallyResult {
}
// POST /gov/proposals/{proposalId}/votes Vote a proposal
func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64) (resultTx ctypes.ResultBroadcastTxCommit) {
func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID uint64, option string, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := utils.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, false, false)
vr := voteReq{
Voter: proposerAddr,
Option: "Yes",
BaseReq: utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: accnum,
Sequence: sequence,
},
Voter: proposerAddr,
Option: option,
BaseReq: baseReq,
}
req, err := cdc.MarshalJSON(vr)
@ -1340,16 +1300,13 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.
// TODO: Test this functionality, it is not currently in any of the tests
// POST /slashing/validators/{validatorAddr}/unjail Unjail a jailed validator
func doUnjail(t *testing.T, port, seed, name, password string,
valAddr sdk.ValAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
valAddr sdk.ValAddress, fees sdk.Coins) (resultTx ctypes.ResultBroadcastTxCommit) {
chainID := viper.GetString(client.FlagChainID)
baseReq := utils.NewBaseReq(name, password, "", chainID, "", "", 1, 1, fees, false, false)
ur := unjailReq{utils.BaseReq{
Name: name,
Password: password,
ChainID: chainID,
AccountNumber: 1,
Sequence: 1,
}}
ur := unjailReq{
BaseReq: baseReq,
}
req, err := cdc.MarshalJSON(ur)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/slashing/validators/%s/unjail", valAddr.String()), req)

View File

@ -101,30 +101,70 @@ func WriteGenerateStdTxResponse(w http.ResponseWriter, cdc *codec.Codec, txBldr
// BaseReq defines a structure that can be embedded in other request structures
// that all share common "base" fields.
type BaseReq struct {
Name string `json:"name"`
Password string `json:"password"`
ChainID string `json:"chain_id"`
AccountNumber uint64 `json:"account_number"`
Sequence uint64 `json:"sequence"`
Gas string `json:"gas"`
GasAdjustment string `json:"gas_adjustment"`
GenerateOnly bool `json:"generate_only"`
Simulate bool `json:"simulate"`
Name string `json:"name"`
Password string `json:"password"`
Memo string `json:"memo"`
ChainID string `json:"chain_id"`
AccountNumber uint64 `json:"account_number"`
Sequence uint64 `json:"sequence"`
Fees sdk.Coins `json:"fees"`
Gas string `json:"gas"`
GasAdjustment string `json:"gas_adjustment"`
GenerateOnly bool `json:"generate_only"`
Simulate bool `json:"simulate"`
}
// NewBaseReq creates a new basic request instance and sanitizes its values
func NewBaseReq(
name, password, memo, chainID string, gas, gasAdjustment string,
accNumber, seq uint64, fees sdk.Coins, genOnly, simulate bool) BaseReq {
return BaseReq{
Name: strings.TrimSpace(name),
Password: password,
Memo: strings.TrimSpace(memo),
ChainID: strings.TrimSpace(chainID),
Fees: fees,
Gas: strings.TrimSpace(gas),
GasAdjustment: strings.TrimSpace(gasAdjustment),
AccountNumber: accNumber,
Sequence: seq,
GenerateOnly: genOnly,
Simulate: simulate,
}
}
// Sanitize performs basic sanitization on a BaseReq object.
func (br BaseReq) Sanitize() BaseReq {
return BaseReq{
Name: strings.TrimSpace(br.Name),
Password: strings.TrimSpace(br.Password),
ChainID: strings.TrimSpace(br.ChainID),
Gas: strings.TrimSpace(br.Gas),
GasAdjustment: strings.TrimSpace(br.GasAdjustment),
AccountNumber: br.AccountNumber,
Sequence: br.Sequence,
GenerateOnly: br.GenerateOnly,
Simulate: br.Simulate,
newBr := NewBaseReq(
br.Name, br.Password, br.Memo, br.ChainID, br.Gas, br.GasAdjustment,
br.AccountNumber, br.Sequence, br.Fees, br.GenerateOnly, br.Simulate,
)
return newBr
}
// ValidateBasic performs basic validation of a BaseReq. If custom validation
// logic is needed, the implementing request handler should perform those
// checks manually.
func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool {
if !br.GenerateOnly && !br.Simulate {
switch {
case len(br.Password) == 0:
WriteErrorResponse(w, http.StatusUnauthorized, "password required but not specified")
return false
case len(br.ChainID) == 0:
WriteErrorResponse(w, http.StatusUnauthorized, "chain-id required but not specified")
return false
case !br.Fees.IsValid():
WriteErrorResponse(w, http.StatusPaymentRequired, "invalid or insufficient fees")
return false
}
}
if len(br.Name) == 0 {
WriteErrorResponse(w, http.StatusUnauthorized, "name required but not specified")
return false
}
return true
}
/*
@ -156,27 +196,6 @@ func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req i
return nil
}
// ValidateBasic performs basic validation of a BaseReq. If custom validation
// logic is needed, the implementing request handler should perform those
// checks manually.
func (br BaseReq) ValidateBasic(w http.ResponseWriter, cliCtx context.CLIContext) bool {
if !cliCtx.GenerateOnly && !cliCtx.Simulate {
switch {
case len(br.Password) == 0:
WriteErrorResponse(w, http.StatusUnauthorized, "password required but not specified")
return false
case len(br.ChainID) == 0:
WriteErrorResponse(w, http.StatusUnauthorized, "chain-id required but not specified")
return false
}
}
if len(br.Name) == 0 {
WriteErrorResponse(w, http.StatusUnauthorized, "name required but not specified")
return false
}
return true
}
// CompleteAndBroadcastTxREST implements a utility function that facilitates
// sending a series of messages in a signed transaction given a TxBuilder and a
// QueryContext. It ensures that the account exists, has a proper number and
@ -186,40 +205,37 @@ func (br BaseReq) ValidateBasic(w http.ResponseWriter, cliCtx context.CLIContext
// NOTE: Also see CompleteAndBroadcastTxCli.
// NOTE: Also see x/stake/client/rest/tx.go delegationsRequestHandlerFn.
func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx context.CLIContext, baseReq BaseReq, msgs []sdk.Msg, cdc *codec.Codec) {
simulateGas, gas, err := client.ReadGasFlag(baseReq.Gas)
gasAdjustment, ok := ParseFloat64OrReturnBadRequest(w, baseReq.GasAdjustment, client.DefaultGasAdjustment)
if !ok {
return
}
simulateAndExecute, gas, err := client.ParseGas(baseReq.Gas)
if err != nil {
WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
adjustment, ok := ParseFloat64OrReturnBadRequest(w, baseReq.GasAdjustment, client.DefaultGasAdjustment)
if !ok {
return
}
txBldr := authtxb.NewTxBuilder(GetTxEncoder(cdc), baseReq.AccountNumber,
baseReq.Sequence, gas, gasAdjustment, baseReq.Simulate,
baseReq.ChainID, baseReq.Memo, baseReq.Fees)
txBldr := authtxb.TxBuilder{
TxEncoder: GetTxEncoder(cdc),
Gas: gas,
GasAdjustment: adjustment,
SimulateGas: simulateGas,
ChainID: baseReq.ChainID,
AccountNumber: baseReq.AccountNumber,
Sequence: baseReq.Sequence,
}
if baseReq.Simulate || simulateAndExecute {
if gasAdjustment < 0 {
WriteErrorResponse(w, http.StatusBadRequest, "gas adjustment must be a positive float")
return
}
if baseReq.Simulate || txBldr.SimulateGas {
newBldr, err := EnrichCtxWithGas(txBldr, cliCtx, baseReq.Name, msgs)
txBldr, err = EnrichCtxWithGas(txBldr, cliCtx, baseReq.Name, msgs)
if err != nil {
WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
if baseReq.Simulate {
WriteSimulationResponse(w, newBldr.Gas)
WriteSimulationResponse(w, txBldr.GetGas())
return
}
txBldr = newBldr
}
if baseReq.GenerateOnly {

View File

@ -3,10 +3,11 @@ package utils
import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"io"
"os"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/libs/common"
@ -35,12 +36,12 @@ func CompleteAndBroadcastTxCli(txBldr authtxb.TxBuilder, cliCtx context.CLIConte
return err
}
if txBldr.SimulateGas || cliCtx.Simulate {
if txBldr.GetSimulateAndExecute() || cliCtx.Simulate {
txBldr, err = EnrichCtxWithGas(txBldr, cliCtx, name, msgs)
if err != nil {
return err
}
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas)
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.GetGas())
}
if cliCtx.Simulate {
return nil
@ -131,7 +132,7 @@ func SignStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string,
"The generated transaction's intended signer does not match the given signer: %q", name)
}
if !offline && txBldr.AccountNumber == 0 {
if !offline && txBldr.GetAccountNumber() == 0 {
accNum, err := cliCtx.GetAccountNumber(addr)
if err != nil {
return signedStdTx, err
@ -139,7 +140,7 @@ func SignStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string,
txBldr = txBldr.WithAccountNumber(accNum)
}
if !offline && txBldr.Sequence == 0 {
if !offline && txBldr.GetSequence() == 0 {
accSeq, err := cliCtx.GetAccountSequence(addr)
if err != nil {
return signedStdTx, err
@ -172,7 +173,7 @@ func simulateMsgs(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name stri
if err != nil {
return
}
estimated, adjusted, err = CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, txBldr.GasAdjustment)
estimated, adjusted, err = CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, txBldr.GetGasAdjustment())
return
}
@ -200,7 +201,7 @@ func prepareTxBuilder(txBldr authtxb.TxBuilder, cliCtx context.CLIContext) (auth
// TODO: (ref #1903) Allow for user supplied account number without
// automatically doing a manual lookup.
if txBldr.AccountNumber == 0 {
if txBldr.GetAccountNumber() == 0 {
accNum, err := cliCtx.GetAccountNumber(from)
if err != nil {
return txBldr, err
@ -210,7 +211,7 @@ func prepareTxBuilder(txBldr authtxb.TxBuilder, cliCtx context.CLIContext) (auth
// TODO: (ref #1903) Allow for user supplied account sequence without
// automatically doing a manual lookup.
if txBldr.Sequence == 0 {
if txBldr.GetSequence() == 0 {
accSeq, err := cliCtx.GetAccountSequence(from)
if err != nil {
return txBldr, err
@ -231,7 +232,7 @@ func buildUnsignedStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msg
}
func buildUnsignedStdTxOffline(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) (stdTx auth.StdTx, err error) {
if txBldr.SimulateGas {
if txBldr.GetSimulateAndExecute() {
var name string
name, err = cliCtx.GetFromName()
if err != nil {
@ -242,7 +243,7 @@ func buildUnsignedStdTxOffline(txBldr authtxb.TxBuilder, cliCtx context.CLIConte
if err != nil {
return
}
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas)
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.GetGas())
}
stdSignMsg, err := txBldr.Build(msgs)
if err != nil {

View File

@ -3,11 +3,12 @@ package utils
import (
"encoding/json"
"errors"
"testing"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
"testing"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/libs/common"

View File

@ -22,12 +22,12 @@ func ExampleTxSendSize() {
addr1 := sdk.AccAddress(priv1.PubKey().Address())
priv2 := secp256k1.GenPrivKeySecp256k1([]byte{1})
addr2 := sdk.AccAddress(priv2.PubKey().Address())
coins := []sdk.Coin{sdk.NewCoin("denom", sdk.NewInt(10))}
coins := sdk.Coins{sdk.NewCoin("denom", sdk.NewInt(10))}
msg1 := bank.MsgSend{
Inputs: []bank.Input{bank.NewInput(addr1, coins)},
Outputs: []bank.Output{bank.NewOutput(addr2, coins)},
}
fee := auth.NewStdFee(gas, coins...)
fee := auth.NewStdFee(gas, coins)
signBytes := auth.StdSignBytes("example-chain-ID",
1, 1, fee, []sdk.Msg{msg1}, "")
sig, _ := priv1.Sign(signBytes)

View File

@ -78,7 +78,7 @@ func TestGaiaCLIFeesDeduction(t *testing.T) {
// test simulation
success := executeWrite(t, fmt.Sprintf(
"gaiacli tx send %v --amount=1000footoken --to=%s --from=foo --fee=1footoken --dry-run", flags, barAddr), app.DefaultKeyPass)
"gaiacli tx send %v --amount=1000footoken --to=%s --from=foo --fees=1footoken --dry-run", flags, barAddr), app.DefaultKeyPass)
require.True(t, success)
tests.WaitForNextNBlocksTM(1, port)
// ensure state didn't change
@ -87,7 +87,7 @@ func TestGaiaCLIFeesDeduction(t *testing.T) {
// insufficient funds (coins + fees)
success = executeWrite(t, fmt.Sprintf(
"gaiacli tx send %v --amount=1000footoken --to=%s --from=foo --fee=1footoken", flags, barAddr), app.DefaultKeyPass)
"gaiacli tx send %v --amount=1000footoken --to=%s --from=foo --fees=1footoken", flags, barAddr), app.DefaultKeyPass)
require.False(t, success)
tests.WaitForNextNBlocksTM(1, port)
// ensure state didn't change
@ -96,7 +96,7 @@ func TestGaiaCLIFeesDeduction(t *testing.T) {
// test success (transfer = coins + fees)
success = executeWrite(t, fmt.Sprintf(
"gaiacli tx send %v --fee=300footoken --amount=500footoken --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass)
"gaiacli tx send %v --fees=300footoken --amount=500footoken --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass)
require.True(t, success)
cleanupDirs(gaiadHome, gaiacliHome)
}

View File

@ -270,7 +270,7 @@ func EnsureSufficientMempoolFees(ctx sdk.Context, stdTx StdTx) sdk.Result {
// - Make the gasPrice not a constant, and account for tx size.
// - Make Gas an unsigned integer and use tx basic validation
if stdTx.Fee.Gas <= 0 {
return sdk.ErrInternal(fmt.Sprintf("invalid gas supplied: %d", stdTx.Fee.Gas)).Result()
return sdk.ErrInternal(fmt.Sprintf("gas supplied must be a positive integer: %d", stdTx.Fee.Gas)).Result()
}
requiredFees := adjustFeesByGas(ctx.MinimumFees(), stdTx.Fee.Gas)

View File

@ -23,7 +23,7 @@ func newTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg {
func newStdFee() StdFee {
return NewStdFee(50000,
sdk.NewInt64Coin("atom", 150),
sdk.Coins{sdk.NewInt64Coin("atom", 150)},
)
}
@ -429,24 +429,24 @@ func TestAnteHandlerMemoGas(t *testing.T) {
var tx sdk.Tx
msg := newTestMsg(addr1)
privs, accnums, seqs := []crypto.PrivKey{priv1}, []uint64{0}, []uint64{0}
fee := NewStdFee(0, sdk.NewInt64Coin("atom", 0))
fee := NewStdFee(0, sdk.Coins{sdk.NewInt64Coin("atom", 0)})
// tx does not have enough gas
tx = newTestTx(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee)
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeOutOfGas)
// tx with memo doesn't have enough gas
fee = NewStdFee(801, sdk.NewInt64Coin("atom", 0))
fee = NewStdFee(801, sdk.Coins{sdk.NewInt64Coin("atom", 0)})
tx = newTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, "abcininasidniandsinasindiansdiansdinaisndiasndiadninsd")
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeOutOfGas)
// memo too large
fee = NewStdFee(9000, sdk.NewInt64Coin("atom", 0))
fee = NewStdFee(9000, sdk.Coins{sdk.NewInt64Coin("atom", 0)})
tx = newTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, strings.Repeat("01234567890", 500))
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeMemoTooLarge)
// tx with memo has enough gas
fee = NewStdFee(9000, sdk.NewInt64Coin("atom", 0))
fee = NewStdFee(9000, sdk.Coins{sdk.NewInt64Coin("atom", 0)})
tx = newTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, strings.Repeat("0123456789", 10))
checkValidTx(t, anteHandler, ctx, tx, false)
}

View File

@ -75,7 +75,7 @@ func makeSignCmd(cdc *amino.Codec) func(cmd *cobra.Command, args []string) error
txBldr := authtxb.NewTxBuilderFromCLI()
if viper.GetBool(flagValidateSigs) {
if !printAndValidateSigs(cliCtx, txBldr.ChainID, stdTx, offline) {
if !printAndValidateSigs(cliCtx, txBldr.GetChainID(), stdTx, offline) {
return fmt.Errorf("signatures validation failed")
}

View File

@ -41,11 +41,8 @@ func SignTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Ha
return
}
txBldr := authtxb.TxBuilder{
ChainID: m.ChainID,
AccountNumber: m.AccountNumber,
Sequence: m.Sequence,
}
txBldr := authtxb.NewTxBuilder(utils.GetTxEncoder(cdc), m.AccountNumber,
m.Sequence, m.Tx.Fee.Gas, 1.0, false, m.ChainID, m.Tx.GetMemo(), m.Tx.Fee.Amount)
signedTx, err := txBldr.SignStdTx(m.LocalAccountName, m.Password, m.Tx, m.AppendSig)
if keyerror.IsErrKeyNotFound(err) {

View File

@ -1,6 +1,8 @@
package context
import (
"strings"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -12,102 +14,136 @@ import (
// TxBuilder implements a transaction context created in SDK modules.
type TxBuilder struct {
TxEncoder sdk.TxEncoder
AccountNumber uint64
Sequence uint64
Gas uint64
GasAdjustment float64
SimulateGas bool
ChainID string
Memo string
Fee string
txEncoder sdk.TxEncoder
accountNumber uint64
sequence uint64
gas uint64
gasAdjustment float64
simulateAndExecute bool
chainID string
memo string
fees sdk.Coins
}
// NewTxBuilder returns a new initialized TxBuilder
func NewTxBuilder(txEncoder sdk.TxEncoder, accNumber, seq, gas uint64, gasAdj float64, simulateAndExecute bool, chainID, memo string, fees sdk.Coins) TxBuilder {
return TxBuilder{
txEncoder: txEncoder,
accountNumber: accNumber,
sequence: seq,
gas: gas,
gasAdjustment: gasAdj,
simulateAndExecute: simulateAndExecute,
chainID: chainID,
memo: memo,
fees: fees,
}
}
// NewTxBuilderFromCLI returns a new initialized TxBuilder with parameters from
// the command line using Viper.
func NewTxBuilderFromCLI() TxBuilder {
// if chain ID is not specified manually, read default chain ID
chainID := viper.GetString(client.FlagChainID)
return TxBuilder{
ChainID: chainID,
AccountNumber: uint64(viper.GetInt64(client.FlagAccountNumber)),
Gas: client.GasFlagVar.Gas,
GasAdjustment: viper.GetFloat64(client.FlagGasAdjustment),
Sequence: uint64(viper.GetInt64(client.FlagSequence)),
SimulateGas: client.GasFlagVar.Simulate,
Fee: viper.GetString(client.FlagFee),
Memo: viper.GetString(client.FlagMemo),
txbldr := TxBuilder{
accountNumber: uint64(viper.GetInt64(client.FlagAccountNumber)),
sequence: uint64(viper.GetInt64(client.FlagSequence)),
gas: client.GasFlagVar.Gas,
gasAdjustment: viper.GetFloat64(client.FlagGasAdjustment),
simulateAndExecute: client.GasFlagVar.Simulate,
chainID: viper.GetString(client.FlagChainID),
memo: viper.GetString(client.FlagMemo),
}
return txbldr.WithFees(viper.GetString(client.FlagFees))
}
// WithCodec returns a copy of the context with an updated codec.
// GetTxEncoder returns the transaction encoder
func (bldr TxBuilder) GetTxEncoder() sdk.TxEncoder { return bldr.txEncoder }
// GetAccountNumber returns the account number
func (bldr TxBuilder) GetAccountNumber() uint64 { return bldr.accountNumber }
// GetSequence returns the transaction sequence
func (bldr TxBuilder) GetSequence() uint64 { return bldr.sequence }
// GetGas returns the gas for the transaction
func (bldr TxBuilder) GetGas() uint64 { return bldr.gas }
// GetGasAdjustment returns the gas adjustment
func (bldr TxBuilder) GetGasAdjustment() float64 { return bldr.gasAdjustment }
// GetSimulateAndExecute returns the option to simulate and then execute the transaction
// using the gas from the simulation results
func (bldr TxBuilder) GetSimulateAndExecute() bool { return bldr.simulateAndExecute }
// GetChainID returns the chain id
func (bldr TxBuilder) GetChainID() string { return bldr.chainID }
// GetMemo returns the memo message
func (bldr TxBuilder) GetMemo() string { return bldr.memo }
// GetFees returns the fees for the transaction
func (bldr TxBuilder) GetFees() sdk.Coins { return bldr.fees }
// WithTxEncoder returns a copy of the context with an updated codec.
func (bldr TxBuilder) WithTxEncoder(txEncoder sdk.TxEncoder) TxBuilder {
bldr.TxEncoder = txEncoder
bldr.txEncoder = txEncoder
return bldr
}
// WithChainID returns a copy of the context with an updated chainID.
func (bldr TxBuilder) WithChainID(chainID string) TxBuilder {
bldr.ChainID = chainID
bldr.chainID = chainID
return bldr
}
// WithGas returns a copy of the context with an updated gas.
func (bldr TxBuilder) WithGas(gas uint64) TxBuilder {
bldr.Gas = gas
bldr.gas = gas
return bldr
}
// WithFee returns a copy of the context with an updated fee.
func (bldr TxBuilder) WithFee(fee string) TxBuilder {
bldr.Fee = fee
// WithFees returns a copy of the context with an updated fee.
func (bldr TxBuilder) WithFees(fees string) TxBuilder {
parsedFees, err := sdk.ParseCoins(fees)
if err != nil {
panic(err)
}
bldr.fees = parsedFees
return bldr
}
// WithSequence returns a copy of the context with an updated sequence number.
func (bldr TxBuilder) WithSequence(sequence uint64) TxBuilder {
bldr.Sequence = sequence
bldr.sequence = sequence
return bldr
}
// WithMemo returns a copy of the context with an updated memo.
func (bldr TxBuilder) WithMemo(memo string) TxBuilder {
bldr.Memo = memo
bldr.memo = strings.TrimSpace(memo)
return bldr
}
// WithAccountNumber returns a copy of the context with an account number.
func (bldr TxBuilder) WithAccountNumber(accnum uint64) TxBuilder {
bldr.AccountNumber = accnum
bldr.accountNumber = accnum
return bldr
}
// Build builds a single message to be signed from a TxBuilder given a set of
// messages. It returns an error if a fee is supplied but cannot be parsed.
func (bldr TxBuilder) Build(msgs []sdk.Msg) (StdSignMsg, error) {
chainID := bldr.ChainID
chainID := bldr.chainID
if chainID == "" {
return StdSignMsg{}, errors.Errorf("chain ID required but not specified")
}
fee := sdk.Coin{}
if bldr.Fee != "" {
parsedFee, err := sdk.ParseCoin(bldr.Fee)
if err != nil {
return StdSignMsg{}, err
}
fee = parsedFee
}
return StdSignMsg{
ChainID: bldr.ChainID,
AccountNumber: bldr.AccountNumber,
Sequence: bldr.Sequence,
Memo: bldr.Memo,
ChainID: bldr.chainID,
AccountNumber: bldr.accountNumber,
Sequence: bldr.sequence,
Memo: bldr.memo,
Msgs: msgs,
Fee: auth.NewStdFee(bldr.Gas, fee),
Fee: auth.NewStdFee(bldr.gas, bldr.fees),
}, nil
}
@ -119,7 +155,7 @@ func (bldr TxBuilder) Sign(name, passphrase string, msg StdSignMsg) ([]byte, err
return nil, err
}
return bldr.TxEncoder(auth.NewStdTx(msg.Msgs, msg.Fee, []auth.StdSignature{sig}, msg.Memo))
return bldr.txEncoder(auth.NewStdTx(msg.Msgs, msg.Fee, []auth.StdSignature{sig}, msg.Memo))
}
// BuildAndSign builds a single message to be signed, and signs a transaction
@ -158,16 +194,16 @@ func (bldr TxBuilder) BuildWithPubKey(name string, msgs []sdk.Msg) ([]byte, erro
PubKey: info.GetPubKey(),
}}
return bldr.TxEncoder(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
return bldr.txEncoder(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
}
// SignStdTx appends a signature to a StdTx and returns a copy of a it. If append
// is false, it replaces the signatures already attached with the new signature.
func (bldr TxBuilder) SignStdTx(name, passphrase string, stdTx auth.StdTx, appendSig bool) (signedStdTx auth.StdTx, err error) {
stdSignature, err := MakeSignature(name, passphrase, StdSignMsg{
ChainID: bldr.ChainID,
AccountNumber: bldr.AccountNumber,
Sequence: bldr.Sequence,
ChainID: bldr.chainID,
AccountNumber: bldr.accountNumber,
Sequence: bldr.sequence,
Fee: stdTx.Fee,
Msgs: stdTx.GetMsgs(),
Memo: stdTx.GetMemo(),

View File

@ -29,7 +29,7 @@ func TestTxBuilderBuild(t *testing.T) {
SimulateGas bool
ChainID string
Memo string
Fee string
Fees sdk.Coins
}
defaultMsg := []sdk.Msg{sdk.NewTestMsg(addr)}
tests := []struct {
@ -47,33 +47,23 @@ func TestTxBuilderBuild(t *testing.T) {
GasAdjustment: 1.1,
SimulateGas: false,
ChainID: "test-chain",
Memo: "hello",
Fee: "1" + stakeTypes.DefaultBondDenom,
Memo: "hello from Voyager !",
Fees: sdk.Coins{sdk.NewCoin(stakeTypes.DefaultBondDenom, sdk.NewInt(1))},
},
defaultMsg,
StdSignMsg{
ChainID: "test-chain",
AccountNumber: 1,
Sequence: 1,
Memo: "hello",
Memo: "hello from Voyager !",
Msgs: defaultMsg,
Fee: auth.NewStdFee(100, sdk.NewCoin(stakeTypes.DefaultBondDenom, sdk.NewInt(1))),
Fee: auth.NewStdFee(100, sdk.Coins{sdk.NewCoin(stakeTypes.DefaultBondDenom, sdk.NewInt(1))}),
},
false,
},
}
for i, tc := range tests {
bldr := TxBuilder{
TxEncoder: tc.fields.TxEncoder,
AccountNumber: tc.fields.AccountNumber,
Sequence: tc.fields.Sequence,
Gas: tc.fields.Gas,
GasAdjustment: tc.fields.GasAdjustment,
SimulateGas: tc.fields.SimulateGas,
ChainID: tc.fields.ChainID,
Memo: tc.fields.Memo,
Fee: tc.fields.Fee,
}
bldr := NewTxBuilder(tc.fields.TxEncoder, tc.fields.AccountNumber, tc.fields.Sequence, tc.fields.Gas, tc.fields.GasAdjustment, tc.fields.SimulateGas, tc.fields.ChainID, tc.fields.Memo, tc.fields.Fees)
got, err := bldr.Build(tc.msgs)
require.Equal(t, tc.wantErr, (err != nil), "TxBuilder.Build() error = %v, wantErr %v, tc %d", err, tc.wantErr, i)
if !reflect.DeepEqual(got, tc.want) {

View File

@ -133,7 +133,7 @@ type StdFee struct {
Gas uint64 `json:"gas"`
}
func NewStdFee(gas uint64, amount ...sdk.Coin) StdFee {
func NewStdFee(gas uint64, amount sdk.Coins) StdFee {
return StdFee{
Amount: amount,
Gas: gas,

View File

@ -43,7 +43,7 @@ var (
coins = sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
halfCoins = sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}
manyCoins = sdk.Coins{sdk.NewInt64Coin("foocoin", 1), sdk.NewInt64Coin("barcoin", 1)}
freeFee = auth.NewStdFee(100000, sdk.Coins{sdk.NewInt64Coin("foocoin", 0)}...)
freeFee = auth.NewStdFee(100000, sdk.Coins{sdk.NewInt64Coin("foocoin", 0)})
sendMsg1 = MsgSend{
Inputs: []Input{NewInput(addr1, coins)},

View File

@ -49,21 +49,18 @@ func SendRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CLIC
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
info, err := kb.Get(baseReq.Name)
info, err := kb.Get(req.BaseReq.Name)
if err != nil {
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
msg := client.CreateMsg(sdk.AccAddress(info.GetPubKey().Address()), to, req.Amount)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}

View File

@ -78,11 +78,8 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
@ -100,7 +97,7 @@ func postProposalHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han
return
}
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}
@ -126,11 +123,8 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
@ -142,7 +136,7 @@ func depositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerF
return
}
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}
@ -168,11 +162,8 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
@ -190,7 +181,7 @@ func voteHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc
return
}
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}

View File

@ -43,15 +43,12 @@ func TransferRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
info, err := kb.Get(baseReq.Name)
info, err := kb.Get(req.BaseReq.Name)
if err != nil {
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
return
@ -59,10 +56,10 @@ func TransferRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.
packet := ibc.NewIBCPacket(
sdk.AccAddress(info.GetPubKey().Address()), to,
req.Amount, baseReq.ChainID, destChainID,
req.Amount, req.BaseReq.ChainID, destChainID,
)
msg := ibc.IBCTransferMsg{IBCPacket: packet}
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}

View File

@ -38,15 +38,12 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
info, err := kb.Get(baseReq.Name)
info, err := kb.Get(req.BaseReq.Name)
if err != nil {
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
return
@ -64,6 +61,6 @@ func unjailRequestHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.CL
}
msg := slashing.NewMsgUnjail(valAddr)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}

View File

@ -63,15 +63,12 @@ func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
info, err := kb.Get(baseReq.Name)
info, err := kb.Get(req.BaseReq.Name)
if err != nil {
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
return
@ -89,7 +86,7 @@ func postDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx context.
return
}
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}
@ -103,15 +100,12 @@ func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx contex
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
info, err := kb.Get(baseReq.Name)
info, err := kb.Get(req.BaseReq.Name)
if err != nil {
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
return
@ -129,7 +123,7 @@ func postRedelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx contex
return
}
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}
@ -143,15 +137,12 @@ func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx
return
}
cliCtx = cliCtx.WithGenerateOnly(req.BaseReq.GenerateOnly)
cliCtx = cliCtx.WithSimulation(req.BaseReq.Simulate)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w, cliCtx) {
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
info, err := kb.Get(baseReq.Name)
info, err := kb.Get(req.BaseReq.Name)
if err != nil {
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
return
@ -169,6 +160,6 @@ func postUnbondingDelegationsHandlerFn(cdc *codec.Codec, kb keys.Keybase, cliCtx
return
}
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, baseReq, []sdk.Msg{msg}, cdc)
utils.CompleteAndBroadcastTxREST(w, r, cliCtx, req.BaseReq, []sdk.Msg{msg}, cdc)
}
}

View File

@ -20,7 +20,7 @@ var (
coins = sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(10))}
fee = auth.NewStdFee(
100000,
sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))}...,
sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))},
)
commissionMsg = NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())