Almost from scratch reimplementation of bech32cosmos integration.

This commit is contained in:
Zaki Manian 2018-05-26 23:21:29 +02:00
parent 4ad3de4204
commit f33f49a840
23 changed files with 355 additions and 121 deletions

8
Gopkg.lock generated
View File

@ -13,6 +13,12 @@
packages = ["btcec"] packages = ["btcec"]
revision = "1432d294a5b055c297457c25434efbf13384cc46" revision = "1432d294a5b055c297457c25434efbf13384cc46"
[[projects]]
branch = "master"
name = "github.com/cosmos/bech32cosmos"
packages = ["go"]
revision = "efca97cd8c0852c44d96dfdcc70565c306eddff0"
[[projects]] [[projects]]
name = "github.com/davecgh/go-spew" name = "github.com/davecgh/go-spew"
packages = ["spew"] packages = ["spew"]
@ -457,6 +463,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "7540d2ecdb5d7d5084ab4e6132e929bbd501bd6add3006d8f08a6b2c127e0c7d" inputs-digest = "f0c6224dc5f30c1a7dea716d619665831ea0932b0eb9afc6ac897dbc459134fa"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -85,6 +85,11 @@
name = "google.golang.org/genproto" name = "google.golang.org/genproto"
revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200" revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200"
[[constraint]]
name = "github.com/cosmos/bech32cosmos"
branch = "master"
[prune] [prune]
go-tests = true go-tests = true
unused-packages = true unused-packages = true

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -55,7 +56,7 @@ func QueryKeysRequestHandler(w http.ResponseWriter, r *http.Request) {
} }
keysOutput := make([]KeyOutput, len(infos)) keysOutput := make([]KeyOutput, len(infos))
for i, info := range infos { for i, info := range infos {
keysOutput[i] = KeyOutput{Name: info.Name, Address: info.PubKey.Address().String()} keysOutput[i] = KeyOutput{Name: info.Name, Address: sdk.Address(info.PubKey.Address().Bytes())}
} }
output, err := json.MarshalIndent(keysOutput, "", " ") output, err := json.MarshalIndent(keysOutput, "", " ")
if err != nil { if err != nil {

View File

@ -4,6 +4,7 @@ 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"
@ -50,7 +51,7 @@ func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
keyOutput := KeyOutput{Name: info.Name, Address: info.PubKey.Address().String()} keyOutput := KeyOutput{Name: info.Name, Address: sdk.Address(info.PubKey.Address())}
output, err := json.MarshalIndent(keyOutput, "", " ") output, err := json.MarshalIndent(keyOutput, "", " ")
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(500)

View File

@ -1,19 +1,20 @@
package keys package keys
import ( import (
"encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"path/filepath" "path/filepath"
"strings"
"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"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
) )
// KeyDBName is the directory under root where we store the keys // KeyDBName is the directory under root where we store the keys
@ -47,16 +48,16 @@ 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 string `json:"address"` Address sdk.Address `json:"address"`
PubKey string `json:"pub_key"` PubKey crypto.PubKey `json:"pub_key"`
} }
func NewKeyOutput(info keys.Info) KeyOutput { func NewKeyOutput(info keys.Info) KeyOutput {
return KeyOutput{ return KeyOutput{
Name: info.Name, Name: info.Name,
Address: info.PubKey.Address().String(), Address: sdk.Address(info.PubKey.Address().Bytes()),
PubKey: strings.ToUpper(hex.EncodeToString(info.PubKey.Bytes())), PubKey: info.PubKey,
} }
} }
@ -73,7 +74,15 @@ func printInfo(info keys.Info) {
switch viper.Get(cli.OutputFlag) { switch viper.Get(cli.OutputFlag) {
case "text": case "text":
fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n") fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n")
fmt.Printf("%s\t%s\t%s\n", ko.Name, ko.Address, ko.PubKey) bechAccount, err := sdk.Bech32CosmosifyAcc(ko.Address)
if err != nil {
panic(err)
}
bechPubKey, err := sdk.Bech32CosmosifyAccPub(ko.PubKey)
if err != nil {
panic(err)
}
fmt.Printf("%s\t%s\t%s\n", ko.Name, bechAccount, bechPubKey)
case "json": case "json":
out, err := json.MarshalIndent(ko, "", "\t") out, err := json.MarshalIndent(ko, "", "\t")
if err != nil { if err != nil {

View File

@ -92,10 +92,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)
assert.Equal(t, m[0].Name, name, "Did not serve keys name correctly") assert.Equal(t, m[0].Name, name, "Did not serve keys name correctly")
assert.Equal(t, m[0].Address, sendAddr, "Did not serve keys Address correctly") assert.Equal(t, m[0].Address, sendAddrAcc, "Did not serve keys Address correctly")
assert.Equal(t, m[1].Name, newName, "Did not serve keys name correctly") assert.Equal(t, m[1].Name, newName, "Did not serve keys name correctly")
assert.Equal(t, m[1].Address, addr, "Did not serve keys Address correctly") assert.Equal(t, m[1].Address, addrAcc, "Did not serve keys Address correctly")
// select key // select key
keyEndpoint := fmt.Sprintf("/keys/%s", newName) keyEndpoint := fmt.Sprintf("/keys/%s", newName)
@ -106,7 +109,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, addr, m2.Address, "Did not serve keys Address correctly") assert.Equal(t, addrAcc, 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))

View File

@ -13,9 +13,11 @@ import (
"github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/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/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"
crypto "github.com/tendermint/go-crypto"
) )
func TestGaiaCLISend(t *testing.T) { func TestGaiaCLISend(t *testing.T) {
@ -38,24 +40,32 @@ func TestGaiaCLISend(t *testing.T) {
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json") barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json")
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) fooBech, err := sdk.Bech32CosmosifyAcc(fooAddr)
if err != nil {
t.Error(err)
}
barBech, err := sdk.Bech32CosmosifyAcc(barAddr)
if err != nil {
t.Error(err)
}
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak"))
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass) executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass)
time.Sleep(time.Second * 3) // waiting for some blocks to pass time.Sleep(time.Second * 3) // waiting for some blocks to pass
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barBech, flags))
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak"))
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak"))
// test autosequencing // test autosequencing
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass) executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass)
time.Sleep(time.Second * 3) // waiting for some blocks to pass time.Sleep(time.Second * 3) // waiting for some blocks to pass
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barBech, flags))
assert.Equal(t, int64(20), barAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(20), barAcc.GetCoins().AmountOf("steak"))
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
assert.Equal(t, int64(30), fooAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(30), fooAcc.GetCoins().AmountOf("steak"))
} }
@ -77,21 +87,32 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) {
defer cmd.Process.Kill() defer cmd.Process.Kill()
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json") barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json")
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass) fooBech, err := sdk.Bech32CosmosifyAcc(fooAddr)
if err != nil {
t.Error(err)
}
barBech, err := sdk.Bech32CosmosifyAcc(barAddr)
if err != nil {
t.Error(err)
}
valPrivkey := crypto.GenPrivKeyEd25519()
valAddr := sdk.Address((valPrivkey.PubKey().Address()))
bechVal, err := sdk.Bech32CosmosifyVal(valAddr)
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barBech), pass)
time.Sleep(time.Second * 3) // waiting for some blocks to pass time.Sleep(time.Second * 3) // waiting for some blocks to pass
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak"))
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barBech, flags))
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak"))
// declare candidacy // declare candidacy
declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) declStr := fmt.Sprintf("gaiacli create-validator %v", flags)
declStr += fmt.Sprintf(" --name=%v", "bar") declStr += fmt.Sprintf(" --name=%v", "bar")
declStr += fmt.Sprintf(" --address-candidate=%v", barAddr) declStr += fmt.Sprintf(" --validator-address=%v", bechVal)
declStr += fmt.Sprintf(" --pubkey=%v", barPubKey)
declStr += fmt.Sprintf(" --amount=%v", "3steak") declStr += fmt.Sprintf(" --amount=%v", "3steak")
declStr += fmt.Sprintf(" --moniker=%v", "bar-vally") declStr += fmt.Sprintf(" --moniker=%v", "bar-vally")
fmt.Printf("debug declStr: %v\n", declStr) fmt.Printf("debug declStr: %v\n", declStr)
@ -100,8 +121,8 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) {
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("steak")) assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("steak"))
candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr))
assert.Equal(t, candidate.Address.String(), barAddr) assert.Equal(t, candidate.Owner.String(), barAddr)
assert.Equal(t, int64(3), candidate.BondedShares.Evaluate()) assert.Equal(t, int64(3), candidate.PoolShares)
// TODO timeout issues if not connected to the internet // TODO timeout issues if not connected to the internet
// unbond a single share // unbond a single share
@ -125,6 +146,9 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) {
for _, write := range writes { for _, write := range writes {
_, err := wc.Write([]byte(write + "\n")) _, err := wc.Write([]byte(write + "\n"))
if err != nil {
fmt.Println(err)
}
require.NoError(t, err) require.NoError(t, err)
} }
fmt.Printf("debug waiting cmdStr: %v\n", cmdStr) fmt.Printf("debug waiting cmdStr: %v\n", cmdStr)
@ -159,7 +183,7 @@ func executeInit(t *testing.T, cmdStr string) (chainID string) {
return return
} }
func executeGetAddrPK(t *testing.T, cmdStr string) (addr, pubKey string) { func executeGetAddrPK(t *testing.T, cmdStr string) (sdk.Address, crypto.PubKey) {
out := tests.ExecuteT(t, cmdStr) out := tests.ExecuteT(t, cmdStr)
var ko keys.KeyOutput var ko keys.KeyOutput
keys.UnmarshalJSON([]byte(out), &ko) keys.UnmarshalJSON([]byte(out), &ko)
@ -180,9 +204,9 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount {
return acc return acc
} }
func executeGetCandidate(t *testing.T, cmdStr string) stake.Candidate { func executeGetCandidate(t *testing.T, cmdStr string) stake.Validator {
out := tests.ExecuteT(t, cmdStr) out := tests.ExecuteT(t, cmdStr)
var candidate stake.Candidate var candidate stake.Validator
cdc := app.MakeCodec() cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &candidate) err := cdc.UnmarshalJSON([]byte(out), &candidate)
require.NoError(t, err, "out %v, err %v", out, err) require.NoError(t, err, "out %v, err %v", out, err)

View File

@ -103,9 +103,9 @@ type ValidatorGovInfo struct {
* `Proposals: int64 => Proposal` maps `proposalID` to the `Proposal` * `Proposals: int64 => Proposal` maps `proposalID` to the `Proposal`
`proposalID` `proposalID`
* `Options: <proposalID | voterAddress | validatorAddress> => VoteType`: maps to the vote of the `voterAddress` for `proposalID` re its delegation to `validatorAddress`. * `Options: <proposalID | voterAddress | Address> => VoteType`: maps to the vote of the `voterAddress` for `proposalID` re its delegation to `Address`.
Returns 0x0 If `voterAddress` has not voted under this validator. Returns 0x0 If `voterAddress` has not voted under this validator.
* `ValidatorGovInfos: <proposalID | validatorAddress> => ValidatorGovInfo`: maps to the gov info for the `validatorAddress` and `proposalID`. * `ValidatorGovInfos: <proposalID | Address> => ValidatorGovInfo`: maps to the gov info for the `Address` and `proposalID`.
Returns `nil` if proposal has not entered voting period or if `address` was not the Returns `nil` if proposal has not entered voting period or if `address` was not the
address of a validator when proposal entered voting period. address of a validator when proposal entered voting period.

View File

@ -184,7 +184,7 @@ vote on the proposal.
type TxGovVote struct { type TxGovVote struct {
ProposalID int64 // proposalID of the proposal ProposalID int64 // proposalID of the proposal
Option string // option from OptionSet chosen by the voter Option string // option from OptionSet chosen by the voter
ValidatorAddress crypto.address // Address of the validator voter wants to tie its vote to Address crypto.address // Address of the validator voter wants to tie its vote to
} }
``` ```
@ -202,7 +202,7 @@ Votes need to be tied to a validator in order to compute validator's voting
power. If a delegator is bonded to multiple validators, it will have to send power. If a delegator is bonded to multiple validators, it will have to send
one transaction per validator (the UI should facilitate this so that multiple one transaction per validator (the UI should facilitate this so that multiple
transactions can be sent in one "vote flow"). If the sender is the validator transactions can be sent in one "vote flow"). If the sender is the validator
itself, then it will input its own address as `ValidatorAddress` itself, then it will input its own address as `Address`
Next is a pseudocode proposal of the way `TxGovVote` transactions are Next is a pseudocode proposal of the way `TxGovVote` transactions are
handled: handled:
@ -223,39 +223,39 @@ handled:
// There is no proposal for this proposalID // There is no proposal for this proposalID
throw throw
validator = load(CurrentValidators, txGovVote.ValidatorAddress) validator = load(CurrentValidators, txGovVote.Address)
if !proposal.InitProcedure.OptionSet.includes(txGovVote.Option) OR if !proposal.InitProcedure.OptionSet.includes(txGovVote.Option) OR
(validator == nil) then (validator == nil) then
// Throws if // Throws if
// Option is not in Option Set of procedure that was active when vote opened OR if // Option is not in Option Set of procedure that was active when vote opened OR if
// ValidatorAddress is not the address of a current validator // Address is not the address of a current validator
throw throw
option = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorAddress>) option = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.Address>)
if (option != nil) if (option != nil)
// sender has already voted with the Atoms bonded to ValidatorAddress // sender has already voted with the Atoms bonded to Address
throw throw
if (proposal.VotingStartBlock < 0) OR if (proposal.VotingStartBlock < 0) OR
(CurrentBlock > proposal.VotingStartBlock + proposal.InitProcedure.VotingPeriod) OR (CurrentBlock > proposal.VotingStartBlock + proposal.InitProcedure.VotingPeriod) OR
(proposal.VotingStartBlock < lastBondingBlock(sender, txGovVote.ValidatorAddress) OR (proposal.VotingStartBlock < lastBondingBlock(sender, txGovVote.Address) OR
(proposal.VotingStartBlock < lastUnbondingBlock(sender, txGovVote.Address) OR (proposal.VotingStartBlock < lastUnbondingBlock(sender, txGovVote.Address) OR
(proposal.Votes.YesVotes/proposal.InitTotalVotingPower >= 2/3) then (proposal.Votes.YesVotes/proposal.InitTotalVotingPower >= 2/3) then
// Throws if // Throws if
// Vote has not started OR if // Vote has not started OR if
// Vote had ended OR if // Vote had ended OR if
// sender bonded Atoms to ValidatorAddress after start of vote OR if // sender bonded Atoms to Address after start of vote OR if
// sender unbonded Atoms from ValidatorAddress after start of vote OR if // sender unbonded Atoms from Address after start of vote OR if
// special condition is met, i.e. proposal is accepted and closed // special condition is met, i.e. proposal is accepted and closed
throw throw
validatorGovInfo = load(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.ValidatorAddress>) validatorGovInfo = load(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.Address>)
if (validatorGovInfo == nil) if (validatorGovInfo == nil)
// validator became validator after proposal entered voting period // validator became validator after proposal entered voting period
@ -263,39 +263,39 @@ handled:
// sender can vote, check if sender == validator and store sender's option in Options // sender can vote, check if sender == validator and store sender's option in Options
store(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorAddress>, txGovVote.Option) store(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.Address>, txGovVote.Option)
if (sender != validator.address) if (sender != validator.address)
// Here, sender is not the Address of the validator whose Address is txGovVote.ValidatorAddress // Here, sender is not the Address of the validator whose Address is txGovVote.Address
if sender does not have bonded Atoms to txGovVote.ValidatorAddress then if sender does not have bonded Atoms to txGovVote.Address then
// check in Staking module // check in Staking module
throw throw
validatorOption = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorAddress>) validatorOption = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.Address>)
if (validatorOption == nil) if (validatorOption == nil)
// Validator has not voted already // Validator has not voted already
validatorGovInfo.Minus += sender.bondedAmounTo(txGovVote.ValidatorAddress) validatorGovInfo.Minus += sender.bondedAmounTo(txGovVote.Address)
store(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.ValidatorAddress>, validatorGovInfo) store(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.Address>, validatorGovInfo)
else else
// Validator has already voted // Validator has already voted
// Reduce votes of option chosen by validator by sender's bonded Amount // Reduce votes of option chosen by validator by sender's bonded Amount
proposal.Votes.validatorOption -= sender.bondedAmountTo(txGovVote.ValidatorAddress) proposal.Votes.validatorOption -= sender.bondedAmountTo(txGovVote.Address)
// increase votes of option chosen by sender by bonded Amount // increase votes of option chosen by sender by bonded Amount
senderOption = txGovVote.Option senderOption = txGovVote.Option
propoal.Votes.senderOption -= sender.bondedAmountTo(txGovVote.ValidatorAddress) propoal.Votes.senderOption -= sender.bondedAmountTo(txGovVote.Address)
store(Proposals, txGovVote.ProposalID, proposal) store(Proposals, txGovVote.ProposalID, proposal)
else else
// sender is the address of the validator whose main Address is txGovVote.ValidatorAddress // sender is the address of the validator whose main Address is txGovVote.Address
// i.e. sender == validator // i.e. sender == validator
proposal.Votes.validatorOption += (validatorGovInfo.InitVotingPower - validatorGovInfo.Minus) proposal.Votes.validatorOption += (validatorGovInfo.InitVotingPower - validatorGovInfo.Minus)

View File

@ -1,14 +1,13 @@
package server package server
import ( import (
"encoding/hex"
"fmt" "fmt"
"strings"
"github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/wire"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
sdk "github.com/cosmos/cosmos-sdk/types"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
pvm "github.com/tendermint/tendermint/types/priv_validator" pvm "github.com/tendermint/tendermint/types/priv_validator"
@ -41,21 +40,24 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command {
cfg := ctx.Config cfg := ctx.Config
privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()) privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorFile())
pubKey := privValidator.PubKey valAddr := sdk.Address(privValidator.PubKey.Address())
if viper.GetBool(flagJSON) { if viper.GetBool(flagJSON) {
cdc := wire.NewCodec() cdc := wire.NewCodec()
wire.RegisterCrypto(cdc) wire.RegisterCrypto(cdc)
pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) pubKeyJSONBytes, err := cdc.MarshalJSON(valAddr)
if err != nil { if err != nil {
return err return err
} }
fmt.Println(string(pubKeyJSONBytes)) fmt.Println(string(pubKeyJSONBytes))
return nil return nil
} }
pubKeyHex := strings.ToUpper(hex.EncodeToString(pubKey.Bytes())) addr, err := sdk.Bech32CosmosifyVal(valAddr)
fmt.Println(pubKeyHex) if err != nil {
return err
}
fmt.Println(addr)
return nil return nil
}, },
} }

