cosmos-sdk/cmd/gaia/lcd_test/lcd_test.go

1105 lines
40 KiB
Go

package lcd_test
import (
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
"os"
"regexp"
"strings"
"testing"
"time"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
"github.com/cosmos/cosmos-sdk/tests"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
dclcommon "github.com/cosmos/cosmos-sdk/x/distribution/client/common"
distrrest "github.com/cosmos/cosmos-sdk/x/distribution/client/rest"
disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
)
const (
name1 = "test1"
memo = "LCD test tx"
pw = client.DefaultKeyPass
)
var fees = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)}
func init() {
mintkey.BcryptSecurityParameter = 1
version.Version = os.Getenv("VERSION")
}
func TestVersion(t *testing.T) {
// skip the test if the VERSION environment variable has not been set
if version.Version == "" {
t.SkipNow()
}
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
// node info
res, body := Request(t, port, "GET", "/version", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
reg, err := regexp.Compile(`\d+\.\d+\.\d+.*`)
require.Nil(t, err)
match := reg.MatchString(body)
require.True(t, match, body, body)
// node info
res, body = Request(t, port, "GET", "/node_version", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
reg, err = regexp.Compile(`\d+\.\d+\.\d+.*`)
require.Nil(t, err)
match = reg.MatchString(body)
require.True(t, match, body)
}
func TestNodeStatus(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
getNodeInfo(t, port)
getSyncStatus(t, port, false)
}
func TestBlock(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
getBlock(t, port, -1, false)
getBlock(t, port, 2, false)
getBlock(t, port, 100000000, true)
}
func TestValidators(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
resultVals := getValidatorSets(t, port, -1, false)
require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosvalcons")
require.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalconspub")
getValidatorSets(t, port, 2, false)
getValidatorSets(t, port, 10000000, true)
}
func TestCoinSend(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
bz, err := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6")
require.NoError(t, err)
someFakeAddr := sdk.AccAddress(bz)
// query empty
res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", someFakeAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create TX
receiveAddr, resultTx := doTransfer(t, port, seed, name1, memo, pw, addr, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.Code)
// query sender
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, sdk.DefaultBondDenom, coins[0].Denom)
require.Equal(t, expectedBalance.Amount.SubRaw(1), coins[0].Amount)
expectedBalance = coins[0]
// query receiver
acc2 := getAccount(t, port, receiveAddr)
coins2 := acc2.GetCoins()
require.Equal(t, sdk.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, memo, pw, addr, "100", 0, false, true, 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, memo, pw, addr, "-200", 0, false, false, fees)
require.Equal(t, http.StatusBadRequest, res.StatusCode, body)
// 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, memo, pw, addr, "0", 0, false, true, fees)
require.Equal(t, http.StatusInternalServerError, res.StatusCode, body)
// test failure with wrong adjustment
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, client.GasFlagAuto, 0.1, false, true, fees)
require.Equal(t, http.StatusInternalServerError, res.StatusCode, body)
// run simulation and test success with estimated gas
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 gasEstResp rest.GasEstimateResponse
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &gasEstResp))
require.NotZero(t, gasEstResp.GasEstimate)
acc = getAccount(t, port, addr)
require.Equal(t, expectedBalance.Amount, acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
// run successful tx
gas := fmt.Sprintf("%d", gasEstResp.GasEstimate)
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, gas, 1.0, false, true, 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.Code)
acc = getAccount(t, port, addr)
expectedBalance = expectedBalance.Sub(fees[0])
require.Equal(t, expectedBalance.Amount.SubRaw(1), acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
}
func TestCoinSendAccAuto(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// send a transfer tx without specifying account number and sequence
res, body, _ := doTransferWithGasAccAuto(
t, port, seed, name1, memo, pw, addr, "200000", 1.0, false, true, fees,
)
require.Equal(t, http.StatusOK, res.StatusCode, body)
// query sender
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, sdk.DefaultBondDenom, coins[0].Denom)
require.Equal(t, expectedBalance.Amount.SubRaw(1), coins[0].Amount)
}
func TestCoinMultiSendGenerateOnly(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
// generate only
res, body, _ := doTransferWithGas(t, port, seed, "", memo, "", addr, "200000", 1, false, false, fees)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var stdTx auth.StdTx
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &stdTx))
require.Equal(t, len(stdTx.Msgs), 1)
require.Equal(t, stdTx.GetMsgs()[0].Route(), "bank")
require.Equal(t, stdTx.GetMsgs()[0].GetSigners(), []sdk.AccAddress{addr})
require.Equal(t, 0, len(stdTx.Signatures))
require.Equal(t, memo, stdTx.Memo)
require.NotZero(t, stdTx.Fee.Gas)
require.IsType(t, stdTx.GetMsgs()[0], bank.MsgSend{})
require.Equal(t, addr, stdTx.GetMsgs()[0].(bank.MsgSend).FromAddress)
}
func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
acc := getAccount(t, port, addr)
// simulate tx
res, body, _ := doTransferWithGas(
t, port, seed, name1, memo, "", addr, client.GasFlagAuto, 1.0, true, false, fees,
)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var gasEstResp rest.GasEstimateResponse
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &gasEstResp))
require.NotZero(t, gasEstResp.GasEstimate)
// generate tx
gas := fmt.Sprintf("%d", gasEstResp.GasEstimate)
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, "", addr, gas, 1, false, false, fees)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var tx auth.StdTx
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &tx))
require.Equal(t, len(tx.Msgs), 1)
require.Equal(t, tx.Msgs[0].Route(), "bank")
require.Equal(t, tx.Msgs[0].GetSigners(), []sdk.AccAddress{addr})
require.Equal(t, 0, len(tx.Signatures))
require.Equal(t, memo, tx.Memo)
require.NotZero(t, tx.Fee.Gas)
gasEstimate := int64(tx.Fee.Gas)
_, body = signAndBroadcastGenTx(t, port, name1, pw, body, acc, 1.0, false)
// check if tx was committed
var txResp sdk.TxResponse
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &txResp))
require.Equal(t, uint32(0), txResp.Code)
require.Equal(t, gasEstimate, txResp.GasWanted)
}
func TestEncodeTx(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
res, body, _ := doTransferWithGas(t, port, seed, name1, memo, "", addr, "2", 1, false, false, fees)
var tx auth.StdTx
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &tx))
encodedJSON, _ := cdc.MarshalJSON(tx)
res, body = Request(t, port, "POST", "/txs/encode", encodedJSON)
// Make sure it came back ok, and that we can decode it back to the transaction
// 200 response.
require.Equal(t, http.StatusOK, res.StatusCode, body)
encodeResp := struct {
Tx string `json:"tx"`
}{}
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &encodeResp))
// verify that the base64 decodes
decodedBytes, err := base64.StdEncoding.DecodeString(encodeResp.Tx)
require.Nil(t, err)
// check that the transaction decodes as expected
var decodedTx auth.StdTx
require.Nil(t, cdc.UnmarshalBinaryLengthPrefixed(decodedBytes, &decodedTx))
require.Equal(t, memo, decodedTx.Memo)
}
func TestTxs(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
var emptyTxs []sdk.TxResponse
txResult := getTransactions(t, port)
require.Equal(t, emptyTxs, txResult.Txs)
// query empty
txResult = getTransactions(t, port, fmt.Sprintf("sender=%s", addr.String()))
require.Equal(t, emptyTxs, txResult.Txs)
// also tests url decoding
txResult = getTransactions(t, port, fmt.Sprintf("sender=%s", addr.String()))
require.Equal(t, emptyTxs, txResult.Txs)
txResult = getTransactions(t, port, fmt.Sprintf("action=submit%%20proposal&sender=%s", addr.String()))
require.Equal(t, emptyTxs, txResult.Txs)
// create tx
receiveAddr, resultTx := doTransfer(t, port, seed, name1, memo, pw, addr, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx is queryable
tx := getTransaction(t, port, resultTx.TxHash)
require.Equal(t, resultTx.TxHash, tx.TxHash)
// query sender
txResult = getTransactions(t, port, fmt.Sprintf("sender=%s", addr.String()))
require.Len(t, txResult.Txs, 1)
require.Equal(t, resultTx.Height, txResult.Txs[0].Height)
// query recipient
txResult = getTransactions(t, port, fmt.Sprintf("recipient=%s", receiveAddr.String()))
require.Len(t, txResult.Txs, 1)
require.Equal(t, resultTx.Height, txResult.Txs[0].Height)
// query transaction that doesn't exist
validTxHash := "9ADBECAAD8DACBEC3F4F535704E7CF715C765BDCEDBEF086AFEAD31BA664FB0B"
res, body := getTransactionRequest(t, port, validTxHash)
require.True(t, strings.Contains(body, validTxHash))
require.Equal(t, http.StatusNotFound, res.StatusCode)
// bad query string
res, body = getTransactionRequest(t, port, "badtxhash")
require.True(t, strings.Contains(body, "encoding/hex"))
require.Equal(t, http.StatusInternalServerError, res.StatusCode)
}
func TestPoolParamsQuery(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, _ := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
defaultParams := staking.DefaultParams()
params := getStakingParams(t, port)
require.True(t, defaultParams.Equal(params))
pool := getStakingPool(t, port)
initialPool := staking.InitialPool()
tokens := sdk.TokensFromTendermintPower(100)
freeTokens := sdk.TokensFromTendermintPower(50)
initialPool.NotBondedTokens = initialPool.NotBondedTokens.Add(tokens)
initialPool.BondedTokens = initialPool.BondedTokens.Add(tokens) // Delegate tx on GaiaAppGenState
initialPool.NotBondedTokens = initialPool.NotBondedTokens.Add(freeTokens) // freeTokensPerAcc = 50 on GaiaAppGenState
require.Equal(t, initialPool.BondedTokens, pool.BondedTokens)
//TODO include this test once REST for distribution is online, need to include distribution tokens from inflation
// for this equality to make sense
//require.Equal(t, initialPool.NotBondedTokens, pool.NotBondedTokens)
}
func TestValidatorsQuery(t *testing.T) {
cleanup, valPubKeys, operAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
require.Equal(t, 1, len(valPubKeys))
require.Equal(t, 1, len(operAddrs))
validators := getValidators(t, port)
require.Equal(t, 1, len(validators), fmt.Sprintf("%+v", validators))
// make sure all the validators were found (order unknown because sorted by operator addr)
foundVal := false
if validators[0].ConsPubKey == valPubKeys[0] {
foundVal = true
}
require.True(t, foundVal, "pk %v, operator %v", operAddrs[0], validators[0].OperatorAddress)
}
func TestValidatorQuery(t *testing.T) {
cleanup, valPubKeys, operAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
require.Equal(t, 1, len(valPubKeys))
require.Equal(t, 1, len(operAddrs))
validator := getValidator(t, port, operAddrs[0])
require.Equal(t, validator.OperatorAddress, operAddrs[0], "The returned validator does not hold the correct data")
}
func TestBonding(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, _ := CreateAddr(t, name1, pw, kb)
cleanup, valPubKeys, operAddrs, port := InitializeTestLCD(t, 2, []sdk.AccAddress{addr}, false)
tests.WaitForHeight(1, port)
defer cleanup()
require.Equal(t, 2, len(valPubKeys))
require.Equal(t, 2, len(operAddrs))
amt := sdk.TokensFromTendermintPower(60)
amtDec := amt.ToDec()
validator := getValidator(t, port, operAddrs[0])
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create bond TX
delTokens := sdk.TokensFromTendermintPower(60)
resultTx := doDelegate(t, port, name1, pw, addr, operAddrs[0], delTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
require.Equal(t, uint32(0), resultTx.Code)
// query tx
txResult := getTransactions(t, port,
fmt.Sprintf("action=delegate&sender=%s", addr),
fmt.Sprintf("destination-validator=%s", operAddrs[0]),
)
require.Len(t, txResult.Txs, 1)
require.Equal(t, resultTx.Height, txResult.Txs[0].Height)
// verify balance
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(delTokens), coins.AmountOf(sdk.DefaultBondDenom))
expectedBalance = coins[0]
// query delegation
bond := getDelegation(t, port, addr, operAddrs[0])
require.Equal(t, amtDec, bond.Shares)
delegatorDels := getDelegatorDelegations(t, port, addr)
require.Len(t, delegatorDels, 1)
require.Equal(t, amtDec, delegatorDels[0].Shares)
// query all delegations to validator
bonds := getValidatorDelegations(t, port, operAddrs[0])
require.Len(t, bonds, 2)
bondedValidators := getDelegatorValidators(t, port, addr)
require.Len(t, bondedValidators, 1)
require.Equal(t, operAddrs[0], bondedValidators[0].OperatorAddress)
require.Equal(t, validator.DelegatorShares.Add(amtDec).String(), bondedValidators[0].DelegatorShares.String())
bondedValidator := getDelegatorValidator(t, port, addr, operAddrs[0])
require.Equal(t, operAddrs[0], bondedValidator.OperatorAddress)
// testing unbonding
unbondingTokens := sdk.TokensFromTendermintPower(30)
resultTx = doUndelegate(t, port, name1, pw, addr, operAddrs[0], unbondingTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
require.Equal(t, uint32(0), resultTx.Code)
// sender should have not received any coins as the unbonding has only just begun
acc = getAccount(t, port, addr)
coins = acc.GetCoins()
expectedBalance = expectedBalance.Sub(fees[0])
require.True(t,
expectedBalance.Amount.LT(coins.AmountOf(sdk.DefaultBondDenom)) ||
expectedBalance.Amount.Equal(coins.AmountOf(sdk.DefaultBondDenom)),
"should get tokens back from automatic withdrawal after an unbonding delegation",
)
expectedBalance = coins[0]
// query tx
txResult = getTransactions(t, port,
fmt.Sprintf("action=begin_unbonding&sender=%s", addr),
fmt.Sprintf("source-validator=%s", operAddrs[0]),
)
require.Len(t, txResult.Txs, 1)
require.Equal(t, resultTx.Height, txResult.Txs[0].Height)
ubd := getUnbondingDelegation(t, port, addr, operAddrs[0])
require.Len(t, ubd.Entries, 1)
require.Equal(t, delTokens.QuoRaw(2), ubd.Entries[0].Balance)
// test redelegation
rdTokens := sdk.TokensFromTendermintPower(30)
resultTx = doBeginRedelegation(t, port, name1, pw, addr, operAddrs[0], operAddrs[1], rdTokens, fees)
require.Equal(t, uint32(0), resultTx.Code)
tests.WaitForHeight(resultTx.Height+1, port)
// query delegations, unbondings and redelegations from validator and delegator
delegatorDels = getDelegatorDelegations(t, port, addr)
require.Len(t, delegatorDels, 1)
require.Equal(t, operAddrs[1], delegatorDels[0].ValidatorAddress)
// TODO uncomment once all validators actually sign in the lcd tests
//validator2 := getValidator(t, port, operAddrs[1])
//delTokensAfterRedelegation := validator2.ShareTokens(delegatorDels[0].GetShares())
//require.Equal(t, rdTokens.ToDec(), delTokensAfterRedelegation)
// verify balance after paying fees
acc = getAccount(t, port, addr)
expectedBalance = expectedBalance.Sub(fees[0])
require.True(t,
expectedBalance.Amount.LT(coins.AmountOf(sdk.DefaultBondDenom)) ||
expectedBalance.Amount.Equal(coins.AmountOf(sdk.DefaultBondDenom)),
"should get tokens back from automatic withdrawal after an unbonding delegation",
)
// query tx
txResult = getTransactions(t, port,
fmt.Sprintf("action=begin_redelegate&sender=%s", addr),
fmt.Sprintf("source-validator=%s", operAddrs[0]),
fmt.Sprintf("destination-validator=%s", operAddrs[1]),
)
require.Len(t, txResult.Txs, 1)
require.Equal(t, resultTx.Height, txResult.Txs[0].Height)
redelegation := getRedelegations(t, port, addr, operAddrs[0], operAddrs[1])
require.Len(t, redelegation, 1)
require.Len(t, redelegation[0].Entries, 1)
delegatorUbds := getDelegatorUnbondingDelegations(t, port, addr)
require.Len(t, delegatorUbds, 1)
require.Len(t, delegatorUbds[0].Entries, 1)
require.Equal(t, rdTokens, delegatorUbds[0].Entries[0].Balance)
delegatorReds := getRedelegations(t, port, addr, nil, nil)
require.Len(t, delegatorReds, 1)
require.Len(t, delegatorReds[0].Entries, 1)
validatorUbds := getValidatorUnbondingDelegations(t, port, operAddrs[0])
require.Len(t, validatorUbds, 1)
require.Len(t, validatorUbds[0].Entries, 1)
require.Equal(t, rdTokens, validatorUbds[0].Entries[0].Balance)
validatorReds := getRedelegations(t, port, nil, operAddrs[0], nil)
require.Len(t, validatorReds, 1)
require.Len(t, validatorReds[0].Entries, 1)
// TODO Undonding status not currently implemented
// require.Equal(t, sdk.Unbonding, bondedValidators[0].Status)
// query txs
txs := getBondingTxs(t, port, addr, "")
require.Len(t, txs, 3, "All Txs found")
txs = getBondingTxs(t, port, addr, "bond")
require.Len(t, txs, 1, "All bonding txs found")
txs = getBondingTxs(t, port, addr, "unbond")
require.Len(t, txs, 1, "All unbonding txs found")
txs = getBondingTxs(t, port, addr, "redelegate")
require.Len(t, txs, 1, "All redelegation txs found")
}
func TestSubmitProposal(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create SubmitProposal TX
proposalTokens := sdk.TokensFromTendermintPower(5)
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, proposalTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.Code)
var proposalID uint64
bz, err := hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID)
// verify balance
acc = getAccount(t, port, addr)
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(proposalTokens), acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
proposer := getProposer(t, port, proposalID)
require.Equal(t, addr.String(), proposer.Proposer)
require.Equal(t, proposalID, proposer.ProposalID)
}
func TestSubmitParamChangeProposal(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create proposal tx
proposalTokens := sdk.TokensFromTendermintPower(5)
resultTx := doSubmitParamChangeProposal(t, port, seed, name1, pw, addr, proposalTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.Code)
var proposalID uint64
bz, err := hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID)
// verify balance
acc = getAccount(t, port, addr)
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(proposalTokens), acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
proposer := getProposer(t, port, proposalID)
require.Equal(t, addr.String(), proposer.Proposer)
require.Equal(t, proposalID, proposer.ProposalID)
}
func TestDeposit(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create SubmitProposal TX
proposalTokens := sdk.TokensFromTendermintPower(5)
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, proposalTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.Code)
var proposalID uint64
bz, err := hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID)
// verify balance
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(proposalTokens), coins.AmountOf(sdk.DefaultBondDenom))
expectedBalance = coins[0]
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
// create SubmitProposal TX
depositTokens := sdk.TokensFromTendermintPower(5)
resultTx = doDeposit(t, port, seed, name1, pw, addr, proposalID, depositTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// verify balance after deposit and fee
acc = getAccount(t, port, addr)
expectedBalance = expectedBalance.Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(depositTokens), acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
// query tx
txResult := getTransactions(t, port, fmt.Sprintf("action=deposit&sender=%s", addr))
require.Len(t, txResult.Txs, 1)
require.Equal(t, resultTx.Height, txResult.Txs[0].Height)
// query proposal
totalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(10))}
proposal = getProposal(t, port, proposalID)
require.True(t, proposal.TotalDeposit.IsEqual(totalCoins))
// query deposit
deposit := getDeposit(t, port, proposalID, addr)
require.True(t, deposit.Amount.IsEqual(totalCoins))
}
func TestVote(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, operAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create SubmitProposal TX
proposalTokens := sdk.TokensFromTendermintPower(10)
resultTx := doSubmitProposal(t, port, seed, name1, pw, addr, proposalTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.Code)
var proposalID uint64
bz, err := hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID)
// verify balance
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(proposalTokens), coins.AmountOf(sdk.DefaultBondDenom))
expectedBalance = coins[0]
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
require.Equal(t, gov.StatusVotingPeriod, proposal.Status)
// vote
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.Sub(fees[0])
require.Equal(t, expectedBalance.Amount, coins.AmountOf(sdk.DefaultBondDenom))
expectedBalance = coins[0]
// query tx
txResult := getTransactions(t, port, fmt.Sprintf("action=vote&sender=%s", addr))
require.Len(t, txResult.Txs, 1)
require.Equal(t, resultTx.Height, txResult.Txs[0].Height)
vote := getVote(t, port, proposalID, addr)
require.Equal(t, proposalID, vote.ProposalID)
require.Equal(t, gov.OptionYes, vote.Option)
tally := getTally(t, port, proposalID)
require.Equal(t, sdk.ZeroInt(), tally.Yes, "tally should be 0 as the address is not bonded")
// create bond TX
delTokens := sdk.TokensFromTendermintPower(60)
resultTx = doDelegate(t, port, name1, pw, addr, operAddrs[0], delTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// verify balance
acc = getAccount(t, port, addr)
coins = acc.GetCoins()
expectedBalance = expectedBalance.Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(delTokens), coins.AmountOf(sdk.DefaultBondDenom))
expectedBalance = coins[0]
tally = getTally(t, port, proposalID)
require.Equal(t, delTokens, 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.Sub(fees[0])
require.Equal(t, expectedBalance.Amount, acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
tally = getTally(t, port, proposalID)
require.Equal(t, sdk.ZeroInt(), tally.Yes, "tally should be 0 the user changed the option")
require.Equal(t, delTokens, tally.No, "tally should be equal to the amount delegated")
}
func TestUnjail(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, _ := CreateAddr(t, name1, pw, kb)
cleanup, valPubKeys, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
// XXX: any less than this and it fails
tests.WaitForHeight(3, port)
pkString, _ := sdk.Bech32ifyConsPub(valPubKeys[0])
signingInfo := getSigningInfo(t, port, pkString)
tests.WaitForHeight(4, port)
require.Equal(t, true, signingInfo.IndexOffset > 0)
require.Equal(t, time.Unix(0, 0).UTC(), signingInfo.JailedUntil)
require.Equal(t, true, signingInfo.MissedBlocksCounter == 0)
signingInfoList := getSigningInfoList(t, port)
require.NotZero(t, len(signingInfoList))
}
func TestProposalsQuery(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addrs, seeds, names, passwords := CreateAddrs(t, kb, 2)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addrs[0], addrs[1]}, true)
defer cleanup()
depositParam := getDepositParam(t, port)
halfMinDeposit := depositParam.MinDeposit.AmountOf(sdk.DefaultBondDenom).QuoRaw(2)
getVotingParam(t, port)
getTallyingParam(t, port)
// Addr1 proposes (and deposits) proposals #1 and #2
resultTx := doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit, fees)
var proposalID1 uint64
bz, err := hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID1)
tests.WaitForHeight(resultTx.Height+1, port)
resultTx = doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit, fees)
var proposalID2 uint64
bz, err = hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &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, fees)
var proposalID3 uint64
bz, err = hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &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, fees)
tests.WaitForHeight(resultTx.Height+1, port)
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
deposits := getDeposits(t, port, proposalID1)
require.Len(t, deposits, 1)
deposit := getDeposit(t, port, proposalID1, addrs[0])
require.Equal(t, deposit, deposits[0])
deposits = getDeposits(t, port, proposalID2)
require.Len(t, deposits, 2)
deposit = getDeposit(t, port, proposalID2, addrs[0])
require.True(t, deposit.Equals(deposits[0]))
deposit = getDeposit(t, port, proposalID2, addrs[1])
require.True(t, deposit.Equals(deposits[1]))
deposits = getDeposits(t, port, proposalID3)
require.Len(t, deposits, 1)
deposit = getDeposit(t, port, proposalID3, addrs[1])
require.Equal(t, deposit, deposits[0])
// increasing the amount of the deposit should update the existing one
depositTokens := sdk.TokensFromTendermintPower(1)
resultTx = doDeposit(t, port, seeds[0], names[0], passwords[0], addrs[0], proposalID1, depositTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
deposits = getDeposits(t, port, proposalID1)
require.Len(t, deposits, 1)
// Only proposals #1 should be in Deposit Period
proposals := getProposalsFilterStatus(t, port, gov.StatusDepositPeriod)
require.Len(t, proposals, 1)
require.Equal(t, proposalID1, proposals[0].ProposalID)
// Only proposals #2 and #3 should be in Voting Period
proposals = getProposalsFilterStatus(t, port, gov.StatusVotingPeriod)
require.Len(t, proposals, 2)
require.Equal(t, proposalID2, proposals[0].ProposalID)
require.Equal(t, proposalID3, proposals[1].ProposalID)
// Addr1 votes on proposals #2 & #3
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, "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, "Yes", fees)
tests.WaitForHeight(resultTx.Height+1, port)
// Test query all proposals
proposals = getProposalsAll(t, port)
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
require.Equal(t, proposalID2, (proposals[1]).ProposalID)
require.Equal(t, proposalID3, (proposals[2]).ProposalID)
// Test query deposited by addr1
proposals = getProposalsFilterDepositor(t, port, addrs[0])
require.Equal(t, proposalID1, (proposals[0]).ProposalID)
// Test query deposited by addr2
proposals = getProposalsFilterDepositor(t, port, addrs[1])
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
// Test query voted by addr1
proposals = getProposalsFilterVoter(t, port, addrs[0])
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
require.Equal(t, proposalID3, (proposals[1]).ProposalID)
// Test query voted by addr2
proposals = getProposalsFilterVoter(t, port, addrs[1])
require.Equal(t, proposalID3, (proposals[0]).ProposalID)
// Test query voted and deposited by addr1
proposals = getProposalsFilterVoterDepositor(t, port, addrs[0], addrs[0])
require.Equal(t, proposalID2, (proposals[0]).ProposalID)
// Test query votes on Proposal 2
votes := getVotes(t, port, proposalID2)
require.Len(t, votes, 1)
require.Equal(t, addrs[0], votes[0].Voter)
// Test query votes on Proposal 3
votes = getVotes(t, port, proposalID3)
require.Len(t, votes, 2)
require.True(t, addrs[0].String() == votes[0].Voter.String() || addrs[0].String() == votes[1].Voter.String())
require.True(t, addrs[1].String() == votes[0].Voter.String() || addrs[1].String() == votes[1].Voter.String())
}
func TestSlashingGetParams(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
res, body := Request(t, port, "GET", "/slashing/parameters", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var params slashing.Params
err := cdc.UnmarshalJSON([]byte(body), &params)
require.NoError(t, err)
}
func TestDistributionGetParams(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
res, body := Request(t, port, "GET", "/distribution/parameters", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &dclcommon.PrettyParams{}))
}
func TestDistributionFlow(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, valAddrs, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
valAddr := valAddrs[0]
operAddr := sdk.AccAddress(valAddr)
var rewards sdk.DecCoins
res, body := Request(t, port, "GET", fmt.Sprintf("/distribution/validators/%s/outstanding_rewards", valAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
var valDistInfo distrrest.ValidatorDistInfo
res, body = Request(t, port, "GET", "/distribution/validators/"+valAddr.String(), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &valDistInfo))
require.Equal(t, valDistInfo.OperatorAddress.String(), sdk.AccAddress(valAddr).String())
// Delegate some coins
delTokens := sdk.TokensFromTendermintPower(60)
resultTx := doDelegate(t, port, name1, pw, addr, valAddr, delTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
require.Equal(t, uint32(0), resultTx.Code)
// send some coins
_, resultTx = doTransfer(t, port, seed, name1, memo, pw, addr, fees)
tests.WaitForHeight(resultTx.Height+5, port)
require.Equal(t, uint32(0), resultTx.Code)
// Query outstanding rewards changed
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/validators/%s/outstanding_rewards", valAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
// Query validator distribution info
res, body = Request(t, port, "GET", "/distribution/validators/"+valAddr.String(), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &valDistInfo))
// Query validator's rewards
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/validators/%s/rewards", valAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
// Query self-delegation
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/rewards/%s", operAddr, valAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
// Query delegation
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/rewards/%s", addr, valAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &rewards))
// Query delegator's rewards total
var delRewards disttypes.QueryDelegatorTotalRewardsResponse
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/rewards", operAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, json.Unmarshal([]byte(body), &delRewards))
// Query delegator's withdrawal address
var withdrawAddr string
res, body = Request(t, port, "GET", fmt.Sprintf("/distribution/delegators/%s/withdraw_address", operAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &withdrawAddr))
require.Equal(t, operAddr.String(), withdrawAddr)
// Withdraw delegator's rewards
resultTx = doWithdrawDelegatorAllRewards(t, port, seed, name1, pw, addr, fees)
require.Equal(t, uint32(0), resultTx.Code)
}
func TestMintingQueries(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, _ := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
res, body := Request(t, port, "GET", "/minting/parameters", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var params mint.Params
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &params))
res, body = Request(t, port, "GET", "/minting/inflation", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var inflation sdk.Dec
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &inflation))
res, body = Request(t, port, "GET", "/minting/annual-provisions", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var annualProvisions sdk.Dec
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &annualProvisions))
}
func TestAccountBalanceQuery(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, _ := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
bz, err := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6")
require.NoError(t, err)
someFakeAddr := sdk.AccAddress(bz)
// empty account
res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", someFakeAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.Contains(t, body, `"type":"auth/Account"`)
// empty account balance
res, body = Request(t, port, "GET", fmt.Sprintf("/bank/balances/%s", someFakeAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.Contains(t, body, "[]")
}