Merge PR #3674: Remove password/keybase from REST Client

This commit is contained in:
Alexander Bezobchuk
2019-02-19 10:15:39 -08:00
committed by Jack Zampolin
parent 6967de1073
commit e39debd359
26 changed files with 335 additions and 1335 deletions
+29 -176
View File
@@ -11,7 +11,6 @@ import (
"testing"
"time"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client"
@@ -23,7 +22,6 @@ import (
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"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"
@@ -48,119 +46,6 @@ func init() {
version.Version = os.Getenv("VERSION")
}
func TestSeedsAreDifferent(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()
mnemonic1 := getKeysSeed(t, port)
mnemonic2 := getKeysSeed(t, port)
require.NotEqual(t, mnemonic1, mnemonic2)
}
func TestKeyRecover(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
myName1 := "TestKeyRecover_1"
myName2 := "TestKeyRecover_2"
mnemonic := getKeysSeed(t, port)
expectedInfo, _ := kb.CreateAccount(myName1, mnemonic, "", pw, 0, 0)
expectedAddress := expectedInfo.GetAddress().String()
expectedPubKey := sdk.MustBech32ifyAccPub(expectedInfo.GetPubKey())
// recover key
doRecoverKey(t, port, myName2, pw, mnemonic, 0, 0)
keys := getKeys(t, port)
require.Equal(t, expectedAddress, keys[0].Address)
require.Equal(t, expectedPubKey, keys[0].PubKey)
}
func TestKeyRecoverHDPath(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}, true)
defer cleanup()
mnemonic := getKeysSeed(t, port)
for account := uint32(0); account < 50; account += 13 {
for index := uint32(0); index < 50; index += 15 {
name1Idx := fmt.Sprintf("name1_%d_%d", account, index)
name2Idx := fmt.Sprintf("name2_%d_%d", account, index)
expectedInfo, _ := kb.CreateAccount(name1Idx, mnemonic, "", pw, account, index)
expectedAddress := expectedInfo.GetAddress().String()
expectedPubKey := sdk.MustBech32ifyAccPub(expectedInfo.GetPubKey())
// recover key
doRecoverKey(t, port, name2Idx, pw, mnemonic, account, index)
keysName2Idx := getKey(t, port, name2Idx)
require.Equal(t, expectedAddress, keysName2Idx.Address)
require.Equal(t, expectedPubKey, keysName2Idx.PubKey)
}
}
}
func TestKeys(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr1, _ := CreateAddr(t, name1, pw, kb)
addr1Bech32 := addr1.String()
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr1}, true)
defer cleanup()
// get new seed & recover key
mnemonic2 := getKeysSeed(t, port)
doRecoverKey(t, port, name2, pw, mnemonic2, 0, 0)
// add key
mnemonic3 := mnemonic2
resp := doKeysPost(t, port, name3, pw, mnemonic3, 0, 0)
addr3Bech32 := resp.Address
_, err = sdk.AccAddressFromBech32(addr3Bech32)
require.NoError(t, err, "Failed to return a correct bech32 address")
// test if created account is the correct account
expectedInfo3, _ := kb.CreateAccount(name3, mnemonic3, "", pw, 0, 0)
expectedAddress3 := sdk.AccAddress(expectedInfo3.GetPubKey().Address()).String()
require.Equal(t, expectedAddress3, addr3Bech32)
// existing keys
require.Equal(t, name1, getKey(t, port, name1).Name, "Did not serve keys name correctly")
require.Equal(t, addr1Bech32, getKey(t, port, name1).Address, "Did not serve keys Address correctly")
require.Equal(t, name2, getKey(t, port, name2).Name, "Did not serve keys name correctly")
require.Equal(t, addr3Bech32, getKey(t, port, name2).Address, "Did not serve keys Address correctly")
require.Equal(t, name3, getKey(t, port, name3).Name, "Did not serve keys name correctly")
require.Equal(t, addr3Bech32, getKey(t, port, name3).Address, "Did not serve keys Address correctly")
// select key
key := getKey(t, port, name3)
require.Equal(t, name3, key.Name, "Did not serve keys name correctly")
require.Equal(t, addr3Bech32, key.Address, "Did not serve keys Address correctly")
// update key
updateKey(t, port, name3, pw, altPw, false)
// here it should say unauthorized as we changed the password before
updateKey(t, port, name3, pw, altPw, true)
// delete key
deleteKey(t, port, name3, altPw)
}
func TestVersion(t *testing.T) {
// skip the test if the VERSION environment variable has not been set
if version.Version == "" {
@@ -255,7 +140,7 @@ func TestCoinSend(t *testing.T) {
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, false, fees)
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)
@@ -268,11 +153,11 @@ func TestCoinSend(t *testing.T) {
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, false, fees)
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, false, fees)
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)
@@ -291,7 +176,7 @@ func TestCoinSend(t *testing.T) {
// run successful tx
gas := fmt.Sprintf("%d", gasEstResp.GasEstimate)
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, gas, 1.0, false, false, fees)
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)
@@ -316,7 +201,9 @@ func TestCoinSendAccAuto(t *testing.T) {
initialBalance := acc.GetCoins()
// send a transfer tx without specifying account number and sequence
res, body, _ := doTransferWithGasAccAuto(t, port, seed, name1, memo, pw, "200000", 1.0, false, false, fees)
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
@@ -336,7 +223,7 @@ func TestCoinMultiSendGenerateOnly(t *testing.T) {
defer cleanup()
// generate only
res, body, _ := doTransferWithGas(t, port, seed, "", memo, "", addr, "200000", 1, false, true, fees)
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
@@ -356,6 +243,7 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.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)
@@ -371,74 +259,40 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
// generate tx
gas := fmt.Sprintf("%d", gasEstResp.GasEstimate)
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, "", addr, gas, 1, false, true, fees)
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, "", addr, gas, 1, false, false, fees)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var msg auth.StdTx
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &msg))
require.Equal(t, len(msg.Msgs), 1)
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))
require.Equal(t, memo, msg.Memo)
require.NotZero(t, msg.Fee.Gas)
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(msg.Fee.Gas)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
// sign tx
var signedMsg auth.StdTx
payload := authrest.SignBody{
Tx: msg,
BaseReq: rest.NewBaseReq(
name1, pw, "", viper.GetString(client.FlagChainID), "", "",
accnum, sequence, nil, nil, false, false,
),
}
json, err := cdc.MarshalJSON(payload)
require.Nil(t, err)
res, body = Request(t, port, "POST", "/tx/sign", json)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &signedMsg))
require.Equal(t, len(msg.Msgs), len(signedMsg.Msgs))
require.Equal(t, msg.Msgs[0].Type(), signedMsg.Msgs[0].Type())
require.Equal(t, msg.Msgs[0].GetSigners(), signedMsg.Msgs[0].GetSigners())
require.Equal(t, 1, len(signedMsg.Signatures))
// broadcast tx
broadcastPayload := struct {
Tx auth.StdTx `json:"tx"`
Return string `json:"return"`
}{Tx: signedMsg, Return: "block"}
json, err = cdc.MarshalJSON(broadcastPayload)
require.Nil(t, err)
res, body = Request(t, port, "POST", "/tx/broadcast", json)
require.Equal(t, http.StatusOK, res.StatusCode, body)
gasEstimate := int64(tx.Fee.Gas)
_, body = signAndBroadcastGenTx(t, port, name1, pw, body, acc, 1.0, false)
// check if tx was committed
var resultTx sdk.TxResponse
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &resultTx))
require.Equal(t, uint32(0), resultTx.Code)
require.Equal(t, gasEstimate, resultTx.GasWanted)
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) {
// Setup
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()
// Make a transaction to test with
res, body, _ := doTransferWithGas(t, port, seed, name1, memo, "", addr, "2", 1, false, true, fees)
res, body, _ := doTransferWithGas(t, port, seed, name1, memo, "", addr, "2", 1, false, false, fees)
var tx auth.StdTx
cdc.UnmarshalJSON([]byte(body), &tx)
// Build the request
// build the request
encodeReq := struct {
Tx auth.StdTx `json:"tx"`
}{Tx: tx}
@@ -446,20 +300,19 @@ func TestEncodeTx(t *testing.T) {
res, body = Request(t, port, "POST", "/tx/encode", encodedJSON)
// Make sure it came back ok, and that we can decode it back to the transaction
// 200 response
// 200 response.
require.Equal(t, http.StatusOK, res.StatusCode, body)
encodeResp := struct {
Tx string `json:"tx"`
}{}
// No error decoding the JSON
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &encodeResp))
// Check that the base64 decodes
// verify that the base64 decodes
decodedBytes, err := base64.StdEncoding.DecodeString(encodeResp.Tx)
require.Nil(t, err)
// Check that the transaction decodes as expected
// check that the transaction decodes as expected
var decodedTx auth.StdTx
require.Nil(t, cdc.UnmarshalBinaryLengthPrefixed(decodedBytes, &decodedTx))
require.Equal(t, memo, decodedTx.Memo)
+13 -240
View File
@@ -3,14 +3,12 @@ swagger: "2.0"
info:
version: "3.0"
title: Gaia-Lite for Cosmos
description: A REST interface for state queries, transaction generation, signing, and broadcast.
description: A REST interface for state queries, transaction generation and broadcasting.
tags:
- name: ICS0
description: Tendermint APIs, such as query blocks, transactions and validatorset
- name: ICS1
description: Key management APIs
- name: ICS20
description: Create, sign and broadcast transactions
description: Create and broadcast transactions
- name: ICS21
description: Stake module APIs
- name: ICS22
@@ -269,42 +267,6 @@ paths:
$ref: "#/definitions/BroadcastTxCommitResult"
500:
description: Internal Server Error
/tx/sign:
post:
tags:
- ICS20
summary: Sign a Tx
description: Sign a Tx providing locally stored account and according password
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: sendToken
description: sign tx
required: true
schema:
type: object
properties:
base_req:
$ref: "#/definitions/BaseReq"
tx:
$ref: "#/definitions/StdTx"
append_sig:
type: boolean
example: true
responses:
200:
description: The signed Tx
schema:
$ref: "#/definitions/StdTx"
400:
description: The Tx was malformated or key doesn't exist
401:
description: Key password is wrong
500:
description: Server internal error
/tx/broadcast:
post:
tags:
@@ -393,8 +355,7 @@ paths:
description: Server internal error
/bank/accounts/{address}/transfers:
post:
summary: Send coins (build -> sign -> send)
description: Send coins (build -> sign -> send)
summary: Send coins from one account to another
tags:
- ICS20
consumes:
@@ -409,7 +370,7 @@ paths:
type: string
- in: body
name: account
description: The password of the account to remove from the KMS
description: The sender and tx information
required: true
schema:
type: object
@@ -422,188 +383,13 @@ paths:
$ref: "#/definitions/Coin"
responses:
202:
description: Tx was send and will probably be added to the next block
description: Tx was succesfully generated
schema:
$ref: "#/definitions/BroadcastTxCommitResult"
$ref: "#/definitions/StdTx"
400:
description: Invalid request
401:
description: Key password is wrong
500:
description: Server internal error
/keys:
get:
summary: List of accounts stored locally
tags:
- ICS1
produces:
- application/json
responses:
200:
description: Array of accounts
schema:
type: array
items:
$ref: "#/definitions/KeyOutput"
500:
description: Server internal error
post:
summary: Create a new account locally
tags:
- ICS1
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: account
description: The account to create
schema:
type: object
required:
- name
- password
- seed
properties:
name:
type: string
password:
type: string
seed:
type: string
responses:
200:
description: Returns account information of the created key
schema:
$ref: "#/definitions/KeyOutput"
400:
description: Invalid request
409:
description: Key name confliction
500:
description: Server internal error
/keys/seed:
get:
summary: Create a new seed to create a new account with
tags:
- ICS1
responses:
200:
description: 24 word Seed
schema:
type: string
example: blossom pool issue kidney elevator blame furnace winter account merry vessel security depend exact travel bargain problem jelly rural net again mask roast chest
/keys/{name}/recover:
post:
summary: Recover a account from a seed
tags:
- ICS1
consumes:
- application/json
produces:
- application/json
parameters:
- in: path
name: name
description: Account name
required: true
type: string
- in: body
name: pwdAndSeed
description: Provide password and seed to recover a key
schema:
type: object
required:
- password
- seed
properties:
password:
type: string
seed:
type: string
responses:
200:
description: Returns account information of the recovered key
schema:
$ref: "#/definitions/KeyOutput"
400:
description: Invalid request
409:
description: Key name confliction
500:
description: Server internal error
/keys/{name}:
parameters:
- in: path
name: name
description: Account name
required: true
type: string
get:
summary: Get a certain locally stored account
tags:
- ICS1
produces:
- application/json
responses:
200:
description: Locally stored account
schema:
$ref: "#/definitions/KeyOutput"
404:
description: Key doesn't exist
put:
summary: Update the password for this account in the KMS
tags:
- ICS1
consumes:
- application/json
parameters:
- in: body
name: account
description: The new and old password
schema:
type: object
required:
- new_password
- old_password
properties:
new_password:
type: string
old_password:
type: string
responses:
200:
description: Updated password
401:
description: Key password is wrong
404:
description: Key doesn't exist
delete:
summary: Remove an account
tags:
- ICS1
consumes:
- application/json
parameters:
- in: body
name: account
description: The password of the account to remove from the KMS
schema:
type: object
required:
- password
properties:
password:
type: string
responses:
200:
description: Removed account
401:
description: Key password is wrong
404:
description: Key doesn't exist
/auth/accounts/{address}:
get:
summary: Get the account information on blockchain
@@ -861,7 +647,7 @@ paths:
parameters:
- in: body
name: delegation
description: The password of the account to remove from the KMS
description: The sender and tx information
schema:
type: object
properties:
@@ -884,13 +670,11 @@ paths:
- application/json
responses:
200:
description: OK
description: Tx was succesfully generated
schema:
$ref: "#/definitions/BroadcastTxCommitResult"
$ref: "#/definitions/StdTx"
400:
description: Invalid delegator address or redelegation request body
401:
description: Key password is wrong
500:
description: Internal Server Error
/staking/delegators/{delegatorAddr}/validators:
@@ -1170,16 +954,14 @@ paths:
type: object
properties:
base_req:
$ref: "#/definitions/BaseReq"
$ref: "#/definitions/StdTx"
responses:
200:
description: OK
description: Tx was succesfully generated
schema:
$ref: "#/definitions/BroadcastTxCommitResult"
400:
description: Invalid validator address or base_req
401:
description: Key password is wrong
500:
description: Internal Server Error
/slashing/parameters:
@@ -1246,13 +1028,11 @@ paths:
$ref: "#/definitions/Coin"
responses:
200:
description: OK
description: Tx was succesfully generated
schema:
$ref: "#/definitions/BroadcastTxCommitResult"
$ref: "#/definitions/StdTx"
400:
description: Invalid proposal body
401:
description: Key password is wrong
500:
description: Internal Server Error
get:
@@ -2189,9 +1969,6 @@ definitions:
type: string
example: "cosmos1g9ahr6xhht5rmqven628nklxluzyv8z9jqjcmc"
description: Sender address or Keybase name to generate a transaction
password:
type: string
example: "12345678"
memo:
type: string
example: "Sent via Cosmos Voyager 🚀"
@@ -2214,10 +1991,6 @@ definitions:
type: array
items:
$ref: "#/definitions/Coin"
generate_only:
type: boolean
example: false
description: Create a JSON transaction that can be signed client side instead of actually signing and broadcasting
simulate:
type: boolean
example: false
+220 -130
View File
@@ -20,6 +20,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/utils"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/client/tx"
@@ -397,7 +398,6 @@ func startLCD(logger log.Logger, listenAddr string, cdc *codec.Codec, t *testing
// NOTE: If making updates here also update cmd/gaia/cmd/gaiacli/main.go
func registerRoutes(rs *RestServer) {
keys.RegisterRoutes(rs.Mux, rs.CliCtx.Indent)
rpc.RegisterRoutes(rs.CliCtx, rs.Mux)
tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
authrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, auth.StoreKey)
@@ -647,52 +647,42 @@ func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account {
// ICS 20 - Tokens
// ----------------------------------------------------------------------
// POST /tx/sign Sign a Tx
func doSign(t *testing.T, port, name, password, chainID string, accnum, sequence uint64, msg auth.StdTx) auth.StdTx {
var signedMsg auth.StdTx
payload := authrest.SignBody{
Tx: msg,
BaseReq: rest.NewBaseReq(
name, password, "", chainID, "", "", accnum, sequence, nil, nil, false, false,
),
}
json, err := cdc.MarshalJSON(payload)
require.Nil(t, err)
res, body := Request(t, port, "POST", "/tx/sign", json)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &signedMsg))
return signedMsg
}
// POST /tx/broadcast Send a signed Tx
func doBroadcast(t *testing.T, port string, msg auth.StdTx) sdk.TxResponse {
tx := authrest.BroadcastReq{Tx: msg, Return: "block"}
req, err := cdc.MarshalJSON(tx)
require.Nil(t, err)
res, body := Request(t, port, "POST", "/tx/broadcast", req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var resultTx sdk.TxResponse
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &resultTx))
return resultTx
}
func doBroadcast(t *testing.T, port string, tx auth.StdTx) (*http.Response, string) {
txReq := authrest.BroadcastReq{Tx: tx, Return: "block"}
// 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, memo, password string, addr sdk.AccAddress, fees sdk.Coins) (receiveAddr sdk.AccAddress, resultTx sdk.TxResponse) {
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)
req, err := cdc.MarshalJSON(txReq)
require.Nil(t, err)
return receiveAddr, resultTx
return Request(t, port, "POST", "/tx/broadcast", req)
}
// doTransfer performs a balance transfer with auto gas calculation. It also signs
// the tx and broadcasts it.
func doTransfer(
t *testing.T, port, seed, name, memo, pwd string, addr sdk.AccAddress, fees sdk.Coins,
) (sdk.AccAddress, sdk.TxResponse) {
resp, body, recvAddr := doTransferWithGas(
t, port, seed, name, memo, pwd, addr, "", 1.0, false, true, fees,
)
require.Equal(t, http.StatusOK, resp.StatusCode, resp)
var txResp sdk.TxResponse
err := cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return recvAddr, txResp
}
// doTransferWithGas performs a balance transfer with a specified gas value. The
// broadcast parameter determines if the tx should only be generated or also
// signed and broadcasted. The sending account's number and sequence are
// determined prior to generating the tx.
func doTransferWithGas(
t *testing.T, port, seed, from, memo, password string, addr sdk.AccAddress,
gas string, gasAdjustment float64, simulate, generateOnly bool, fees sdk.Coins,
) (res *http.Response, body string, receiveAddr sdk.AccAddress) {
t *testing.T, port, seed, name, memo, pwd string, addr sdk.AccAddress,
gas string, gasAdjustment float64, simulate, broadcast bool, fees sdk.Coins,
) (resp *http.Response, body string, receiveAddr sdk.AccAddress) {
// create receive address
kb := crkeys.NewInMemory()
@@ -708,15 +698,9 @@ func doTransferWithGas(
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
if generateOnly {
// generate only txs do not use a Keybase so the address must be used
from = addr.String()
}
from := addr.String()
baseReq := rest.NewBaseReq(
from, password, memo, chainID, gas,
fmt.Sprintf("%f", gasAdjustment), accnum, sequence, fees, nil,
generateOnly, simulate,
from, memo, chainID, gas, fmt.Sprintf("%f", gasAdjustment), accnum, sequence, fees, nil, simulate,
)
sr := bankrest.SendReq{
@@ -727,17 +711,28 @@ func doTransferWithGas(
req, err := cdc.MarshalJSON(sr)
require.NoError(t, err)
res, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req)
return
// generate tx
resp, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req)
if !broadcast {
return resp, body, receiveAddr
}
// sign and broadcast
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, gasAdjustment, simulate)
return resp, body, receiveAddr
}
// doTransferWithGasAccAuto is similar to doTransferWithGas except that it
// automatically determines the account's number and sequence when generating the
// tx.
func doTransferWithGasAccAuto(
t *testing.T, port, seed, from, memo, password string, gas string,
gasAdjustment float64, simulate, generateOnly bool, fees sdk.Coins,
) (res *http.Response, body string, receiveAddr sdk.AccAddress) {
t *testing.T, port, seed, name, memo, pwd string, addr sdk.AccAddress,
gas string, gasAdjustment float64, simulate, broadcast bool, fees sdk.Coins,
) (resp *http.Response, body string, receiveAddr sdk.AccAddress) {
// create receive address
kb := crkeys.NewInMemory()
acc := getAccount(t, port, addr)
receiveInfo, _, err := kb.CreateMnemonic(
"receive_address", crkeys.English, gapp.DefaultKeyPass, crkeys.SigningAlgo("secp256k1"),
@@ -747,9 +742,9 @@ func doTransferWithGasAccAuto(
receiveAddr = sdk.AccAddress(receiveInfo.GetPubKey().Address())
chainID := viper.GetString(client.FlagChainID)
from := addr.String()
baseReq := rest.NewBaseReq(
from, password, memo, chainID, gas,
fmt.Sprintf("%f", gasAdjustment), 0, 0, fees, nil, generateOnly, simulate,
from, memo, chainID, gas, fmt.Sprintf("%f", gasAdjustment), 0, 0, fees, nil, simulate,
)
sr := bankrest.SendReq{
@@ -760,8 +755,45 @@ func doTransferWithGasAccAuto(
req, err := cdc.MarshalJSON(sr)
require.NoError(t, err)
res, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req)
return
resp, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers", receiveAddr), req)
if !broadcast {
return resp, body, receiveAddr
}
// sign and broadcast
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, gasAdjustment, simulate)
return resp, body, receiveAddr
}
// signAndBroadcastGenTx accepts a successfully generated unsigned tx, signs it,
// and broadcasts it.
func signAndBroadcastGenTx(
t *testing.T, port, name, pwd, genTx string, acc auth.Account, gasAdjustment float64, simulate bool,
) (resp *http.Response, body string) {
chainID := viper.GetString(client.FlagChainID)
var tx auth.StdTx
err := cdc.UnmarshalJSON([]byte(genTx), &tx)
require.Nil(t, err)
txbldr := txbuilder.NewTxBuilder(
utils.GetTxEncoder(cdc),
acc.GetAccountNumber(),
acc.GetSequence(),
tx.Fee.Gas,
gasAdjustment,
simulate,
chainID,
tx.Memo,
tx.Fee.Amount,
nil,
)
signedTx, err := txbldr.SignStdTx(name, pwd, tx, false)
require.NoError(t, err)
return doBroadcast(t, port, signedTx)
}
// ----------------------------------------------------------------------
@@ -769,30 +801,40 @@ func doTransferWithGasAccAuto(
// ----------------------------------------------------------------------
// POST /staking/delegators/{delegatorAddr}/delegations Submit delegation
func doDelegate(t *testing.T, port, name, password string,
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) {
func doDelegate(
t *testing.T, port, name, pwd string, delAddr sdk.AccAddress,
valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins,
) sdk.TxResponse {
acc := getAccount(t, port, delAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
msg := msgDelegationsInput{
BaseReq: baseReq,
DelegatorAddr: delAddr,
ValidatorAddr: valAddr,
Delegation: sdk.NewCoin(sdk.DefaultBondDenom, amount),
}
req, err := cdc.MarshalJSON(msg)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/delegations", delAddr.String()), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var result sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &result)
require.Nil(t, err)
resp, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/delegations", delAddr.String()), req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return result
// sign and broadcast
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
type msgDelegationsInput struct {
@@ -803,31 +845,39 @@ type msgDelegationsInput struct {
}
// POST /staking/delegators/{delegatorAddr}/delegations Submit delegation
func doUndelegate(t *testing.T, port, name, password string,
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) {
func doUndelegate(
t *testing.T, port, name, pwd string, delAddr sdk.AccAddress,
valAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins,
) sdk.TxResponse {
acc := getAccount(t, port, delAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
msg := msgUndelegateInput{
BaseReq: baseReq,
DelegatorAddr: delAddr,
ValidatorAddr: valAddr,
SharesAmount: sdk.NewDecFromInt(amount),
}
req, err := cdc.MarshalJSON(msg)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/unbonding_delegations", delAddr), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
resp, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/unbonding_delegations", delAddr), req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var result sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &result)
require.Nil(t, err)
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return result
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
type msgUndelegateInput struct {
@@ -838,17 +888,18 @@ type msgUndelegateInput struct {
}
// POST /staking/delegators/{delegatorAddr}/delegations Submit delegation
func doBeginRedelegation(t *testing.T, port, name, password string,
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount sdk.Int,
fees sdk.Coins) (resultTx sdk.TxResponse) {
func doBeginRedelegation(
t *testing.T, port, name, pwd string, delAddr sdk.AccAddress, valSrcAddr,
valDstAddr sdk.ValAddress, amount sdk.Int, fees sdk.Coins,
) sdk.TxResponse {
acc := getAccount(t, port, delAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
msg := stakingrest.MsgBeginRedelegateInput{
BaseReq: baseReq,
DelegatorAddr: delAddr,
@@ -856,17 +907,21 @@ func doBeginRedelegation(t *testing.T, port, name, password string,
ValidatorDstAddr: valDstAddr,
SharesAmount: sdk.NewDecFromInt(amount),
}
req, err := cdc.MarshalJSON(msg)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/redelegations", delAddr), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
resp, body := Request(t, port, "POST", fmt.Sprintf("/staking/delegators/%s/redelegations", delAddr), req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var result sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &result)
require.Nil(t, err)
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return result
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
type msgBeginRedelegateInput struct {
@@ -1073,15 +1128,18 @@ func getStakingParams(t *testing.T, port string) staking.Params {
// ICS 22 - Gov
// ----------------------------------------------------------------------
// POST /gov/proposals Submit a proposal
func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress,
amount sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) {
func doSubmitProposal(
t *testing.T, port, seed, name, pwd string, proposerAddr sdk.AccAddress,
amount sdk.Int, fees sdk.Coins,
) sdk.TxResponse {
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
pr := govrest.PostProposalReq{
Title: "Test",
Description: "test",
@@ -1095,14 +1153,17 @@ func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerA
require.NoError(t, err)
// submitproposal
res, body := Request(t, port, "POST", "/gov/proposals", req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
resp, body := Request(t, port, "POST", "/gov/proposals", req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var results sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return results
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
// GET /gov/proposals Query proposals
@@ -1161,15 +1222,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 sdk.Int, fees sdk.Coins) (resultTx sdk.TxResponse) {
func doDeposit(
t *testing.T, port, seed, name, pwd string, proposerAddr sdk.AccAddress,
proposalID uint64, amount sdk.Int, fees sdk.Coins,
) sdk.TxResponse {
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
dr := govrest.DepositReq{
Depositor: proposerAddr,
Amount: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, amount)},
@@ -1179,14 +1243,17 @@ func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk
req, err := cdc.MarshalJSON(dr)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
resp, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var results sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return results
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
// GET /gov/proposals/{proposalId}/deposits Query deposits
@@ -1210,14 +1277,19 @@ 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, option string, fees sdk.Coins) (resultTx sdk.TxResponse) {
func doVote(
t *testing.T, port, seed, name, pwd string, proposerAddr sdk.AccAddress,
proposalID uint64, option string, fees sdk.Coins,
) sdk.TxResponse {
// get the account to get the sequence
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
vr := govrest.VoteReq{
Voter: proposerAddr,
Option: option,
@@ -1227,14 +1299,17 @@ func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.Ac
req, err := cdc.MarshalJSON(vr)
require.NoError(t, err)
res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
resp, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var results sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return results
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
// GET /gov/proposals/{proposalId}/votes Query voters
@@ -1339,24 +1414,32 @@ 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, fees sdk.Coins) (resultTx sdk.TxResponse) {
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", 1, 1, fees, nil, false, false)
func doUnjail(
t *testing.T, port, seed, name, pwd string, valAddr sdk.ValAddress, fees sdk.Coins,
) sdk.TxResponse {
acc := getAccount(t, port, sdk.AccAddress(valAddr.Bytes()))
from := acc.GetAddress().String()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(from, "", chainID, "", "", 1, 1, fees, nil, false)
ur := slashingrest.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)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
resp, body := Request(t, port, "POST", fmt.Sprintf("/slashing/validators/%s/unjail", valAddr.String()), req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return results
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
type unjailReq struct {
@@ -1366,27 +1449,34 @@ type unjailReq struct {
// ICS24 - fee distribution
// POST /distribution/delegators/{delgatorAddr}/rewards Withdraw delegator rewards
func doWithdrawDelegatorAllRewards(t *testing.T, port, seed, name, password string,
delegatorAddr sdk.AccAddress, fees sdk.Coins) (resultTx sdk.TxResponse) {
func doWithdrawDelegatorAllRewards(
t *testing.T, port, seed, name, pwd string, delegatorAddr sdk.AccAddress, fees sdk.Coins,
) sdk.TxResponse {
// get the account to get the sequence
acc := getAccount(t, port, delegatorAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
baseReq := rest.NewBaseReq(name, password, "", chainID, "", "", accnum, sequence, fees, nil, false, false)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
wr := struct {
BaseReq rest.BaseReq `json:"base_req"`
}{BaseReq: baseReq}
req := cdc.MustMarshalJSON(wr)
res, body := Request(t, port, "POST", fmt.Sprintf("/distribution/delegators/%s/rewards", delegatorAddr), req)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results sdk.TxResponse
cdc.MustUnmarshalJSON([]byte(body), &results)
resp, body := Request(t, port, "POST", fmt.Sprintf("/distribution/delegators/%s/rewards", delegatorAddr), req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
return results
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var txResp sdk.TxResponse
err := cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
func mustParseDecCoins(dcstring string) sdk.DecCoins {