View File

@ -3,15 +3,38 @@ package types
import ( import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt"
bech32cosmos "github.com/cosmos/bech32cosmos/go"
crypto "github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )
// Address in go-crypto style //Address is a go crypto-style Address
type Address = cmn.HexBytes type Address = cmn.HexBytes
// Bech32CosmosifyAcc takes Address and returns the Bech32Cosmos encoded string
func Bech32CosmosifyAcc(addr Address) (string, error) {
return bech32cosmos.ConvertAndEncode("cosmosaccaddr", addr.Bytes())
}
// Bech32CosmosifyAccPub takes AccountPubKey and returns the Bech32Cosmos encoded string
func Bech32CosmosifyAccPub(pub crypto.PubKey) (string, error) {
return bech32cosmos.ConvertAndEncode("cosmosaccpub", pub.Bytes())
}
// Bech32CosmosifyVal returns the Bech32Cosmos encoded string for a validator address
func Bech32CosmosifyVal(addr Address) (string, error) {
return bech32cosmos.ConvertAndEncode("cosmosvaladdr", addr.Bytes())
}
// Bech32CosmosifyValPub returns the Bech32Cosmos encoded string for a validator pubkey
func Bech32CosmosifyValPub(pub crypto.PubKey) (string, error) {
return bech32cosmos.ConvertAndEncode("cosmosvalpub", pub.Bytes())
}
// create an Address from a string // create an Address from a string
func GetAddress(address string) (addr Address, err error) { func GetAccAddressHex(address string) (addr Address, err error) {
if len(address) == 0 { if len(address) == 0 {
return addr, errors.New("must use provide address") return addr, errors.New("must use provide address")
} }
@ -21,3 +44,51 @@ func GetAddress(address string) (addr Address, err error) {
} }
return Address(bz), nil return Address(bz), nil
} }
// create an Address from a string
func GetAccAddressBech32Cosmos(address string) (addr Address, err error) {
if len(address) == 0 {
return addr, errors.New("must use provide address")
}
hrp, bz, err := bech32cosmos.DecodeAndConvert(address)
if hrp != "cosmosaccaddr" {
return addr, fmt.Errorf("Invalid Address Prefix. Expected cosmosaccaddr, Got %s", hrp)
}
if err != nil {
return nil, err
}
return Address(bz), nil
}
// create an Address from a string
func GetValAddressHex(address string) (addr Address, err error) {
if len(address) == 0 {
return addr, errors.New("must use provide address")
}
bz, err := hex.DecodeString(address)
if err != nil {
return nil, err
}
return Address(bz), nil
}
// create an Address from a string
func GetValAddressBech32Cosmos(address string) (addr Address, err error) {
if len(address) == 0 {
return addr, errors.New("must use provide address")
}
hrp, bz, err := bech32cosmos.DecodeAndConvert(address)
if hrp != "cosmosvaladdr" {
return addr, fmt.Errorf("Invalid Address Prefix. Expected cosmosvaladdr, Got %s", hrp)
}
if err != nil {
return nil, err
}
return Address(bz), nil
}

