Add fees and memo to REST, updated CLI to receive coins as fees (#3069)
This commit is contained in:
committed by
Jack Zampolin
parent
c9ef680f67
commit
f02f7aa5a0
+10
-9
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+143
-61
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+57
-100
@@ -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)
|
||||
|
||||
+75
-59
@@ -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 {
|
||||
|
||||
+11
-10
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user