Merge PR #1086: Bech32Cosmos output/input for the LCD
* refactored bech32ization * updated keys endpoints for bech32 * bech32 for sending and querying * trying to change output of validator addresses * fixed validator output * linted * fixed merge conflict * added bech32 to staking endpoints * removed some logging statements * added GetAccPubKeyBech32Cosmos * fixed cli tests * updated swagger * merged standard bech32 change * renamed bech32cosmos to bech32 * bech32ify json output for key add * readded changelog * fixed changelog merge issue * Update CHANGELOG.md
This commit is contained in:
parent
af15f89531
commit
5f409ce832
|
@ -1,5 +1,9 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
BREAKING CHANGES
|
||||||
|
|
||||||
|
* [lcd] Switch to bech32 for addresses on all human readable inputs and outputs
|
||||||
|
|
||||||
## 0.18.0
|
## 0.18.0
|
||||||
|
|
||||||
_2018-06-05_
|
_2018-06-05_
|
||||||
|
|
|
@ -102,12 +102,6 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addOutput lets us json format the data
|
|
||||||
type addOutput struct {
|
|
||||||
Key keys.Info `json:"key"`
|
|
||||||
Seed string `json:"seed"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func printCreate(info keys.Info, seed string) {
|
func printCreate(info keys.Info, seed string) {
|
||||||
output := viper.Get(cli.OutputFlag)
|
output := viper.Get(cli.OutputFlag)
|
||||||
switch output {
|
switch output {
|
||||||
|
@ -121,7 +115,10 @@ func printCreate(info keys.Info, seed string) {
|
||||||
fmt.Println(seed)
|
fmt.Println(seed)
|
||||||
}
|
}
|
||||||
case "json":
|
case "json":
|
||||||
out := addOutput{Key: info}
|
out, err := Bech32KeyOutput(info)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
if !viper.GetBool(flagNoBackup) {
|
if !viper.GetBool(flagNoBackup) {
|
||||||
out.Seed = seed
|
out.Seed = seed
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,9 +53,11 @@ func QueryKeysRequestHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte("[]"))
|
w.Write([]byte("[]"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
keysOutput := make([]KeyOutput, len(infos))
|
keysOutput, err := Bech32KeysOutput(infos)
|
||||||
for i, info := range infos {
|
if err != nil {
|
||||||
keysOutput[i] = KeyOutput{Name: info.Name, Address: sdk.Address(info.PubKey.Address().Bytes())}
|
w.WriteHeader(500)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
output, err := json.MarshalIndent(keysOutput, "", " ")
|
output, err := json.MarshalIndent(keysOutput, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
keys "github.com/tendermint/go-crypto/keys"
|
keys "github.com/tendermint/go-crypto/keys"
|
||||||
|
|
||||||
|
@ -51,7 +50,12 @@ func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
keyOutput := KeyOutput{Name: info.Name, Address: sdk.Address(info.PubKey.Address())}
|
keyOutput, err := Bech32KeyOutput(info)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
output, err := json.MarshalIndent(keyOutput, "", " ")
|
output, err := json.MarshalIndent(keyOutput, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
|
||||||
keys "github.com/tendermint/go-crypto/keys"
|
keys "github.com/tendermint/go-crypto/keys"
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
|
@ -47,29 +46,47 @@ func SetKeyBase(kb keys.Keybase) {
|
||||||
|
|
||||||
// used for outputting keys.Info over REST
|
// used for outputting keys.Info over REST
|
||||||
type KeyOutput struct {
|
type KeyOutput struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Address sdk.Address `json:"address"`
|
Address string `json:"address"`
|
||||||
PubKey crypto.PubKey `json:"pub_key"`
|
PubKey string `json:"pub_key"`
|
||||||
|
Seed string `json:"seed,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKeyOutput(info keys.Info) KeyOutput {
|
// create a list of KeyOutput in bech32 format
|
||||||
return KeyOutput{
|
func Bech32KeysOutput(infos []keys.Info) ([]KeyOutput, error) {
|
||||||
Name: info.Name,
|
|
||||||
Address: sdk.Address(info.PubKey.Address().Bytes()),
|
|
||||||
PubKey: info.PubKey,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKeyOutputs(infos []keys.Info) []KeyOutput {
|
|
||||||
kos := make([]KeyOutput, len(infos))
|
kos := make([]KeyOutput, len(infos))
|
||||||
for i, info := range infos {
|
for i, info := range infos {
|
||||||
kos[i] = NewKeyOutput(info)
|
ko, err := Bech32KeyOutput(info)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kos[i] = ko
|
||||||
}
|
}
|
||||||
return kos
|
return kos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a KeyOutput in bech32 format
|
||||||
|
func Bech32KeyOutput(info keys.Info) (KeyOutput, error) {
|
||||||
|
bechAccount, err := sdk.Bech32ifyAcc(sdk.Address(info.PubKey.Address().Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
return KeyOutput{}, err
|
||||||
|
}
|
||||||
|
bechPubKey, err := sdk.Bech32ifyAccPub(info.PubKey)
|
||||||
|
if err != nil {
|
||||||
|
return KeyOutput{}, err
|
||||||
|
}
|
||||||
|
return KeyOutput{
|
||||||
|
Name: info.Name,
|
||||||
|
Address: bechAccount,
|
||||||
|
PubKey: bechPubKey,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func printInfo(info keys.Info) {
|
func printInfo(info keys.Info) {
|
||||||
ko := NewKeyOutput(info)
|
ko, err := Bech32KeyOutput(info)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
switch viper.Get(cli.OutputFlag) {
|
switch viper.Get(cli.OutputFlag) {
|
||||||
case "text":
|
case "text":
|
||||||
fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
|
fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
|
||||||
|
@ -84,7 +101,10 @@ func printInfo(info keys.Info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func printInfos(infos []keys.Info) {
|
func printInfos(infos []keys.Info) {
|
||||||
kos := NewKeyOutputs(infos)
|
kos, err := Bech32KeysOutput(infos)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
switch viper.Get(cli.OutputFlag) {
|
switch viper.Get(cli.OutputFlag) {
|
||||||
case "text":
|
case "text":
|
||||||
fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
|
fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
|
||||||
|
@ -101,13 +121,5 @@ func printInfos(infos []keys.Info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func printKeyOutput(ko KeyOutput) {
|
func printKeyOutput(ko KeyOutput) {
|
||||||
bechAccount, err := sdk.Bech32ifyAcc(ko.Address)
|
fmt.Printf("%s\t%s\t%s\n", ko.Name, ko.Address, ko.PubKey)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
bechPubKey, err := sdk.Bech32ifyAccPub(ko.PubKey)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fmt.Printf("%s\t%s\t%s\n", ko.Name, bechAccount, bechPubKey)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ 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"
|
||||||
|
rpc "github.com/cosmos/cosmos-sdk/client/rpc"
|
||||||
gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
tests "github.com/cosmos/cosmos-sdk/tests"
|
tests "github.com/cosmos/cosmos-sdk/tests"
|
||||||
|
@ -40,14 +41,17 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/wire"
|
"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"
|
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
|
stakerest "github.com/cosmos/cosmos-sdk/x/stake/client/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
coinDenom = "steak"
|
coinDenom = "steak"
|
||||||
coinAmount = int64(10000000)
|
coinAmount = int64(10000000)
|
||||||
|
|
||||||
validatorAddr1 = ""
|
validatorAddr1Hx = ""
|
||||||
validatorAddr2 = ""
|
validatorAddr2Hx = ""
|
||||||
|
validatorAddr1 = ""
|
||||||
|
validatorAddr2 = ""
|
||||||
|
|
||||||
// XXX bad globals
|
// XXX bad globals
|
||||||
name = "test"
|
name = "test"
|
||||||
|
@ -99,13 +103,13 @@ func TestKeys(t *testing.T) {
|
||||||
err = cdc.UnmarshalJSON([]byte(body), &m)
|
err = cdc.UnmarshalJSON([]byte(body), &m)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
sendAddrAcc, _ := sdk.GetAccAddressHex(sendAddr)
|
|
||||||
addrAcc, _ := sdk.GetAccAddressHex(addr)
|
addrAcc, _ := sdk.GetAccAddressHex(addr)
|
||||||
|
addrBech32, _ := sdk.Bech32ifyAcc(addrAcc)
|
||||||
|
|
||||||
assert.Equal(t, m[0].Name, name, "Did not serve keys name correctly")
|
assert.Equal(t, name, m[0].Name, "Did not serve keys name correctly")
|
||||||
assert.Equal(t, m[0].Address, sendAddrAcc, "Did not serve keys Address correctly")
|
assert.Equal(t, sendAddr, m[0].Address, "Did not serve keys Address correctly")
|
||||||
assert.Equal(t, m[1].Name, newName, "Did not serve keys name correctly")
|
assert.Equal(t, newName, m[1].Name, "Did not serve keys name correctly")
|
||||||
assert.Equal(t, m[1].Address, addrAcc, "Did not serve keys Address correctly")
|
assert.Equal(t, addrBech32, m[1].Address, "Did not serve keys Address correctly")
|
||||||
|
|
||||||
// select key
|
// select key
|
||||||
keyEndpoint := fmt.Sprintf("/keys/%s", newName)
|
keyEndpoint := fmt.Sprintf("/keys/%s", newName)
|
||||||
|
@ -116,7 +120,7 @@ func TestKeys(t *testing.T) {
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
assert.Equal(t, newName, m2.Name, "Did not serve keys name correctly")
|
assert.Equal(t, newName, m2.Name, "Did not serve keys name correctly")
|
||||||
assert.Equal(t, addrAcc, m2.Address, "Did not serve keys Address correctly")
|
assert.Equal(t, addrBech32, m2.Address, "Did not serve keys Address correctly")
|
||||||
|
|
||||||
// update key
|
// update key
|
||||||
jsonStr = []byte(fmt.Sprintf(`{"old_password":"%s", "new_password":"12345678901"}`, newPassword))
|
jsonStr = []byte(fmt.Sprintf(`{"old_password":"%s", "new_password":"12345678901"}`, newPassword))
|
||||||
|
@ -198,7 +202,7 @@ func TestBlock(t *testing.T) {
|
||||||
|
|
||||||
func TestValidators(t *testing.T) {
|
func TestValidators(t *testing.T) {
|
||||||
|
|
||||||
var resultVals ctypes.ResultValidators
|
var resultVals rpc.ResultValidatorsOutput
|
||||||
|
|
||||||
res, body := request(t, port, "GET", "/validatorsets/latest", nil)
|
res, body := request(t, port, "GET", "/validatorsets/latest", nil)
|
||||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||||
|
@ -206,7 +210,10 @@ func TestValidators(t *testing.T) {
|
||||||
err := cdc.UnmarshalJSON([]byte(body), &resultVals)
|
err := cdc.UnmarshalJSON([]byte(body), &resultVals)
|
||||||
require.Nil(t, err, "Couldn't parse validatorset")
|
require.Nil(t, err, "Couldn't parse validatorset")
|
||||||
|
|
||||||
assert.NotEqual(t, ctypes.ResultValidators{}, resultVals)
|
assert.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals)
|
||||||
|
|
||||||
|
assert.Contains(t, resultVals.Validators[0].Address, "cosmosvaladdr")
|
||||||
|
assert.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalpub")
|
||||||
|
|
||||||
// --
|
// --
|
||||||
|
|
||||||
|
@ -216,7 +223,7 @@ func TestValidators(t *testing.T) {
|
||||||
err = cdc.UnmarshalJSON([]byte(body), &resultVals)
|
err = cdc.UnmarshalJSON([]byte(body), &resultVals)
|
||||||
require.Nil(t, err, "Couldn't parse validatorset")
|
require.Nil(t, err, "Couldn't parse validatorset")
|
||||||
|
|
||||||
assert.NotEqual(t, ctypes.ResultValidators{}, resultVals)
|
assert.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals)
|
||||||
|
|
||||||
// --
|
// --
|
||||||
|
|
||||||
|
@ -225,10 +232,11 @@ func TestValidators(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCoinSend(t *testing.T) {
|
func TestCoinSend(t *testing.T) {
|
||||||
|
bz, _ := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6")
|
||||||
|
someFakeAddr, _ := sdk.Bech32ifyAcc(bz)
|
||||||
|
|
||||||
// query empty
|
// query empty
|
||||||
//res, body := request(t, port, "GET", "/accounts/8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6", nil)
|
res, body := request(t, port, "GET", "/accounts/"+someFakeAddr, 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)
|
||||||
|
|
||||||
acc := getAccount(t, sendAddr)
|
acc := getAccount(t, sendAddr)
|
||||||
|
@ -323,15 +331,14 @@ func TestValidatorsQuery(t *testing.T) {
|
||||||
|
|
||||||
// make sure all the validators were found (order unknown because sorted by owner addr)
|
// make sure all the validators were found (order unknown because sorted by owner addr)
|
||||||
foundVal1, foundVal2 := false, false
|
foundVal1, foundVal2 := false, false
|
||||||
res1, res2 := hex.EncodeToString(validators[0].Owner), hex.EncodeToString(validators[1].Owner)
|
if validators[0].Owner == validatorAddr1 || validators[1].Owner == validatorAddr1 {
|
||||||
if res1 == validatorAddr1 || res2 == validatorAddr1 {
|
|
||||||
foundVal1 = true
|
foundVal1 = true
|
||||||
}
|
}
|
||||||
if res1 == validatorAddr2 || res2 == validatorAddr2 {
|
if validators[0].Owner == validatorAddr2 || validators[1].Owner == validatorAddr2 {
|
||||||
foundVal2 = true
|
foundVal2 = true
|
||||||
}
|
}
|
||||||
assert.True(t, foundVal1, "validatorAddr1 %v, res1 %v, res2 %v", validatorAddr1, res1, res2)
|
assert.True(t, foundVal1, "validatorAddr1 %v, owner1 %v, owner2 %v", validatorAddr1, validators[0].Owner, validators[1].Owner)
|
||||||
assert.True(t, foundVal2, "validatorAddr2 %v, res1 %v, res2 %v", validatorAddr2, res1, res2)
|
assert.True(t, foundVal2, "validatorAddr2 %v, owner1 %v, owner2 %v", validatorAddr2, validators[0].Owner, validators[1].Owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBond(t *testing.T) {
|
func TestBond(t *testing.T) {
|
||||||
|
@ -418,8 +425,10 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||||
|
|
||||||
pk1 := genDoc.Validators[0].PubKey
|
pk1 := genDoc.Validators[0].PubKey
|
||||||
pk2 := genDoc.Validators[1].PubKey
|
pk2 := genDoc.Validators[1].PubKey
|
||||||
validatorAddr1 = hex.EncodeToString(pk1.Address())
|
validatorAddr1Hx = hex.EncodeToString(pk1.Address())
|
||||||
validatorAddr2 = hex.EncodeToString(pk2.Address())
|
validatorAddr2Hx = hex.EncodeToString(pk2.Address())
|
||||||
|
validatorAddr1, _ = sdk.Bech32ifyVal(pk1.Address())
|
||||||
|
validatorAddr2, _ = sdk.Bech32ifyVal(pk2.Address())
|
||||||
|
|
||||||
// NOTE it's bad practice to reuse pk address for the owner address but doing in the
|
// NOTE it's bad practice to reuse pk address for the owner address but doing in the
|
||||||
// test for simplicity
|
// test for simplicity
|
||||||
|
@ -444,7 +453,8 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
sendAddr = info.PubKey.Address().String() // XXX global
|
sendAddrHex, _ := sdk.GetAccAddressHex(info.PubKey.Address().String())
|
||||||
|
sendAddr, _ = sdk.Bech32ifyAcc(sendAddrHex) // XXX global
|
||||||
accAuth := auth.NewBaseAccountWithAddress(info.PubKey.Address())
|
accAuth := auth.NewBaseAccountWithAddress(info.PubKey.Address())
|
||||||
accAuth.Coins = sdk.Coins{{"steak", 100}}
|
accAuth.Coins = sdk.Coins{{"steak", 100}}
|
||||||
acc := gapp.NewGenesisAccount(&accAuth)
|
acc := gapp.NewGenesisAccount(&accAuth)
|
||||||
|
@ -548,7 +558,7 @@ func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctype
|
||||||
kb := client.MockKeyBase()
|
kb := client.MockKeyBase()
|
||||||
receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519"))
|
receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519"))
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
receiveAddr = receiveInfo.PubKey.Address().String()
|
receiveAddr, _ = sdk.Bech32ifyAcc(receiveInfo.PubKey.Address())
|
||||||
|
|
||||||
acc := getAccount(t, sendAddr)
|
acc := getAccount(t, sendAddr)
|
||||||
sequence := acc.GetSequence()
|
sequence := acc.GetSequence()
|
||||||
|
@ -565,12 +575,11 @@ func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctype
|
||||||
}
|
}
|
||||||
|
|
||||||
func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) {
|
func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||||
|
|
||||||
// create receive address
|
// create receive address
|
||||||
kb := client.MockKeyBase()
|
kb := client.MockKeyBase()
|
||||||
receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519"))
|
receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519"))
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
receiveAddr := receiveInfo.PubKey.Address().String()
|
receiveAddr, _ := sdk.Bech32ifyAcc(receiveInfo.PubKey.Address())
|
||||||
|
|
||||||
// get the account to get the sequence
|
// get the account to get the sequence
|
||||||
acc := getAccount(t, sendAddr)
|
acc := getAccount(t, sendAddr)
|
||||||
|
@ -609,13 +618,13 @@ func doBond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxC
|
||||||
"sequence": %d,
|
"sequence": %d,
|
||||||
"delegate": [
|
"delegate": [
|
||||||
{
|
{
|
||||||
"delegator_addr": "%x",
|
"delegator_addr": "%s",
|
||||||
"validator_addr": "%s",
|
"validator_addr": "%s",
|
||||||
"bond": { "denom": "%s", "amount": 10 }
|
"bond": { "denom": "%s", "amount": 10 }
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"unbond": []
|
"unbond": []
|
||||||
}`, name, password, sequence, acc.GetAddress(), validatorAddr1, coinDenom))
|
}`, name, password, sequence, sendAddr, validatorAddr1, coinDenom))
|
||||||
res, body := request(t, port, "POST", "/stake/delegations", jsonStr)
|
res, body := request(t, port, "POST", "/stake/delegations", jsonStr)
|
||||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||||
|
|
||||||
|
@ -639,12 +648,12 @@ func doUnbond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastT
|
||||||
"bond": [],
|
"bond": [],
|
||||||
"unbond": [
|
"unbond": [
|
||||||
{
|
{
|
||||||
"delegator_addr": "%x",
|
"delegator_addr": "%s",
|
||||||
"validator_addr": "%s",
|
"validator_addr": "%s",
|
||||||
"shares": "1"
|
"shares": "1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}`, name, password, sequence, acc.GetAddress(), validatorAddr1))
|
}`, name, password, sequence, sendAddr, validatorAddr1))
|
||||||
res, body := request(t, port, "POST", "/stake/delegations", jsonStr)
|
res, body := request(t, port, "POST", "/stake/delegations", jsonStr)
|
||||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||||
|
|
||||||
|
@ -655,11 +664,11 @@ func doUnbond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastT
|
||||||
return results[0]
|
return results[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func getValidators(t *testing.T) []stake.Validator {
|
func getValidators(t *testing.T) []stakerest.StakeValidatorOutput {
|
||||||
// get the account to get the sequence
|
// get the account to get the sequence
|
||||||
res, body := request(t, port, "GET", "/stake/validators", nil)
|
res, body := request(t, port, "GET", "/stake/validators", nil)
|
||||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||||
var validators stake.Validators
|
var validators []stakerest.StakeValidatorOutput
|
||||||
err := cdc.UnmarshalJSON([]byte(body), &validators)
|
err := cdc.UnmarshalJSON([]byte(body), &validators)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
return validators
|
return validators
|
||||||
|
|
|
@ -10,6 +10,8 @@ import (
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO these next two functions feel kinda hacky based on their placement
|
// TODO these next two functions feel kinda hacky based on their placement
|
||||||
|
@ -28,6 +30,38 @@ func ValidatorCommand() *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validator output in bech32 format
|
||||||
|
type ValidatorOutput struct {
|
||||||
|
Address string `json:"address"` // in bech32
|
||||||
|
PubKey string `json:"pub_key"` // in bech32
|
||||||
|
Accum int64 `json:"accum"`
|
||||||
|
VotingPower int64 `json:"voting_power"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validators at a certain height output in bech32 format
|
||||||
|
type ResultValidatorsOutput struct {
|
||||||
|
BlockHeight int64 `json:"block_height"`
|
||||||
|
Validators []ValidatorOutput `json:"validators"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func bech32ValidatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) {
|
||||||
|
bechAddress, err := sdk.Bech32ifyVal(validator.Address)
|
||||||
|
if err != nil {
|
||||||
|
return ValidatorOutput{}, err
|
||||||
|
}
|
||||||
|
bechValPubkey, err := sdk.Bech32ifyValPub(validator.PubKey)
|
||||||
|
if err != nil {
|
||||||
|
return ValidatorOutput{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidatorOutput{
|
||||||
|
Address: bechAddress,
|
||||||
|
PubKey: bechValPubkey,
|
||||||
|
Accum: validator.Accum,
|
||||||
|
VotingPower: validator.VotingPower,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func getValidators(ctx context.CoreContext, height *int64) ([]byte, error) {
|
func getValidators(ctx context.CoreContext, height *int64) ([]byte, error) {
|
||||||
// get the node
|
// get the node
|
||||||
node, err := ctx.GetNode()
|
node, err := ctx.GetNode()
|
||||||
|
@ -35,12 +69,23 @@ func getValidators(ctx context.CoreContext, height *int64) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := node.Validators(height)
|
validatorsRes, err := node.Validators(height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
output, err := cdc.MarshalJSON(res)
|
outputValidatorsRes := ResultValidatorsOutput{
|
||||||
|
BlockHeight: validatorsRes.BlockHeight,
|
||||||
|
Validators: make([]ValidatorOutput, len(validatorsRes.Validators)),
|
||||||
|
}
|
||||||
|
for i := 0; i < len(validatorsRes.Validators); i++ {
|
||||||
|
outputValidatorsRes.Validators[i], err = bech32ValidatorOutput(validatorsRes.Validators[i])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := cdc.MarshalJSON(outputValidatorsRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -96,6 +141,7 @@ func ValidatorSetRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc {
|
||||||
w.Write([]byte(err.Error()))
|
w.Write([]byte(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(output)
|
w.Write(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,13 @@ func executeGetAddrPK(t *testing.T, cmdStr string) (sdk.Address, crypto.PubKey)
|
||||||
var ko keys.KeyOutput
|
var ko keys.KeyOutput
|
||||||
keys.UnmarshalJSON([]byte(out), &ko)
|
keys.UnmarshalJSON([]byte(out), &ko)
|
||||||
|
|
||||||
return ko.Address, ko.PubKey
|
address, err := sdk.GetAccAddressBech32(ko.Address)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
pk, err := sdk.GetAccPubKeyBech32(ko.PubKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return address, pk
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount {
|
func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount {
|
||||||
|
|
|
@ -102,7 +102,7 @@ paths:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: 12 word Seed
|
description: 16 word Seed
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
/keys/{name}:
|
/keys/{name}:
|
||||||
|
@ -204,7 +204,7 @@ paths:
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
name: address
|
name: address
|
||||||
description: Account address
|
description: Account address in bech32 format
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
get:
|
get:
|
||||||
|
@ -222,7 +222,7 @@ paths:
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
name: address
|
name: address
|
||||||
description: Account address
|
description: Account address in bech32 format
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
post:
|
post:
|
||||||
|
@ -255,18 +255,6 @@ paths:
|
||||||
description: Tx was send and will probably be added to the next block
|
description: Tx was send and will probably be added to the next block
|
||||||
400:
|
400:
|
||||||
description: The Tx was malformated
|
description: The Tx was malformated
|
||||||
/accounts/{address}/nonce:
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: address
|
|
||||||
description: Account address
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
get:
|
|
||||||
summary: Get the nonce for a certain account
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Plaintext nonce i.e. "4" defaults to "0"
|
|
||||||
/blocks/latest:
|
/blocks/latest:
|
||||||
get:
|
get:
|
||||||
summary: Get the latest block
|
summary: Get the latest block
|
||||||
|
@ -304,9 +292,14 @@ paths:
|
||||||
200:
|
200:
|
||||||
description: The validator set at the latest block height
|
description: The validator set at the latest block height
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: "#/definitions/Delegate"
|
block_height:
|
||||||
|
type: number
|
||||||
|
validators:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Validator"
|
||||||
/validatorsets/{height}:
|
/validatorsets/{height}:
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
|
@ -322,9 +315,14 @@ paths:
|
||||||
200:
|
200:
|
||||||
description: The validator set at a specific block height
|
description: The validator set at a specific block height
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
properties:
|
||||||
$ref: "#/definitions/Delegate"
|
block_height:
|
||||||
|
type: number
|
||||||
|
validators:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Validator"
|
||||||
404:
|
404:
|
||||||
description: Block at height not available
|
description: Block at height not available
|
||||||
# /txs:
|
# /txs:
|
||||||
|
@ -549,7 +547,20 @@ paths:
|
||||||
definitions:
|
definitions:
|
||||||
Address:
|
Address:
|
||||||
type: string
|
type: string
|
||||||
example: DF096FDE8D380FA5B2AD20DB2962C82DDEA1ED9B
|
description: bech32 encoded addres
|
||||||
|
example: cosmosaccaddr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||||
|
ValidatorAddress:
|
||||||
|
type: string
|
||||||
|
description: bech32 encoded addres
|
||||||
|
example: cosmosvaladdr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||||
|
PubKey:
|
||||||
|
type: string
|
||||||
|
description: bech32 encoded public key
|
||||||
|
example: cosmosaccpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||||
|
ValidatorPubKey:
|
||||||
|
type: string
|
||||||
|
description: bech32 encoded public key
|
||||||
|
example: cosmosvalpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||||
Coins:
|
Coins:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -652,16 +663,6 @@ definitions:
|
||||||
example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958
|
example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958
|
||||||
Pubkey:
|
Pubkey:
|
||||||
$ref: "#/definitions/PubKey"
|
$ref: "#/definitions/PubKey"
|
||||||
PubKey:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- ed25519
|
|
||||||
data:
|
|
||||||
type: string
|
|
||||||
example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958
|
|
||||||
Account:
|
Account:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -753,17 +754,19 @@ definitions:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
Delegate:
|
Validator:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
address:
|
||||||
|
$ref: '#/definitions/ValidatorAddress'
|
||||||
pub_key:
|
pub_key:
|
||||||
$ref: "#/definitions/PubKey"
|
$ref: "#/definitions/ValidatorPubKey"
|
||||||
power:
|
power:
|
||||||
type: number
|
type: number
|
||||||
example: 1000
|
example: 1000
|
||||||
name:
|
accum:
|
||||||
type: string
|
type: number
|
||||||
example: "159.89.3.34"
|
example: 1000
|
||||||
# Added by API Auto Mocking Plugin
|
# Added by API Auto Mocking Plugin
|
||||||
host: virtserver.swaggerhub.com
|
host: virtserver.swaggerhub.com
|
||||||
basePath: /faboweb1/Cosmos-LCD-2/1.0.0
|
basePath: /faboweb1/Cosmos-LCD-2/1.0.0
|
||||||
|
|
|
@ -32,7 +32,7 @@ func Bech32ifyAccPub(pub crypto.PubKey) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bech32ifyVal returns the bech32 encoded string for a validator address
|
// Bech32ifyVal returns the bech32 encoded string for a validator address
|
||||||
func bech32ifyVal(addr Address) (string, error) {
|
func Bech32ifyVal(addr Address) (string, error) {
|
||||||
return bech32.ConvertAndEncode(Bech32PrefixValAddr, addr.Bytes())
|
return bech32.ConvertAndEncode(Bech32PrefixValAddr, addr.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,21 @@ func GetAccAddressBech32(address string) (addr Address, err error) {
|
||||||
return Address(bz), nil
|
return Address(bz), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create a Pubkey from a string
|
||||||
|
func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) {
|
||||||
|
bz, err := getFromBech32(address, Bech32PrefixAccPub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pk, err = crypto.PubKeyFromBytes(bz)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pk, nil
|
||||||
|
}
|
||||||
|
|
||||||
// create an Address from a hex string
|
// create an Address from a hex string
|
||||||
func GetValAddressHex(address string) (addr Address, err error) {
|
func GetValAddressHex(address string) (addr Address, err error) {
|
||||||
if len(address) == 0 {
|
if len(address) == 0 {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package rest
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -26,17 +25,16 @@ func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, sto
|
||||||
func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder, ctx context.CoreContext) http.HandlerFunc {
|
func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder, ctx context.CoreContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
addr := vars["address"]
|
bech32addr := vars["address"]
|
||||||
|
|
||||||
bz, err := hex.DecodeString(addr)
|
addr, err := sdk.GetAccAddressBech32(bech32addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte(err.Error()))
|
w.Write([]byte(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
key := sdk.Address(bz)
|
|
||||||
|
|
||||||
res, err := ctx.Query(key, storeName)
|
res, err := ctx.Query(addr, storeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Write([]byte(fmt.Sprintf("Could't query account. Error: %s", err.Error())))
|
w.Write([]byte(fmt.Sprintf("Could't query account. Error: %s", err.Error())))
|
||||||
|
|
|
@ -41,7 +41,14 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// collect data
|
// collect data
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
address := vars["address"]
|
bech32addr := vars["address"]
|
||||||
|
|
||||||
|
address, err := sdk.GetAccAddressBech32(bech32addr)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var m sendBody
|
var m sendBody
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
@ -64,7 +71,7 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
to, err := sdk.GetAccAddressHex(address)
|
to, err := sdk.GetAccAddressHex(address.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte(err.Error()))
|
w.Write([]byte(err.Error()))
|
||||||
|
|
|
@ -35,7 +35,14 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.Core
|
||||||
// collect data
|
// collect data
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
destChainID := vars["destchain"]
|
destChainID := vars["destchain"]
|
||||||
address := vars["address"]
|
bech32addr := vars["address"]
|
||||||
|
|
||||||
|
address, err := sdk.GetAccAddressBech32(bech32addr)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var m transferBody
|
var m transferBody
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
@ -58,7 +65,7 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.Core
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bz, err := hex.DecodeString(address)
|
bz, err := hex.DecodeString(address.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte(err.Error()))
|
w.Write([]byte(err.Error()))
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package rest
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -30,24 +29,22 @@ func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire
|
||||||
|
|
||||||
// read parameters
|
// read parameters
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
delegator := vars["delegator"]
|
bech32delegator := vars["delegator"]
|
||||||
validator := vars["validator"]
|
bech32validator := vars["validator"]
|
||||||
|
|
||||||
bz, err := hex.DecodeString(delegator)
|
delegatorAddr, err := sdk.GetAccAddressBech32(bech32delegator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte(err.Error()))
|
w.Write([]byte(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delegatorAddr := sdk.Address(bz)
|
|
||||||
|
|
||||||
bz, err = hex.DecodeString(validator)
|
validatorAddr, err := sdk.GetValAddressBech32(bech32validator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte(err.Error()))
|
w.Write([]byte(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
validatorAddr := sdk.Address(bz)
|
|
||||||
|
|
||||||
key := stake.GetDelegationKey(delegatorAddr, validatorAddr, cdc)
|
key := stake.GetDelegationKey(delegatorAddr, validatorAddr, cdc)
|
||||||
|
|
||||||
|
@ -83,6 +80,62 @@ func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO inherit from Validator
|
||||||
|
type StakeValidatorOutput struct {
|
||||||
|
Owner string `json:"owner"` // in bech32
|
||||||
|
PubKey string `json:"pub_key"` // in bech32
|
||||||
|
Revoked bool `json:"revoked"` // has the validator been revoked from bonded status?
|
||||||
|
|
||||||
|
PoolShares stake.PoolShares `json:"pool_shares"` // total shares for tokens held in the pool
|
||||||
|
DelegatorShares sdk.Rat `json:"delegator_shares"` // total shares issued to a validator's delegators
|
||||||
|
|
||||||
|
Description stake.Description `json:"description"` // description terms for the validator
|
||||||
|
BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator
|
||||||
|
BondIntraTxCounter int16 `json:"bond_intra_tx_counter"` // block-local tx index of validator change
|
||||||
|
ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer
|
||||||
|
|
||||||
|
Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators
|
||||||
|
CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this validator can ever charge
|
||||||
|
CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the validator commission
|
||||||
|
CommissionChangeToday sdk.Rat `json:"commission_change_today"` // XXX commission rate change today, reset each day (UTC time)
|
||||||
|
|
||||||
|
// fee related
|
||||||
|
PrevBondedShares sdk.Rat `json:"prev_bonded_shares"` // total shares of a global hold pools
|
||||||
|
}
|
||||||
|
|
||||||
|
func bech32StakeValidatorOutput(validator stake.Validator) (StakeValidatorOutput, error) {
|
||||||
|
bechOwner, err := sdk.Bech32ifyVal(validator.Owner)
|
||||||
|
if err != nil {
|
||||||
|
return StakeValidatorOutput{}, err
|
||||||
|
}
|
||||||
|
bechValPubkey, err := sdk.Bech32ifyValPub(validator.PubKey)
|
||||||
|
if err != nil {
|
||||||
|
return StakeValidatorOutput{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return StakeValidatorOutput{
|
||||||
|
Owner: bechOwner,
|
||||||
|
PubKey: bechValPubkey,
|
||||||
|
Revoked: validator.Revoked,
|
||||||
|
|
||||||
|
PoolShares: validator.PoolShares,
|
||||||
|
DelegatorShares: validator.DelegatorShares,
|
||||||
|
|
||||||
|
Description: validator.Description,
|
||||||
|
BondHeight: validator.BondHeight,
|
||||||
|
BondIntraTxCounter: validator.BondIntraTxCounter,
|
||||||
|
ProposerRewardPool: validator.ProposerRewardPool,
|
||||||
|
|
||||||
|
Commission: validator.Commission,
|
||||||
|
CommissionMax: validator.CommissionMax,
|
||||||
|
CommissionChangeRate: validator.CommissionChangeRate,
|
||||||
|
CommissionChangeToday: validator.CommissionChangeToday,
|
||||||
|
|
||||||
|
PrevBondedShares: validator.PrevBondedShares,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO bech32
|
||||||
// http request handler to query list of validators
|
// http request handler to query list of validators
|
||||||
func validatorsHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Codec) http.HandlerFunc {
|
func validatorsHandlerFn(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) {
|
||||||
|
@ -100,16 +153,20 @@ func validatorsHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Co
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse out the validators
|
// parse out the validators
|
||||||
validators := make([]stake.Validator, len(kvs))
|
validators := make([]StakeValidatorOutput, len(kvs))
|
||||||
for i, kv := range kvs {
|
for i, kv := range kvs {
|
||||||
var validator stake.Validator
|
var validator stake.Validator
|
||||||
|
var bech32Validator StakeValidatorOutput
|
||||||
err = cdc.UnmarshalBinary(kv.Value, &validator)
|
err = cdc.UnmarshalBinary(kv.Value, &validator)
|
||||||
|
if err == nil {
|
||||||
|
bech32Validator, err = bech32StakeValidatorOutput(validator)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
validators[i] = validator
|
validators[i] = bech32Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
output, err := cdc.MarshalJSON(validators)
|
output, err := cdc.MarshalJSON(validators)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package rest
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -23,13 +24,24 @@ func registerTxRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, k
|
||||||
).Methods("POST")
|
).Methods("POST")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type msgDelegateInput struct {
|
||||||
|
DelegatorAddr string `json:"delegator_addr"` // in bech32
|
||||||
|
ValidatorAddr string `json:"validator_addr"` // in bech32
|
||||||
|
Bond sdk.Coin `json:"bond"`
|
||||||
|
}
|
||||||
|
type msgUnbondInput struct {
|
||||||
|
DelegatorAddr string `json:"delegator_addr"` // in bech32
|
||||||
|
ValidatorAddr string `json:"validator_addr"` // in bech32
|
||||||
|
Shares string `json:"shares"`
|
||||||
|
}
|
||||||
|
|
||||||
type editDelegationsBody struct {
|
type editDelegationsBody struct {
|
||||||
LocalAccountName string `json:"name"`
|
LocalAccountName string `json:"name"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
ChainID string `json:"chain_id"`
|
ChainID string `json:"chain_id"`
|
||||||
Sequence int64 `json:"sequence"`
|
Sequence int64 `json:"sequence"`
|
||||||
Delegate []stake.MsgDelegate `json:"delegate"`
|
Delegate []msgDelegateInput `json:"delegate"`
|
||||||
Unbond []stake.MsgUnbond `json:"unbond"`
|
Unbond []msgUnbondInput `json:"unbond"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
|
func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
|
||||||
|
@ -59,21 +71,53 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx conte
|
||||||
messages := make([]sdk.Msg, len(m.Delegate)+len(m.Unbond))
|
messages := make([]sdk.Msg, len(m.Delegate)+len(m.Unbond))
|
||||||
i := 0
|
i := 0
|
||||||
for _, msg := range m.Delegate {
|
for _, msg := range m.Delegate {
|
||||||
if !bytes.Equal(info.Address(), msg.DelegatorAddr) {
|
delegatorAddr, err := sdk.GetAccAddressBech32(msg.DelegatorAddr)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error())))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
validatorAddr, err := sdk.GetValAddressBech32(msg.ValidatorAddr)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !bytes.Equal(info.Address(), delegatorAddr) {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
w.Write([]byte("Must use own delegator address"))
|
w.Write([]byte("Must use own delegator address"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messages[i] = msg
|
messages[i] = stake.MsgDelegate{
|
||||||
|
DelegatorAddr: delegatorAddr,
|
||||||
|
ValidatorAddr: validatorAddr,
|
||||||
|
Bond: msg.Bond,
|
||||||
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
for _, msg := range m.Unbond {
|
for _, msg := range m.Unbond {
|
||||||
if !bytes.Equal(info.Address(), msg.DelegatorAddr) {
|
delegatorAddr, err := sdk.GetAccAddressBech32(msg.DelegatorAddr)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error())))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
validatorAddr, err := sdk.GetValAddressBech32(msg.ValidatorAddr)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !bytes.Equal(info.Address(), delegatorAddr) {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
w.Write([]byte("Must use own delegator address"))
|
w.Write([]byte("Must use own delegator address"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messages[i] = msg
|
messages[i] = stake.MsgUnbond{
|
||||||
|
DelegatorAddr: delegatorAddr,
|
||||||
|
ValidatorAddr: validatorAddr,
|
||||||
|
Shares: msg.Shares,
|
||||||
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue