Merge pull request #994 from cosmos/matt/stake-rest

Staking REST endpoints
This commit is contained in:
Ethan Buchman 2018-05-30 19:54:48 -04:00 committed by GitHub
commit 7f18dbf7a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 440 additions and 72 deletions

View File

@ -56,6 +56,7 @@ FEATURES
* [stake] Creation of a validator/delegation generics in `/types`
* [stake] Helper Description of the store in x/stake/store.md
* [stake] removed use of caches in the stake keeper
* [stake] Added REST API
* [Makefile] Added terraform/ansible playbooks to easily create remote testnets on Digital Ocean
BUG FIXES

View File

@ -59,7 +59,7 @@ func (ctx CoreContext) QuerySubspace(cdc *wire.Codec, subspace []byte, storeName
// Query from Tendermint with the provided storename and path
func (ctx CoreContext) query(key cmn.HexBytes, storeName, endPath string) (res []byte, err error) {
path := fmt.Sprintf("/store/%s/key", storeName)
path := fmt.Sprintf("/store/%s/%s", storeName, endPath)
node, err := ctx.GetNode()
if err != nil {
return res, err

View File

@ -2,6 +2,7 @@ package lcd
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
@ -16,6 +17,7 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
cryptoKeys "github.com/tendermint/go-crypto/keys"
tmcfg "github.com/tendermint/tendermint/config"
nm "github.com/tendermint/tendermint/node"
@ -31,17 +33,21 @@ import (
client "github.com/cosmos/cosmos-sdk/client"
keys "github.com/cosmos/cosmos-sdk/client/keys"
bapp "github.com/cosmos/cosmos-sdk/examples/basecoin/app"
btypes "github.com/cosmos/cosmos-sdk/examples/basecoin/types"
gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
tests "github.com/cosmos/cosmos-sdk/tests"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/stake"
)
var (
coinDenom = "mycoin"
coinDenom = "steak"
coinAmount = int64(10000000)
validatorAddr1 = ""
validatorAddr2 = ""
// XXX bad globals
name = "test"
password = "0123456789"
@ -220,6 +226,7 @@ func TestValidators(t *testing.T) {
func TestCoinSend(t *testing.T) {
// query empty
//res, body := request(t, port, "GET", "/accounts/8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6", nil)
res, body := request(t, port, "GET", "/accounts/8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6", nil)
require.Equal(t, http.StatusNoContent, res.StatusCode, body)
@ -309,6 +316,63 @@ func TestTxs(t *testing.T) {
// assert.NotEqual(t, "[]", body)
}
func TestValidatorsQuery(t *testing.T) {
validators := getValidators(t)
assert.Equal(t, len(validators), 2)
// make sure all the validators were found (order unknown because sorted by owner addr)
foundVal1, foundVal2 := false, false
res1, res2 := hex.EncodeToString(validators[0].Owner), hex.EncodeToString(validators[1].Owner)
if res1 == validatorAddr1 || res2 == validatorAddr1 {
foundVal1 = true
}
if res1 == validatorAddr2 || res2 == validatorAddr2 {
foundVal2 = true
}
assert.True(t, foundVal1, "validatorAddr1 %v, res1 %v, res2 %v", validatorAddr1, res1, res2)
assert.True(t, foundVal2, "validatorAddr2 %v, res1 %v, res2 %v", validatorAddr2, res1, res2)
}
func TestBond(t *testing.T) {
// create bond TX
resultTx := doBond(t, port, seed)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was commited
assert.Equal(t, uint32(0), resultTx.CheckTx.Code)
assert.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// query sender
acc := getAccount(t, sendAddr)
coins := acc.GetCoins()
assert.Equal(t, int64(87), coins.AmountOf(coinDenom))
// query candidate
bond := getDelegation(t, sendAddr, validatorAddr1)
assert.Equal(t, "10/1", bond.Shares.String())
}
func TestUnbond(t *testing.T) {
// create unbond TX
resultTx := doUnbond(t, port, seed)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was commited
assert.Equal(t, uint32(0), resultTx.CheckTx.Code)
assert.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// query sender
acc := getAccount(t, sendAddr)
coins := acc.GetCoins()
assert.Equal(t, int64(98), coins.AmountOf(coinDenom))
// query candidate
bond := getDelegation(t, sendAddr, validatorAddr1)
assert.Equal(t, "9/1", bond.Shares.String())
}
//__________________________________________________________
// helpers
@ -324,26 +388,18 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
if err != nil {
return nil, nil, err
}
var info cryptoKeys.Info
info, seed, err = kb.Create(name, password, cryptoKeys.AlgoEd25519) // XXX global seed
if err != nil {
return nil, nil, err
}
pubKey := info.PubKey
sendAddr = pubKey.Address().String() // XXX global
config := GetConfig()
config.Consensus.TimeoutCommit = 1000
config.Consensus.SkipTimeoutCommit = false
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
// logger = log.NewFilter(logger, log.AllowError())
logger = log.NewFilter(logger, log.AllowError())
privValidatorFile := config.PrivValidatorFile()
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
db := dbm.NewMemDB()
app := bapp.NewBasecoinApp(logger, db)
cdc = bapp.MakeCodec() // XXX
app := gapp.NewGaiaApp(logger, db)
cdc = gapp.MakeCodec() // XXX
genesisFile := config.GenesisFile()
genDoc, err := tmtypes.GenesisDocFromFile(genesisFile)
@ -351,21 +407,53 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
return nil, nil, err
}
coins := sdk.Coins{{coinDenom, coinAmount}}
appState := map[string]interface{}{
"accounts": []*btypes.GenesisAccount{
{
Name: "tester",
Address: pubKey.Address(),
Coins: coins,
},
genDoc.Validators = append(genDoc.Validators,
tmtypes.GenesisValidator{
PubKey: crypto.GenPrivKeyEd25519().PubKey(),
Power: 1,
Name: "val",
},
}
stateBytes, err := json.Marshal(appState)
)
pk1 := genDoc.Validators[0].PubKey
pk2 := genDoc.Validators[1].PubKey
validatorAddr1 = hex.EncodeToString(pk1.Address())
validatorAddr2 = hex.EncodeToString(pk2.Address())
// NOTE it's bad practice to reuse pk address for the owner address but doing in the
// test for simplicity
var appGenTxs [2]json.RawMessage
appGenTxs[0], _, _, err = gapp.GaiaAppGenTxNF(cdc, pk1, pk1.Address(), "test_val1", true)
if err != nil {
return nil, nil, err
}
genDoc.AppStateJSON = stateBytes
appGenTxs[1], _, _, err = gapp.GaiaAppGenTxNF(cdc, pk2, pk2.Address(), "test_val2", true)
if err != nil {
return nil, nil, err
}
genesisState, err := gapp.GaiaAppGenState(cdc, appGenTxs[:])
if err != nil {
return nil, nil, err
}
// add the sendAddr to genesis
var info cryptoKeys.Info
info, seed, err = kb.Create(name, password, cryptoKeys.AlgoEd25519) // XXX global seed
if err != nil {
return nil, nil, err
}
sendAddr = info.PubKey.Address().String() // XXX global
accAuth := auth.NewBaseAccountWithAddress(info.PubKey.Address())
accAuth.Coins = sdk.Coins{{"steak", 100}}
acc := gapp.NewGenesisAccount(&accAuth)
genesisState.Accounts = append(genesisState.Accounts, acc)
appState, err := wire.MarshalJSONIndent(cdc, genesisState)
if err != nil {
return nil, nil, err
}
genDoc.AppStateJSON = appState
// LCD listen address
port = fmt.Sprintf("%d", 17377) // XXX
@ -379,7 +467,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
if err != nil {
return nil, nil, err
}
lcd, err := startLCD(logger, listenAddr)
lcd, err := startLCD(logger, listenAddr, cdc)
if err != nil {
return nil, nil, err
}
@ -418,7 +506,7 @@ func startTM(cfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, p
}
// start the LCD. note this blocks!
func startLCD(logger log.Logger, listenAddr string) (net.Listener, error) {
func startLCD(logger log.Logger, listenAddr string, cdc *wire.Codec) (net.Listener, error) {
handler := createHandler(cdc)
return tmrpc.StartHTTPServer(listenAddr, handler, logger)
}
@ -494,3 +582,81 @@ func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroad
return resultTx
}
func getDelegation(t *testing.T, delegatorAddr, candidateAddr string) stake.Delegation {
// get the account to get the sequence
res, body := request(t, port, "GET", "/stake/"+delegatorAddr+"/bonding_status/"+candidateAddr, nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var bond stake.Delegation
err := cdc.UnmarshalJSON([]byte(body), &bond)
require.Nil(t, err)
return bond
}
func doBond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, sendAddr)
sequence := acc.GetSequence()
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
"sequence": %d,
"delegate": [
{
"delegator_addr": "%x",
"validator_addr": "%s",
"bond": { "denom": "%s", "amount": 10 }
}
],
"unbond": []
}`, name, password, sequence, acc.GetAddress(), validatorAddr1, coinDenom))
res, body := request(t, port, "POST", "/stake/delegations", jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
err := cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
return results[0]
}
func doUnbond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, sendAddr)
sequence := acc.GetSequence()
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
"sequence": %d,
"bond": [],
"unbond": [
{
"delegator_addr": "%x",
"validator_addr": "%s",
"shares": "1"
}
]
}`, name, password, sequence, acc.GetAddress(), validatorAddr1))
res, body := request(t, port, "POST", "/stake/delegations", jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
err := cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
return results[0]
}
func getValidators(t *testing.T) []stake.Validator {
// get the account to get the sequence
res, body := request(t, port, "GET", "/stake/validators", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var validators stake.Validators
err := cdc.UnmarshalJSON([]byte(body), &validators)
require.Nil(t, err)
return validators
}

View File

@ -22,6 +22,7 @@ import (
auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
ibc "github.com/cosmos/cosmos-sdk/x/ibc/client/rest"
stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest"
)
const (
@ -83,5 +84,6 @@ func createHandler(cdc *wire.Codec) http.Handler {
auth.RegisterRoutes(ctx, r, cdc, "acc")
bank.RegisterRoutes(ctx, r, cdc, kb)
ibc.RegisterRoutes(ctx, r, cdc, kb)
stake.RegisterRoutes(ctx, r, cdc, kb)
return r
}

View File

@ -74,7 +74,7 @@ func GaiaAppInit() server.AppInit {
FlagsAppGenState: fsAppGenState,
FlagsAppGenTx: fsAppGenTx,
AppGenTx: GaiaAppGenTx,
AppGenState: GaiaAppGenState,
AppGenState: GaiaAppGenStateJSON,
}
}
@ -85,19 +85,31 @@ type GaiaGenTx struct {
PubKey crypto.PubKey `json:"pub_key"`
}
// Generate a gaia genesis transaction
// Generate a gaia genesis transaction with flags
func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
var addr sdk.Address
var secret string
clientRoot := viper.GetString(flagClientHome)
overwrite := viper.GetBool(flagOWK)
name := viper.GetString(flagName)
var addr sdk.Address
var secret string
addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite)
if err != nil {
return
}
mm := map[string]string{"secret": secret}
var bz []byte
bz, err = cdc.MarshalJSON(mm)
if err != nil {
return
}
cliPrint = json.RawMessage(bz)
return GaiaAppGenTxNF(cdc, pk, addr, name, overwrite)
}
// Generate a gaia genesis transaction without flags
func GaiaAppGenTxNF(cdc *wire.Codec, pk crypto.PubKey, addr sdk.Address, name string, overwrite bool) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
var bz []byte
gaiaGenTx := GaiaGenTx{
@ -111,13 +123,6 @@ func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) (
}
appGenTx = json.RawMessage(bz)
mm := map[string]string{"secret": secret}
bz, err = cdc.MarshalJSON(mm)
if err != nil {
return
}
cliPrint = json.RawMessage(bz)
validator = tmtypes.GenesisValidator{
PubKey: pk,
Power: freeFermionVal,
@ -127,7 +132,7 @@ func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) (
// Create the core parameters for genesis initialization for gaia
// note that the pubkey input is this machines pubkey
func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState GenesisState, err error) {
if len(appGenTxs) == 0 {
err = errors.New("must provide at least genesis transaction")
@ -171,10 +176,21 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso
}
// create the final app state
genesisState := GenesisState{
genesisState = GenesisState{
Accounts: genaccs,
StakeData: stakeData,
}
return
}
// GaiaAppGenState but with JSON
func GaiaAppGenStateJSON(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
// create the final app state
genesisState, err := GaiaAppGenState(cdc, appGenTxs)
if err != nil {
return nil, err
}
appState, err = wire.MarshalJSONIndent(cdc, genesisState)
return
}

View File

@ -35,7 +35,7 @@ type Tx interface {
//__________________________________________________________
// TxDeocder unmarshals transaction bytes
// TxDecoder unmarshals transaction bytes
type TxDecoder func(txBytes []byte) (Tx, Error)
//__________________________________________________________

View File

@ -72,25 +72,26 @@ func GetCmdQueryValidators(storeName string, cdc *wire.Codec) *cobra.Command {
return err
}
// parse out the candidates
var candidates []stake.Validator
// parse out the validators
var validators []stake.Validator
for _, KV := range resKVs {
var validator stake.Validator
cdc.MustUnmarshalBinary(KV.Value, &validator)
candidates = append(candidates, validator)
validators = append(validators, validator)
}
switch viper.Get(cli.OutputFlag) {
case "text":
for _, candidate := range candidates {
resp, err := candidate.HumanReadableString()
for _, validator := range validators {
resp, err := validator.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
}
case "json":
output, err := wire.MarshalJSONIndent(cdc, candidates)
output, err := wire.MarshalJSONIndent(cdc, validators)
if err != nil {
return err
}
@ -157,7 +158,7 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command {
return cmd
}
// get the command to query all the candidates bonded to a delegation
// get the command to query all the validators bonded to a delegation
func GetCmdQueryDelegations(storeName string, cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "delegations [delegator-addr]",
@ -176,7 +177,7 @@ func GetCmdQueryDelegations(storeName string, cdc *wire.Codec) *cobra.Command {
return err
}
// parse out the candidates
// parse out the validators
var delegations []stake.Delegation
for _, KV := range resKVs {
var delegation stake.Delegation

View File

@ -6,7 +6,6 @@ import (
"net/http"
"github.com/gorilla/mux"
"github.com/tendermint/go-crypto/keys"
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -14,14 +13,21 @@ import (
"github.com/cosmos/cosmos-sdk/x/stake"
)
// RegisterRoutes - Central function to define routes that get registered by the main application
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
r.HandleFunc("/stake/{delegator}/bonding_status/{validator}", BondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
func registerQueryRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) {
r.HandleFunc(
"/stake/{delegator}/bonding_status/{validator}",
bondingStatusHandlerFn(ctx, "stake", cdc),
).Methods("GET")
r.HandleFunc(
"/stake/validators",
validatorsHandlerFn(ctx, "stake", cdc),
).Methods("GET")
}
// BondingStatusHandlerFn - http request handler to query delegator bonding status
func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
// http request handler to query delegator bonding status
func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// read parameters
vars := mux.Vars(r)
delegator := vars["delegator"]
@ -76,3 +82,43 @@ func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase,
w.Write(output)
}
}
// http request handler to query list of validators
func validatorsHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
kvs, err := ctx.QuerySubspace(cdc, stake.ValidatorsKey, storeName)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Couldn't query validators. Error: %s", err.Error())))
return
}
// the query will return empty if there are no validators
if len(kvs) == 0 {
w.WriteHeader(http.StatusNoContent)
return
}
// parse out the validators
validators := make([]stake.Validator, len(kvs))
for i, kv := range kvs {
var validator stake.Validator
err = cdc.UnmarshalBinary(kv.Value, &validator)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
return
}
validators[i] = validator
}
output, err := cdc.MarshalJSON(validators)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}

View File

@ -0,0 +1,15 @@
package rest
import (
"github.com/gorilla/mux"
"github.com/tendermint/go-crypto/keys"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/wire"
)
// RegisterRoutes registers staking-related REST handlers to a router
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
registerQueryRoutes(ctx, r, cdc)
registerTxRoutes(ctx, r, cdc, kb)
}

120
x/stake/client/rest/tx.go Normal file
View File

@ -0,0 +1,120 @@
package rest
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"github.com/gorilla/mux"
"github.com/tendermint/go-crypto/keys"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/stake"
)
func registerTxRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
r.HandleFunc(
"/stake/delegations",
editDelegationsRequestHandlerFn(cdc, kb, ctx),
).Methods("POST")
}
type editDelegationsBody struct {
LocalAccountName string `json:"name"`
Password string `json:"password"`
ChainID string `json:"chain_id"`
Sequence int64 `json:"sequence"`
Delegate []stake.MsgDelegate `json:"delegate"`
Unbond []stake.MsgUnbond `json:"unbond"`
}
func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var m editDelegationsBody
body, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
err = json.Unmarshal(body, &m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
info, err := kb.Get(m.LocalAccountName)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
return
}
// build messages
messages := make([]sdk.Msg, len(m.Delegate)+len(m.Unbond))
i := 0
for _, msg := range m.Delegate {
if !bytes.Equal(info.Address(), msg.DelegatorAddr) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Must use own delegator address"))
return
}
messages[i] = msg
i++
}
for _, msg := range m.Unbond {
if !bytes.Equal(info.Address(), msg.DelegatorAddr) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Must use own delegator address"))
return
}
messages[i] = msg
i++
}
// sign messages
signedTxs := make([][]byte, len(messages[:]))
for i, msg := range messages {
// increment sequence for each message
ctx = ctx.WithSequence(m.Sequence)
m.Sequence++
txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
return
}
signedTxs[i] = txBytes
}
// send
// XXX the operation might not be atomic if a tx fails
// should we have a sdk.MultiMsg type to make sending atomic?
results := make([]*ctypes.ResultBroadcastTxCommit, len(signedTxs[:]))
for i, txBytes := range signedTxs {
res, err := ctx.BroadcastTx(txBytes)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
results[i] = res
}
output, err := json.MarshalIndent(results[:], "", " ")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}