View File

@ -15,6 +15,20 @@ const (
Bonded BondStatus = 0x02 Bonded BondStatus = 0x02
) )
//BondStatusToString for pretty prints of Bond Status
func BondStatusToString(b BondStatus) string {
switch b {
case 0x00:
return "Ubbonded"
case 0x01:
return "Unbonding"
case 0x02:
return "Bonded"
default:
return ""
}
}
// validator for a delegated proof of stake system // validator for a delegated proof of stake system
type Validator interface { type Validator interface {
GetStatus() BondStatus // status of the validator GetStatus() BondStatus // status of the validator

View File

@ -18,7 +18,7 @@ func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.Address) {
return key, pub, addr return key, pub, addr
} }
func TestBaseAccountAddressPubKey(t *testing.T) { func TestBaseAddressPubKey(t *testing.T) {
_, pub1, addr1 := keyPubAddr() _, pub1, addr1 := keyPubAddr()
_, pub2, addr2 := keyPubAddr() _, pub2, addr2 := keyPubAddr()
acc := NewBaseAccountWithAddress(addr1) acc := NewBaseAccountWithAddress(addr1)

View File

@ -1,7 +1,6 @@
package cli package cli
import ( import (
"encoding/hex"
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -40,11 +39,11 @@ func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecode
// find the key to look up the account // find the key to look up the account
addr := args[0] addr := args[0]
bz, err := hex.DecodeString(addr)
key, err := sdk.GetAccAddressBech32Cosmos(addr)
if err != nil { if err != nil {
return err return err
} }
key := sdk.Address(bz)
// perform query // perform query
ctx := context.NewCoreContextFromViper() ctx := context.NewCoreContextFromViper()

View File

@ -1,7 +1,6 @@
package cli package cli
import ( import (
"encoding/hex"
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -34,12 +33,11 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command {
} }
toStr := viper.GetString(flagTo) toStr := viper.GetString(flagTo)
bz, err := hex.DecodeString(toStr)
to, err := sdk.GetAccAddressBech32Cosmos(toStr)
if err != nil { if err != nil {
return err return err
} }
to := sdk.Address(bz)
// parse coins // parse coins
amount := viper.GetString(flagAmount) amount := viper.GetString(flagAmount)
coins, err := sdk.ParseCoins(amount) coins, err := sdk.ParseCoins(amount)

View File

@ -1,7 +1,6 @@
package rest package rest
import ( import (
"encoding/hex"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -58,13 +57,12 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont
return return
} }
bz, err := hex.DecodeString(address) to, err := sdk.GetAccAddressHex(address)
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
} }
to := sdk.Address(bz)
// build message // build message
msg := client.BuildMsg(info.PubKey.Address(), to, m.Amount) msg := client.BuildMsg(info.PubKey.Address(), to, m.Amount)

View File

@ -1,13 +1,11 @@
package cli package cli
import ( import (
"encoding/hex"
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/tendermint/tmlibs/cli"
crypto "github.com/tendermint/go-crypto"
"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"
@ -23,7 +21,7 @@ func GetCmdQueryValidator(storeName string, cdc *wire.Codec) *cobra.Command {
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
addr, err := sdk.GetAddress(args[0]) addr, err := sdk.GetAccAddressBech32Cosmos(args[0])
if err != nil { if err != nil {
return err return err
} }
@ -33,13 +31,25 @@ func GetCmdQueryValidator(storeName string, cdc *wire.Codec) *cobra.Command {
if err != nil { if err != nil {
return err return err
} }
// parse out the validator
validator := new(stake.Validator) validator := new(stake.Validator)
cdc.MustUnmarshalBinary(res, validator) cdc.MustUnmarshalBinary(res, validator)
output, err := wire.MarshalJSONIndent(cdc, validator)
fmt.Println(string(output))
switch viper.Get(cli.OutputFlag) {
case "text":
human, err := validator.HumanReadableString()
if err != nil {
return err
}
fmt.Println(human)
case "json":
// parse out the validator
output, err := wire.MarshalJSONIndent(cdc, validator)
if err != nil {
return err
}
fmt.Println(string(output))
}
// TODO output with proofs / machine parseable etc. // TODO output with proofs / machine parseable etc.
return nil return nil
}, },
@ -70,11 +80,23 @@ func GetCmdQueryValidators(storeName string, cdc *wire.Codec) *cobra.Command {
candidates = append(candidates, validator) candidates = append(candidates, validator)
} }
output, err := wire.MarshalJSONIndent(cdc, candidates) switch viper.Get(cli.OutputFlag) {
if err != nil { case "text":
return err for _, candidate := range candidates {
resp, err := candidate.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
}
case "json":
output, err := wire.MarshalJSONIndent(cdc, candidates)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
} }
fmt.Println(string(output))
return nil return nil
// TODO output with proofs / machine parseable etc. // TODO output with proofs / machine parseable etc.
@ -90,18 +112,17 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command {
Short: "Query a delegations bond based on address and validator address", Short: "Query a delegations bond based on address and validator address",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
addr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) addr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressValidator))
if err != nil { if err != nil {
return err return err
} }
bz, err := hex.DecodeString(viper.GetString(FlagAddressDelegator)) delAddr, err := sdk.GetValAddressHex(viper.GetString(FlagAddressDelegator))
if err != nil { if err != nil {
return err return err
} }
delegation := crypto.Address(bz)
key := stake.GetDelegationKey(delegation, addr, cdc) key := stake.GetDelegationKey(delAddr, addr, cdc)
ctx := context.NewCoreContextFromViper() ctx := context.NewCoreContextFromViper()
res, err := ctx.Query(key, storeName) res, err := ctx.Query(key, storeName)
if err != nil { if err != nil {
@ -110,15 +131,24 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command {
// parse out the bond // parse out the bond
bond := new(stake.Delegation) bond := new(stake.Delegation)
cdc.MustUnmarshalBinary(res, bond)
output, err := wire.MarshalJSONIndent(cdc, bond)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
// TODO output with proofs / machine parseable etc. switch viper.Get(cli.OutputFlag) {
case "text":
resp, err := bond.HumanReadableString()
if err != nil {
return err
}
fmt.Println(resp)
case "json":
cdc.MustUnmarshalBinary(res, bond)
output, err := wire.MarshalJSONIndent(cdc, bond)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
}
return nil
}, },
} }
@ -135,7 +165,7 @@ func GetCmdQueryDelegations(storeName string, cdc *wire.Codec) *cobra.Command {
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
delegatorAddr, err := sdk.GetAddress(args[0]) delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(args[0])
if err != nil { if err != nil {
return err return err
} }

View File

@ -28,7 +28,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
if err != nil { if err != nil {
return err return err
} }
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator))
if err != nil { if err != nil {
return err return err
} }
@ -82,7 +82,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
Short: "edit and existing validator account", Short: "edit and existing validator account",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator))
if err != nil { if err != nil {
return err return err
} }
@ -123,8 +123,8 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
return err return err
} }
delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator)) delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressDelegator))
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator))
if err != nil { if err != nil {
return err return err
} }
@ -171,8 +171,8 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command {
} }
} }
delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator)) delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressDelegator))
validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator))
if err != nil { if err != nil {
return err return err
} }

