Merge pull request #994 from cosmos/matt/stake-rest
Staking REST endpoints
This commit is contained in:
commit
7f18dbf7a6
|
@ -56,6 +56,7 @@ FEATURES
|
||||||
* [stake] Creation of a validator/delegation generics in `/types`
|
* [stake] Creation of a validator/delegation generics in `/types`
|
||||||
* [stake] Helper Description of the store in x/stake/store.md
|
* [stake] Helper Description of the store in x/stake/store.md
|
||||||
* [stake] removed use of caches in the stake keeper
|
* [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
|
* [Makefile] Added terraform/ansible playbooks to easily create remote testnets on Digital Ocean
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
|
|
@ -59,7 +59,7 @@ func (ctx CoreContext) QuerySubspace(cdc *wire.Codec, subspace []byte, storeName
|
||||||
|
|
||||||
// Query from Tendermint with the provided storename and path
|
// Query from Tendermint with the provided storename and path
|
||||||
func (ctx CoreContext) query(key cmn.HexBytes, storeName, endPath string) (res []byte, err error) {
|
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()
|
node, err := ctx.GetNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
|
|
@ -2,6 +2,7 @@ package lcd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -16,6 +17,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
cryptoKeys "github.com/tendermint/go-crypto/keys"
|
cryptoKeys "github.com/tendermint/go-crypto/keys"
|
||||||
tmcfg "github.com/tendermint/tendermint/config"
|
tmcfg "github.com/tendermint/tendermint/config"
|
||||||
nm "github.com/tendermint/tendermint/node"
|
nm "github.com/tendermint/tendermint/node"
|
||||||
|
@ -31,17 +33,21 @@ import (
|
||||||
|
|
||||||
client "github.com/cosmos/cosmos-sdk/client"
|
client "github.com/cosmos/cosmos-sdk/client"
|
||||||
keys "github.com/cosmos/cosmos-sdk/client/keys"
|
keys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||||
bapp "github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||||
btypes "github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
|
||||||
tests "github.com/cosmos/cosmos-sdk/tests"
|
tests "github.com/cosmos/cosmos-sdk/tests"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
coinDenom = "mycoin"
|
coinDenom = "steak"
|
||||||
coinAmount = int64(10000000)
|
coinAmount = int64(10000000)
|
||||||
|
|
||||||
|
validatorAddr1 = ""
|
||||||
|
validatorAddr2 = ""
|
||||||
|
|
||||||
// XXX bad globals
|
// XXX bad globals
|
||||||
name = "test"
|
name = "test"
|
||||||
password = "0123456789"
|
password = "0123456789"
|
||||||
|
@ -220,6 +226,7 @@ func TestValidators(t *testing.T) {
|
||||||
func TestCoinSend(t *testing.T) {
|
func TestCoinSend(t *testing.T) {
|
||||||
|
|
||||||
// query empty
|
// query empty
|
||||||
|
//res, body := request(t, port, "GET", "/accounts/8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6", nil)
|
||||||
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)
|
require.Equal(t, http.StatusNoContent, res.StatusCode, body)
|
||||||
|
|
||||||
|
@ -309,6 +316,63 @@ func TestTxs(t *testing.T) {
|
||||||
// assert.NotEqual(t, "[]", body)
|
// 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
|
// helpers
|
||||||
|
|
||||||
|
@ -324,26 +388,18 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
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 := GetConfig()
|
||||||
config.Consensus.TimeoutCommit = 1000
|
config.Consensus.TimeoutCommit = 1000
|
||||||
config.Consensus.SkipTimeoutCommit = false
|
config.Consensus.SkipTimeoutCommit = false
|
||||||
|
|
||||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||||
// logger = log.NewFilter(logger, log.AllowError())
|
logger = log.NewFilter(logger, log.AllowError())
|
||||||
privValidatorFile := config.PrivValidatorFile()
|
privValidatorFile := config.PrivValidatorFile()
|
||||||
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
|
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
app := bapp.NewBasecoinApp(logger, db)
|
app := gapp.NewGaiaApp(logger, db)
|
||||||
cdc = bapp.MakeCodec() // XXX
|
cdc = gapp.MakeCodec() // XXX
|
||||||
|
|
||||||
genesisFile := config.GenesisFile()
|
genesisFile := config.GenesisFile()
|
||||||
genDoc, err := tmtypes.GenesisDocFromFile(genesisFile)
|
genDoc, err := tmtypes.GenesisDocFromFile(genesisFile)
|
||||||
|
@ -351,21 +407,53 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
coins := sdk.Coins{{coinDenom, coinAmount}}
|
genDoc.Validators = append(genDoc.Validators,
|
||||||
appState := map[string]interface{}{
|
tmtypes.GenesisValidator{
|
||||||
"accounts": []*btypes.GenesisAccount{
|
PubKey: crypto.GenPrivKeyEd25519().PubKey(),
|
||||||
{
|
Power: 1,
|
||||||
Name: "tester",
|
Name: "val",
|
||||||
Address: pubKey.Address(),
|
|
||||||
Coins: coins,
|
|
||||||
},
|
},
|
||||||
},
|
)
|
||||||
}
|
|
||||||
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 {
|
if err != nil {
|
||||||
return nil, nil, err
|
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
|
// LCD listen address
|
||||||
port = fmt.Sprintf("%d", 17377) // XXX
|
port = fmt.Sprintf("%d", 17377) // XXX
|
||||||
|
@ -379,7 +467,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
lcd, err := startLCD(logger, listenAddr)
|
lcd, err := startLCD(logger, listenAddr, cdc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
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!
|
// 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)
|
handler := createHandler(cdc)
|
||||||
return tmrpc.StartHTTPServer(listenAddr, handler, logger)
|
return tmrpc.StartHTTPServer(listenAddr, handler, logger)
|
||||||
}
|
}
|
||||||
|
@ -494,3 +582,81 @@ func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroad
|
||||||
|
|
||||||
return resultTx
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||||
bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
||||||
ibc "github.com/cosmos/cosmos-sdk/x/ibc/client/rest"
|
ibc "github.com/cosmos/cosmos-sdk/x/ibc/client/rest"
|
||||||
|
stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -83,5 +84,6 @@ func createHandler(cdc *wire.Codec) http.Handler {
|
||||||
auth.RegisterRoutes(ctx, r, cdc, "acc")
|
auth.RegisterRoutes(ctx, r, cdc, "acc")
|
||||||
bank.RegisterRoutes(ctx, r, cdc, kb)
|
bank.RegisterRoutes(ctx, r, cdc, kb)
|
||||||
ibc.RegisterRoutes(ctx, r, cdc, kb)
|
ibc.RegisterRoutes(ctx, r, cdc, kb)
|
||||||
|
stake.RegisterRoutes(ctx, r, cdc, kb)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ func GaiaAppInit() server.AppInit {
|
||||||
FlagsAppGenState: fsAppGenState,
|
FlagsAppGenState: fsAppGenState,
|
||||||
FlagsAppGenTx: fsAppGenTx,
|
FlagsAppGenTx: fsAppGenTx,
|
||||||
AppGenTx: GaiaAppGenTx,
|
AppGenTx: GaiaAppGenTx,
|
||||||
AppGenState: GaiaAppGenState,
|
AppGenState: GaiaAppGenStateJSON,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,19 +85,31 @@ type GaiaGenTx struct {
|
||||||
PubKey crypto.PubKey `json:"pub_key"`
|
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) (
|
func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) (
|
||||||
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
|
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
|
||||||
|
|
||||||
var addr sdk.Address
|
|
||||||
var secret string
|
|
||||||
clientRoot := viper.GetString(flagClientHome)
|
clientRoot := viper.GetString(flagClientHome)
|
||||||
overwrite := viper.GetBool(flagOWK)
|
overwrite := viper.GetBool(flagOWK)
|
||||||
name := viper.GetString(flagName)
|
name := viper.GetString(flagName)
|
||||||
|
var addr sdk.Address
|
||||||
|
var secret string
|
||||||
addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite)
|
addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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
|
var bz []byte
|
||||||
gaiaGenTx := GaiaGenTx{
|
gaiaGenTx := GaiaGenTx{
|
||||||
|
@ -111,13 +123,6 @@ func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) (
|
||||||
}
|
}
|
||||||
appGenTx = json.RawMessage(bz)
|
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{
|
validator = tmtypes.GenesisValidator{
|
||||||
PubKey: pk,
|
PubKey: pk,
|
||||||
Power: freeFermionVal,
|
Power: freeFermionVal,
|
||||||
|
@ -127,7 +132,7 @@ func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) (
|
||||||
|
|
||||||
// Create the core parameters for genesis initialization for gaia
|
// Create the core parameters for genesis initialization for gaia
|
||||||
// note that the pubkey input is this machines pubkey
|
// 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 {
|
if len(appGenTxs) == 0 {
|
||||||
err = errors.New("must provide at least genesis transaction")
|
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
|
// create the final app state
|
||||||
genesisState := GenesisState{
|
genesisState = GenesisState{
|
||||||
Accounts: genaccs,
|
Accounts: genaccs,
|
||||||
StakeData: stakeData,
|
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)
|
appState, err = wire.MarshalJSONIndent(cdc, genesisState)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ type Tx interface {
|
||||||
|
|
||||||
//__________________________________________________________
|
//__________________________________________________________
|
||||||
|
|
||||||
// TxDeocder unmarshals transaction bytes
|
// TxDecoder unmarshals transaction bytes
|
||||||
type TxDecoder func(txBytes []byte) (Tx, Error)
|
type TxDecoder func(txBytes []byte) (Tx, Error)
|
||||||
|
|
||||||
//__________________________________________________________
|
//__________________________________________________________
|
||||||
|
|
|
@ -72,25 +72,26 @@ func GetCmdQueryValidators(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse out the candidates
|
// parse out the validators
|
||||||
var candidates []stake.Validator
|
var validators []stake.Validator
|
||||||
for _, KV := range resKVs {
|
for _, KV := range resKVs {
|
||||||
var validator stake.Validator
|
var validator stake.Validator
|
||||||
cdc.MustUnmarshalBinary(KV.Value, &validator)
|
cdc.MustUnmarshalBinary(KV.Value, &validator)
|
||||||
candidates = append(candidates, validator)
|
validators = append(validators, validator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch viper.Get(cli.OutputFlag) {
|
switch viper.Get(cli.OutputFlag) {
|
||||||
case "text":
|
case "text":
|
||||||
for _, candidate := range candidates {
|
for _, validator := range validators {
|
||||||
resp, err := candidate.HumanReadableString()
|
resp, err := validator.HumanReadableString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Println(resp)
|
fmt.Println(resp)
|
||||||
}
|
}
|
||||||
case "json":
|
case "json":
|
||||||
output, err := wire.MarshalJSONIndent(cdc, candidates)
|
output, err := wire.MarshalJSONIndent(cdc, validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -157,7 +158,7 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
return cmd
|
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 {
|
func GetCmdQueryDelegations(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "delegations [delegator-addr]",
|
Use: "delegations [delegator-addr]",
|
||||||
|
@ -176,7 +177,7 @@ func GetCmdQueryDelegations(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse out the candidates
|
// parse out the validators
|
||||||
var delegations []stake.Delegation
|
var delegations []stake.Delegation
|
||||||
for _, KV := range resKVs {
|
for _, KV := range resKVs {
|
||||||
var delegation stake.Delegation
|
var delegation stake.Delegation
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/tendermint/go-crypto/keys"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
@ -14,14 +13,21 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
func registerQueryRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) {
|
||||||
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
r.HandleFunc(
|
||||||
r.HandleFunc("/stake/{delegator}/bonding_status/{validator}", BondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
|
"/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
|
// http request handler to query delegator bonding status
|
||||||
func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
|
func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Codec) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// read parameters
|
// read parameters
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
delegator := vars["delegator"]
|
delegator := vars["delegator"]
|
||||||
|
@ -76,3 +82,43 @@ func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase,
|
||||||
w.Write(output)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,8 +22,8 @@ func NewGenesisState(pool Pool, params Params, validators []Validator, bonds []D
|
||||||
// get raw genesis raw message for testing
|
// get raw genesis raw message for testing
|
||||||
func DefaultGenesisState() GenesisState {
|
func DefaultGenesisState() GenesisState {
|
||||||
return GenesisState{
|
return GenesisState{
|
||||||
Pool: initialPool(),
|
Pool: InitialPool(),
|
||||||
Params: defaultParams(),
|
Params: DefaultParams(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,7 +586,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) {
|
||||||
|
|
||||||
func TestGetTendermintUpdatesNotValidatorCliff(t *testing.T) {
|
func TestGetTendermintUpdatesNotValidatorCliff(t *testing.T) {
|
||||||
ctx, _, keeper := createTestInput(t, false, 0)
|
ctx, _, keeper := createTestInput(t, false, 0)
|
||||||
params := defaultParams()
|
params := DefaultParams()
|
||||||
params.MaxValidators = 2
|
params.MaxValidators = 2
|
||||||
keeper.setParams(ctx, params)
|
keeper.setParams(ctx, params)
|
||||||
|
|
||||||
|
@ -721,7 +721,7 @@ func TestBond(t *testing.T) {
|
||||||
|
|
||||||
func TestParams(t *testing.T) {
|
func TestParams(t *testing.T) {
|
||||||
ctx, _, keeper := createTestInput(t, false, 0)
|
ctx, _, keeper := createTestInput(t, false, 0)
|
||||||
expParams := defaultParams()
|
expParams := DefaultParams()
|
||||||
|
|
||||||
//check that the empty keeper loads the default
|
//check that the empty keeper loads the default
|
||||||
resParams := keeper.GetParams(ctx)
|
resParams := keeper.GetParams(ctx)
|
||||||
|
@ -736,7 +736,7 @@ func TestParams(t *testing.T) {
|
||||||
|
|
||||||
func TestPool(t *testing.T) {
|
func TestPool(t *testing.T) {
|
||||||
ctx, _, keeper := createTestInput(t, false, 0)
|
ctx, _, keeper := createTestInput(t, false, 0)
|
||||||
expPool := initialPool()
|
expPool := InitialPool()
|
||||||
|
|
||||||
//check that the empty keeper loads the default
|
//check that the empty keeper loads the default
|
||||||
resPool := keeper.GetPool(ctx)
|
resPool := keeper.GetPool(ctx)
|
||||||
|
|
|
@ -121,8 +121,8 @@ func (msg MsgEditCandidacy) ValidateBasic() sdk.Error {
|
||||||
|
|
||||||
// MsgDelegate - struct for bonding transactions
|
// MsgDelegate - struct for bonding transactions
|
||||||
type MsgDelegate struct {
|
type MsgDelegate struct {
|
||||||
DelegatorAddr sdk.Address `json:"address"`
|
DelegatorAddr sdk.Address `json:"delegator_addr"`
|
||||||
ValidatorAddr sdk.Address `json:"address"`
|
ValidatorAddr sdk.Address `json:"validator_addr"`
|
||||||
Bond sdk.Coin `json:"bond"`
|
Bond sdk.Coin `json:"bond"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +170,8 @@ func (msg MsgDelegate) ValidateBasic() sdk.Error {
|
||||||
|
|
||||||
// MsgUnbond - struct for unbonding transactions
|
// MsgUnbond - struct for unbonding transactions
|
||||||
type MsgUnbond struct {
|
type MsgUnbond struct {
|
||||||
DelegatorAddr sdk.Address `json:"address"`
|
DelegatorAddr sdk.Address `json:"delegator_addr"`
|
||||||
ValidatorAddr sdk.Address `json:"address"`
|
ValidatorAddr sdk.Address `json:"validator_addr"`
|
||||||
Shares string `json:"shares"`
|
Shares string `json:"shares"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ func (p Params) equal(p2 Params) bool {
|
||||||
return bytes.Equal(bz1, bz2)
|
return bytes.Equal(bz1, bz2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultParams() Params {
|
// default params
|
||||||
|
func DefaultParams() Params {
|
||||||
return Params{
|
return Params{
|
||||||
InflationRateChange: sdk.NewRat(13, 100),
|
InflationRateChange: sdk.NewRat(13, 100),
|
||||||
InflationMax: sdk.NewRat(20, 100),
|
InflationMax: sdk.NewRat(20, 100),
|
||||||
|
|
|
@ -31,7 +31,7 @@ func (p Pool) equal(p2 Pool) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// initial pool for testing
|
// initial pool for testing
|
||||||
func initialPool() Pool {
|
func InitialPool() Pool {
|
||||||
return Pool{
|
return Pool{
|
||||||
LooseUnbondedTokens: 0,
|
LooseUnbondedTokens: 0,
|
||||||
BondedTokens: 0,
|
BondedTokens: 0,
|
||||||
|
|
|
@ -113,8 +113,8 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
|
||||||
)
|
)
|
||||||
ck := bank.NewKeeper(accountMapper)
|
ck := bank.NewKeeper(accountMapper)
|
||||||
keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace)
|
keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace)
|
||||||
keeper.setPool(ctx, initialPool())
|
keeper.setPool(ctx, InitialPool())
|
||||||
keeper.setNewParams(ctx, defaultParams())
|
keeper.setNewParams(ctx, DefaultParams())
|
||||||
|
|
||||||
// fill all the addresses with some coins
|
// fill all the addresses with some coins
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
|
|
|
@ -61,7 +61,7 @@ func TestGetInflation(t *testing.T) {
|
||||||
|
|
||||||
func TestProcessProvisions(t *testing.T) {
|
func TestProcessProvisions(t *testing.T) {
|
||||||
ctx, _, keeper := createTestInput(t, false, 0)
|
ctx, _, keeper := createTestInput(t, false, 0)
|
||||||
params := defaultParams()
|
params := DefaultParams()
|
||||||
params.MaxValidators = 2
|
params.MaxValidators = 2
|
||||||
keeper.setParams(ctx, params)
|
keeper.setParams(ctx, params)
|
||||||
pool := keeper.GetPool(ctx)
|
pool := keeper.GetPool(ctx)
|
||||||
|
|
|
@ -169,7 +169,7 @@ func randomValidator(r *rand.Rand) Validator {
|
||||||
|
|
||||||
// generate a random staking state
|
// generate a random staking state
|
||||||
func randomSetup(r *rand.Rand, numValidators int) (Pool, Validators) {
|
func randomSetup(r *rand.Rand, numValidators int) (Pool, Validators) {
|
||||||
pool := initialPool()
|
pool := InitialPool()
|
||||||
|
|
||||||
validators := make([]Validator, numValidators)
|
validators := make([]Validator, numValidators)
|
||||||
for i := 0; i < numValidators; i++ {
|
for i := 0; i < numValidators; i++ {
|
||||||
|
|
Loading…
Reference in New Issue