View File

@ -22,8 +22,8 @@ func NewGenesisState(pool Pool, params Params, validators []Validator, bonds []D
// get raw genesis raw message for testing
func DefaultGenesisState() GenesisState {
return GenesisState{
Pool: initialPool(),
Params: defaultParams(),
Pool: InitialPool(),
Params: DefaultParams(),
}
}

View File

@ -586,7 +586,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) {
func TestGetTendermintUpdatesNotValidatorCliff(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
params := defaultParams()
params := DefaultParams()
params.MaxValidators = 2
keeper.setParams(ctx, params)
@ -721,7 +721,7 @@ func TestBond(t *testing.T) {
func TestParams(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
expParams := defaultParams()
expParams := DefaultParams()
//check that the empty keeper loads the default
resParams := keeper.GetParams(ctx)
@ -736,7 +736,7 @@ func TestParams(t *testing.T) {
func TestPool(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
expPool := initialPool()
expPool := InitialPool()
//check that the empty keeper loads the default
resPool := keeper.GetPool(ctx)

View File

@ -121,8 +121,8 @@ func (msg MsgEditCandidacy) ValidateBasic() sdk.Error {
// MsgDelegate - struct for bonding transactions
type MsgDelegate struct {
DelegatorAddr sdk.Address `json:"address"`
ValidatorAddr sdk.Address `json:"address"`
DelegatorAddr sdk.Address `json:"delegator_addr"`
ValidatorAddr sdk.Address `json:"validator_addr"`
Bond sdk.Coin `json:"bond"`
}
@ -170,8 +170,8 @@ func (msg MsgDelegate) ValidateBasic() sdk.Error {
// MsgUnbond - struct for unbonding transactions
type MsgUnbond struct {
DelegatorAddr sdk.Address `json:"address"`
ValidatorAddr sdk.Address `json:"address"`
DelegatorAddr sdk.Address `json:"delegator_addr"`
ValidatorAddr sdk.Address `json:"validator_addr"`
Shares string `json:"shares"`
}

View File

@ -23,7 +23,8 @@ func (p Params) equal(p2 Params) bool {
return bytes.Equal(bz1, bz2)
}
func defaultParams() Params {
// default params
func DefaultParams() Params {
return Params{
InflationRateChange: sdk.NewRat(13, 100),
InflationMax: sdk.NewRat(20, 100),

View File

@ -31,7 +31,7 @@ func (p Pool) equal(p2 Pool) bool {
}
// initial pool for testing
func initialPool() Pool {
func InitialPool() Pool {
return Pool{
LooseUnbondedTokens: 0,
BondedTokens: 0,

View File

@ -113,8 +113,8 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
)
ck := bank.NewKeeper(accountMapper)
keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace)
keeper.setPool(ctx, initialPool())
keeper.setNewParams(ctx, defaultParams())
keeper.setPool(ctx, InitialPool())
keeper.setNewParams(ctx, DefaultParams())
// fill all the addresses with some coins
for _, addr := range addrs {

View File

@ -61,7 +61,7 @@ func TestGetInflation(t *testing.T) {
func TestProcessProvisions(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
params := defaultParams()
params := DefaultParams()
params.MaxValidators = 2
keeper.setParams(ctx, params)
pool := keeper.GetPool(ctx)

View File

@ -169,7 +169,7 @@ func randomValidator(r *rand.Rand) Validator {
// generate a random staking state
func randomSetup(r *rand.Rand, numValidators int) (Pool, Validators) {
pool := initialPool()
pool := InitialPool()
validators := make([]Validator, numValidators)
for i := 0; i < numValidators; i++ {