View File

@ -2,6 +2,7 @@ package stake
import ( import (
"bytes" "bytes"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
) )
@ -31,3 +32,23 @@ var _ sdk.Delegation = Delegation{}
func (b Delegation) GetDelegator() sdk.Address { return b.DelegatorAddr } func (b Delegation) GetDelegator() sdk.Address { return b.DelegatorAddr }
func (b Delegation) GetValidator() sdk.Address { return b.ValidatorAddr } func (b Delegation) GetValidator() sdk.Address { return b.ValidatorAddr }
func (b Delegation) GetBondShares() sdk.Rat { return b.Shares } func (b Delegation) GetBondShares() sdk.Rat { return b.Shares }
//Human Friendly pretty printer
func (b Delegation) HumanReadableString() (string, error) {
bechAcc, err := sdk.Bech32CosmosifyAcc(b.DelegatorAddr)
if err != nil {
return "", err
}
bechVal, err := sdk.Bech32CosmosifyVal(b.ValidatorAddr)
if err != nil {
return "", err
}
resp := "Delegation \n"
resp += fmt.Sprintf("Delegator: %s\n", bechAcc)
resp += fmt.Sprintf("Validator: %s\n", bechVal)
resp += fmt.Sprintf("Shares: %s", b.Shares.String())
resp += fmt.Sprintf("Height: %d", b.Height)
return resp, nil
}

View File

@ -47,8 +47,10 @@ func NewMsgDeclareCandidacy(validatorAddr sdk.Address, pubkey crypto.PubKey,
} }
//nolint //nolint
func (msg MsgDeclareCandidacy) Type() string { return MsgType } //TODO update "stake/declarecandidacy" func (msg MsgDeclareCandidacy) Type() string { return MsgType } //TODO update "stake/declarecandidacy"
func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.ValidatorAddr} } func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address {
return []sdk.Address{msg.ValidatorAddr}
}
// get the bytes for the message signer to sign on // get the bytes for the message signer to sign on
func (msg MsgDeclareCandidacy) GetSignBytes() []byte { func (msg MsgDeclareCandidacy) GetSignBytes() []byte {
@ -89,8 +91,10 @@ func NewMsgEditCandidacy(validatorAddr sdk.Address, description Description) Msg
} }
//nolint //nolint
func (msg MsgEditCandidacy) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" func (msg MsgEditCandidacy) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy"
func (msg MsgEditCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.ValidatorAddr} } func (msg MsgEditCandidacy) GetSigners() []sdk.Address {
return []sdk.Address{msg.ValidatorAddr}
}
// get the bytes for the message signer to sign on // get the bytes for the message signer to sign on
func (msg MsgEditCandidacy) GetSignBytes() []byte { func (msg MsgEditCandidacy) GetSignBytes() []byte {
@ -131,8 +135,10 @@ func NewMsgDelegate(delegatorAddr, validatorAddr sdk.Address, bond sdk.Coin) Msg
} }
//nolint //nolint
func (msg MsgDelegate) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" func (msg MsgDelegate) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy"
func (msg MsgDelegate) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} } func (msg MsgDelegate) GetSigners() []sdk.Address {
return []sdk.Address{msg.DelegatorAddr}
}
// get the bytes for the message signer to sign on // get the bytes for the message signer to sign on
func (msg MsgDelegate) GetSignBytes() []byte { func (msg MsgDelegate) GetSignBytes() []byte {

View File

@ -1,6 +1,7 @@
package stake package stake
import ( import (
"bytes"
"encoding/hex" "encoding/hex"
"testing" "testing"
@ -21,16 +22,16 @@ import (
// dummy addresses used for testing // dummy addresses used for testing
var ( var (
addrs = []sdk.Address{ addrs = []sdk.Address{
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctqyxjnwh"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctpesxxn9"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6162"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6162", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctzhrnsa6"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6163"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6163", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctr2489qg"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6164"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6164", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctytvs4pd"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6165"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6165", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ct9k6yqul"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6166"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6166", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctxcf3kjq"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6167"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6167", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ct89l9r0j"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6168"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6168", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctg6jkls2"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6169"), testAddr("A58856F0FD53BF058B4909A21AEC019107BA6169", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctf8yz2dc"),
} }
// dummy pubkeys used for testing // dummy pubkeys used for testing
@ -137,10 +138,27 @@ func newPubKey(pk string) (res crypto.PubKey) {
} }
// for incode address generation // for incode address generation
func testAddr(addr string) sdk.Address { func testAddr(addr string, bech string) sdk.Address {
res, err := sdk.GetAddress(addr)
res, err := sdk.GetAccAddressHex(addr)
if err != nil { if err != nil {
panic(err) panic(err)
} }
bechexpected, err := sdk.Bech32CosmosifyAcc(res)
if err != nil {
panic(err)
}
if bech != bechexpected {
panic("Bech encoding doesn't match reference")
}
bechres, err := sdk.GetAccAddressBech32Cosmos(bech)
if err != nil {
panic(err)
}
if bytes.Compare(bechres, res) != 0 {
panic("Bech decode and hex decode don't match")
}
return res return res
} }

View File

@ -2,6 +2,7 @@ package stake
import ( import (
"bytes" "bytes"
"fmt"
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/wire"
@ -236,3 +237,30 @@ func (v Validator) GetOwner() sdk.Address { return v.Owner }
func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey } func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey }
func (v Validator) GetPower() sdk.Rat { return v.PoolShares.Bonded() } func (v Validator) GetPower() sdk.Rat { return v.PoolShares.Bonded() }
func (v Validator) GetBondHeight() int64 { return v.BondHeight } func (v Validator) GetBondHeight() int64 { return v.BondHeight }
//Human Friendly pretty printer
func (v Validator) HumanReadableString() (string, error) {
bechOwner, err := sdk.Bech32CosmosifyAcc(v.Owner)
if err != nil {
return "", err
}
bechVal, err := sdk.Bech32CosmosifyValPub(v.PubKey)
if err != nil {
return "", err
}
resp := "Validator \n"
resp += fmt.Sprintf("Owner: %s\n", bechOwner)
resp += fmt.Sprintf("Validator: %s\n", bechVal)
resp += fmt.Sprintf("Shares: Status %s, Amount: %s\n", sdk.BondStatusToString(v.PoolShares.Status), v.PoolShares.Amount.String())
resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.String())
resp += fmt.Sprintf("Description: %s\n", v.Description)
resp += fmt.Sprintf("Bond Height: %d\n", v.BondHeight)
resp += fmt.Sprintf("Proposer Reward Pool: %s\n", v.ProposerRewardPool.String())
resp += fmt.Sprintf("Commission: %s\n", v.Commission.String())
resp += fmt.Sprintf("Max Commission Rate: %s\n", v.CommissionMax.String())
resp += fmt.Sprintf("Comission Change Rate: %s\n", v.CommissionChangeRate.String())
resp += fmt.Sprintf("Commission Change Today: %s\n", v.CommissionChangeToday.String())
resp += fmt.Sprintf("Previously Bonded Stares: %s\n", v.PrevBondedShares.String())
return resp, nil
}

View File

@ -18,7 +18,7 @@ func NewViewSlashKeeper(k Keeper) ViewSlashKeeper {
// load a delegator bond // load a delegator bond
func (v ViewSlashKeeper) GetDelegation(ctx sdk.Context, func (v ViewSlashKeeper) GetDelegation(ctx sdk.Context,
delegatorAddr, validatorAddr sdk.Address) (bond Delegation, found bool) { delegatorAddr sdk.Address, validatorAddr sdk.Address) (bond Delegation, found bool) {
return v.keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) return v.keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
} }