From caf8c77dced9ea440e2f5145a1b13294868824ef Mon Sep 17 00:00:00 2001 From: sunnya97 Date: Sat, 26 May 2018 18:00:39 -0700 Subject: [PATCH 1/8] works --- store/cachekvstore.go | 11 ----------- store/dbstoreadapter.go | 8 -------- store/gaskvstore.go | 10 ---------- store/iavlstore.go | 12 +----------- store/iavlstore_test.go | 12 ++++++------ types/store.go | 21 +++++++++++---------- x/stake/keeper.go | 28 ++++++++++++++-------------- 7 files changed, 32 insertions(+), 70 deletions(-) diff --git a/store/cachekvstore.go b/store/cachekvstore.go index 772b593050..109bbfc75b 100644 --- a/store/cachekvstore.go +++ b/store/cachekvstore.go @@ -5,7 +5,6 @@ import ( "sort" "sync" - sdk "github.com/cosmos/cosmos-sdk/types" cmn "github.com/tendermint/tmlibs/common" ) @@ -134,16 +133,6 @@ func (ci *cacheKVStore) ReverseIterator(start, end []byte) Iterator { return ci.iterator(start, end, false) } -// Implements KVStore. -func (ci *cacheKVStore) SubspaceIterator(prefix []byte) Iterator { - return ci.iterator(prefix, sdk.PrefixEndBytes(prefix), true) -} - -// Implements KVStore. -func (ci *cacheKVStore) ReverseSubspaceIterator(prefix []byte) Iterator { - return ci.iterator(prefix, sdk.PrefixEndBytes(prefix), false) -} - func (ci *cacheKVStore) iterator(start, end []byte, ascending bool) Iterator { var parent, cache Iterator if ascending { diff --git a/store/dbstoreadapter.go b/store/dbstoreadapter.go index 7a299471f6..58c9e1b293 100644 --- a/store/dbstoreadapter.go +++ b/store/dbstoreadapter.go @@ -19,13 +19,5 @@ func (dsa dbStoreAdapter) CacheWrap() CacheWrap { return NewCacheKVStore(dsa) } -func (dsa dbStoreAdapter) SubspaceIterator(prefix []byte) Iterator { - return dsa.Iterator(prefix, sdk.PrefixEndBytes(prefix)) -} - -func (dsa dbStoreAdapter) ReverseSubspaceIterator(prefix []byte) Iterator { - return dsa.ReverseIterator(prefix, sdk.PrefixEndBytes(prefix)) -} - // dbm.DB implements KVStore so we can CacheKVStore it. var _ KVStore = dbStoreAdapter{dbm.DB(nil)} diff --git a/store/gaskvstore.go b/store/gaskvstore.go index 9f50f34441..db65921da7 100644 --- a/store/gaskvstore.go +++ b/store/gaskvstore.go @@ -75,16 +75,6 @@ func (gi *gasKVStore) ReverseIterator(start, end []byte) sdk.Iterator { return gi.iterator(start, end, false) } -// Implements KVStore. -func (gi *gasKVStore) SubspaceIterator(prefix []byte) sdk.Iterator { - return gi.iterator(prefix, sdk.PrefixEndBytes(prefix), true) -} - -// Implements KVStore. -func (gi *gasKVStore) ReverseSubspaceIterator(prefix []byte) sdk.Iterator { - return gi.iterator(prefix, sdk.PrefixEndBytes(prefix), false) -} - // Implements KVStore. func (gi *gasKVStore) CacheWrap() sdk.CacheWrap { panic("you cannot CacheWrap a GasKVStore") diff --git a/store/iavlstore.go b/store/iavlstore.go index 5399b3d5c4..2b7914c4eb 100644 --- a/store/iavlstore.go +++ b/store/iavlstore.go @@ -125,16 +125,6 @@ func (st *iavlStore) ReverseIterator(start, end []byte) Iterator { return newIAVLIterator(st.tree.Tree(), start, end, false) } -// Implements KVStore. -func (st *iavlStore) SubspaceIterator(prefix []byte) Iterator { - return st.Iterator(prefix, sdk.PrefixEndBytes(prefix)) -} - -// Implements KVStore. -func (st *iavlStore) ReverseSubspaceIterator(prefix []byte) Iterator { - return st.ReverseIterator(prefix, sdk.PrefixEndBytes(prefix)) -} - // Query implements ABCI interface, allows queries // // by default we will return from (latest height -1), @@ -180,7 +170,7 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) { subspace := req.Data res.Key = subspace var KVs []KVPair - iterator := st.SubspaceIterator(subspace) + iterator := sdk.KVStorePrefixIterator(st, subspace) for ; iterator.Valid(); iterator.Next() { KVs = append(KVs, KVPair{iterator.Key(), iterator.Value()}) } diff --git a/store/iavlstore_test.go b/store/iavlstore_test.go index 32bc1ebe0b..e324758c5c 100644 --- a/store/iavlstore_test.go +++ b/store/iavlstore_test.go @@ -157,7 +157,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { i := 0 - iter := iavlStore.SubspaceIterator([]byte("test")) + iter := sdk.KVStorePrefixIterator(iavlStore, []byte("test")) expected := []string{"test1", "test2", "test3"} for i = 0; iter.Valid(); iter.Next() { expectedKey := expected[i] @@ -168,7 +168,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { } assert.Equal(t, len(expected), i) - iter = iavlStore.SubspaceIterator([]byte{byte(55), byte(255), byte(255)}) + iter = sdk.KVStorePrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)}) expected2 := [][]byte{ []byte{byte(55), byte(255), byte(255), byte(0)}, []byte{byte(55), byte(255), byte(255), byte(1)}, @@ -183,7 +183,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { } assert.Equal(t, len(expected), i) - iter = iavlStore.SubspaceIterator([]byte{byte(255), byte(255)}) + iter = sdk.KVStorePrefixIterator(iavlStore, []byte{byte(255), byte(255)}) expected2 = [][]byte{ []byte{byte(255), byte(255), byte(0)}, []byte{byte(255), byte(255), byte(1)}, @@ -216,7 +216,7 @@ func TestIAVLReverseSubspaceIterator(t *testing.T) { i := 0 - iter := iavlStore.ReverseSubspaceIterator([]byte("test")) + iter := sdk.KVStoreReversePrefixIterator(iavlStore, []byte("test")) expected := []string{"test3", "test2", "test1"} for i = 0; iter.Valid(); iter.Next() { expectedKey := expected[i] @@ -227,7 +227,7 @@ func TestIAVLReverseSubspaceIterator(t *testing.T) { } assert.Equal(t, len(expected), i) - iter = iavlStore.ReverseSubspaceIterator([]byte{byte(55), byte(255), byte(255)}) + iter = sdk.KVStoreReversePrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)}) expected2 := [][]byte{ []byte{byte(55), byte(255), byte(255), byte(255)}, []byte{byte(55), byte(255), byte(255), byte(1)}, @@ -242,7 +242,7 @@ func TestIAVLReverseSubspaceIterator(t *testing.T) { } assert.Equal(t, len(expected), i) - iter = iavlStore.ReverseSubspaceIterator([]byte{byte(255), byte(255)}) + iter = sdk.KVStoreReversePrefixIterator(iavlStore, []byte{byte(255), byte(255)}) expected2 = [][]byte{ []byte{byte(255), byte(255), byte(255)}, []byte{byte(255), byte(255), byte(1)}, diff --git a/types/store.go b/types/store.go index abf02ec071..2bd34bebd8 100644 --- a/types/store.go +++ b/types/store.go @@ -84,7 +84,7 @@ type CommitMultiStore interface { LoadVersion(ver int64) error } -//---------------------------------------- +//---------subsp------------------------------- // KVStore // KVStore is a simple interface to get/set data @@ -113,25 +113,26 @@ type KVStore interface { // CONTRACT: No writes may happen within a domain while an iterator exists over it. ReverseIterator(start, end []byte) Iterator - // Iterator over all the keys with a certain prefix in ascending order. - // CONTRACT: No writes may happen within a domain while an iterator exists over it. - SubspaceIterator(prefix []byte) Iterator - - // Iterator over all the keys with a certain prefix in descending order. - // CONTRACT: No writes may happen within a domain while an iterator exists over it. - ReverseSubspaceIterator(prefix []byte) Iterator - // TODO Not yet implemented. // CreateSubKVStore(key *storeKey) (KVStore, error) // TODO Not yet implemented. // GetSubKVStore(key *storeKey) KVStore - } // Alias iterator to db's Iterator for convenience. type Iterator = dbm.Iterator +// Iterator over all the keys with a certain prefix in ascending order +func KVStorePrefixIterator(kvs KVStore, prefix []byte) Iterator { + return kvs.Iterator(prefix, PrefixEndBytes(prefix)) +} + +// Iterator over all the keys with a certain prefix in descending order. +func KVStoreReversePrefixIterator(kvs KVStore, prefix []byte) Iterator { + return kvs.ReverseIterator(prefix, PrefixEndBytes(prefix)) +} + // CacheKVStore cache-wraps a KVStore. After calling .Write() on // the CacheKVStore, all previously created CacheKVStores on the // object expire. diff --git a/x/stake/keeper.go b/x/stake/keeper.go index ada19df9f0..ce84b1e177 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -58,7 +58,7 @@ func (k Keeper) setValidator(ctx sdk.Context, validator Validator) { // Get the set of all validators with no limits, used during genesis dump func (k Keeper) getAllValidators(ctx sdk.Context) (validators Validators) { store := ctx.KVStore(k.storeKey) - iterator := store.SubspaceIterator(ValidatorsKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) i := 0 for ; ; i++ { @@ -78,7 +78,7 @@ func (k Keeper) getAllValidators(ctx sdk.Context) (validators Validators) { // Get the set of all validators, retrieve a maxRetrieve number of records func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve int16) (validators Validators) { store := ctx.KVStore(k.storeKey) - iterator := store.SubspaceIterator(ValidatorsKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) validators = make([]Validator, maxRetrieve) i := 0 @@ -106,7 +106,7 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []Validator) { maxValidators := k.GetParams(ctx).MaxValidators validators = make([]Validator, maxValidators) - iterator := store.SubspaceIterator(ValidatorsBondedKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedKey) i := 0 for ; iterator.Valid(); iterator.Next() { @@ -132,7 +132,7 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []Validator { store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators validators := make([]Validator, maxValidators) - iterator := store.ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest + iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerKey) // largest to smallest i := 0 for { if !iterator.Valid() || i > int(maxValidators-1) { @@ -160,7 +160,7 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []Validator { func (k Keeper) getTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { store := ctx.KVStore(k.storeKey) - iterator := store.SubspaceIterator(TendermintUpdatesKey) //smallest to largest + iterator := sdk.KVStorePrefixIterator(store, TendermintUpdatesKey) //smallest to largest for ; iterator.Valid(); iterator.Next() { valBytes := iterator.Value() var val abci.Validator @@ -176,7 +176,7 @@ func (k Keeper) clearTendermintUpdates(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) // delete subspace - iterator := store.SubspaceIterator(TendermintUpdatesKey) + iterator := sdk.KVStorePrefixIterator(store, TendermintUpdatesKey) for ; iterator.Valid(); iterator.Next() { store.Delete(iterator.Key()) } @@ -278,7 +278,7 @@ func (k Keeper) updateBondedValidators(ctx sdk.Context, store sdk.KVStore, // add the actual validator power sorted store maxValidators := k.GetParams(ctx).MaxValidators - iterator := store.ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest + iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerKey) // largest to smallest bondedValidatorsCount := 0 var validator Validator for { @@ -343,7 +343,7 @@ func (k Keeper) updateBondedValidators(ctx sdk.Context, store sdk.KVStore, func (k Keeper) updateBondedValidatorsFull(ctx sdk.Context, store sdk.KVStore) { // clear the current validators store, add to the ToKickOut temp store toKickOut := make(map[string]byte) - iterator := store.SubspaceIterator(ValidatorsBondedKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedKey) for ; iterator.Valid(); iterator.Next() { ownerAddr := iterator.Value() toKickOut[string(ownerAddr)] = 0 // set anything @@ -352,7 +352,7 @@ func (k Keeper) updateBondedValidatorsFull(ctx sdk.Context, store sdk.KVStore) { // add the actual validator power sorted store maxValidators := k.GetParams(ctx).MaxValidators - iterator = store.ReverseSubspaceIterator(ValidatorsByPowerKey) // largest to smallest + iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerKey) // largest to smallest bondedValidatorsCount := 0 var validator Validator for { @@ -502,7 +502,7 @@ func (k Keeper) GetDelegation(ctx sdk.Context, // load all delegations used during genesis dump func (k Keeper) getAllDelegations(ctx sdk.Context) (delegations []Delegation) { store := ctx.KVStore(k.storeKey) - iterator := store.SubspaceIterator(DelegationKey) + iterator := sdk.KVStorePrefixIterator(store, DelegationKey) i := 0 for ; ; i++ { @@ -523,7 +523,7 @@ func (k Keeper) getAllDelegations(ctx sdk.Context) (delegations []Delegation) { func (k Keeper) GetDelegations(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []Delegation) { store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetDelegationsKey(delegator, k.cdc) - iterator := store.SubspaceIterator(delegatorPrefixKey) //smallest to largest + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest bonds = make([]Delegation, maxRetrieve) i := 0 @@ -665,7 +665,7 @@ var _ sdk.ValidatorSet = Keeper{} // iterate through the active validator set and perform the provided function func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) { store := ctx.KVStore(k.storeKey) - iterator := store.SubspaceIterator(ValidatorsKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) i := int64(0) for ; iterator.Valid(); iterator.Next() { bz := iterator.Value() @@ -683,7 +683,7 @@ func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validato // iterate through the active validator set and perform the provided function func (k Keeper) IterateValidatorsBonded(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) { store := ctx.KVStore(k.storeKey) - iterator := store.SubspaceIterator(ValidatorsBondedKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedKey) i := int64(0) for ; iterator.Valid(); iterator.Next() { address := iterator.Value() @@ -735,7 +735,7 @@ func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.Address, addrVal sdk.Add func (k Keeper) IterateDelegators(ctx sdk.Context, delAddr sdk.Address, fn func(index int64, delegation sdk.Delegation) (stop bool)) { store := ctx.KVStore(k.storeKey) key := GetDelegationsKey(delAddr, k.cdc) - iterator := store.SubspaceIterator(key) + iterator := sdk.KVStorePrefixIterator(store, key) i := int64(0) for ; iterator.Valid(); iterator.Next() { bz := iterator.Value() From c057a71f5b50268b0b90fa96df85e5676ace44ee Mon Sep 17 00:00:00 2001 From: sunnya97 Date: Sat, 26 May 2018 18:04:47 -0700 Subject: [PATCH 2/8] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e429a1c8e..faacc6e341 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ BREAKING CHANGES * [x/auth] got rid of AccountMapper interface (in favor of the struct already in auth module) * [x/auth] removed the FeeHandler function from the AnteHandler, Replaced with FeeKeeper * [x/auth] Removed GetSignatures() from Tx interface (as different Tx styles might use something different than StdSignature) +* [store] Removed SubspaceIterator and ReverseSubspaceIterator from KVStore interface and replaced them with helper functions in /types BUG FIXES From f33f49a840cab82c11a14e8b345d038ea7a36837 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sat, 26 May 2018 23:21:29 +0200 Subject: [PATCH 3/8] Almost from scratch reimplementation of bech32cosmos integration. --- Gopkg.lock | 8 ++- Gopkg.toml | 5 ++ client/keys/list.go | 3 +- client/keys/show.go | 3 +- client/keys/utils.go | 25 ++++++--- client/lcd/lcd_test.go | 9 ++-- cmd/gaia/cli_test/cli_test.go | 58 ++++++++++++++------ docs/spec/governance/state.md | 4 +- docs/spec/governance/transactions.md | 38 ++++++------- server/tm_cmds.go | 14 ++--- types/account.go | 75 +++++++++++++++++++++++++- types/stake.go | 14 +++++ x/auth/account_test.go | 2 +- x/auth/client/cli/account.go | 5 +- x/bank/client/cli/sendtx.go | 6 +-- x/bank/client/rest/sendtx.go | 4 +- x/stake/client/cli/query.go | 80 +++++++++++++++++++--------- x/stake/client/cli/tx.go | 12 ++--- x/stake/delegation.go | 21 ++++++++ x/stake/msg.go | 18 ++++--- x/stake/test_common.go | 42 ++++++++++----- x/stake/validator.go | 28 ++++++++++ x/stake/view_slash_keeper.go | 2 +- 23 files changed, 355 insertions(+), 121 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 37a32820c2..9ca4de6855 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -13,6 +13,12 @@ packages = ["btcec"] revision = "1432d294a5b055c297457c25434efbf13384cc46" +[[projects]] + branch = "master" + name = "github.com/cosmos/bech32cosmos" + packages = ["go"] + revision = "efca97cd8c0852c44d96dfdcc70565c306eddff0" + [[projects]] name = "github.com/davecgh/go-spew" packages = ["spew"] @@ -457,6 +463,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "7540d2ecdb5d7d5084ab4e6132e929bbd501bd6add3006d8f08a6b2c127e0c7d" + inputs-digest = "f0c6224dc5f30c1a7dea716d619665831ea0932b0eb9afc6ac897dbc459134fa" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 5480bc03fc..a1adc79ac7 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -85,6 +85,11 @@ name = "google.golang.org/genproto" revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200" + [[constraint]] + name = "github.com/cosmos/bech32cosmos" + branch = "master" + + [prune] go-tests = true unused-packages = true diff --git a/client/keys/list.go b/client/keys/list.go index 26e06d9daf..9af511e5cd 100644 --- a/client/keys/list.go +++ b/client/keys/list.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" ) @@ -55,7 +56,7 @@ func QueryKeysRequestHandler(w http.ResponseWriter, r *http.Request) { } keysOutput := make([]KeyOutput, len(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, "", " ") if err != nil { diff --git a/client/keys/show.go b/client/keys/show.go index d0555764df..c7be9cc9db 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gorilla/mux" keys "github.com/tendermint/go-crypto/keys" @@ -50,7 +51,7 @@ func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) { 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, "", " ") if err != nil { w.WriteHeader(500) diff --git a/client/keys/utils.go b/client/keys/utils.go index 013aa1848b..eaf1e4c2fb 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -1,19 +1,20 @@ package keys import ( - "encoding/hex" "encoding/json" "fmt" "path/filepath" - "strings" "github.com/spf13/viper" + crypto "github.com/tendermint/go-crypto" keys "github.com/tendermint/go-crypto/keys" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/cosmos/cosmos-sdk/client" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // 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 type KeyOutput struct { - Name string `json:"name"` - Address string `json:"address"` - PubKey string `json:"pub_key"` + Name string `json:"name"` + Address sdk.Address `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` } func NewKeyOutput(info keys.Info) KeyOutput { return KeyOutput{ Name: info.Name, - Address: info.PubKey.Address().String(), - PubKey: strings.ToUpper(hex.EncodeToString(info.PubKey.Bytes())), + Address: sdk.Address(info.PubKey.Address().Bytes()), + PubKey: info.PubKey, } } @@ -73,7 +74,15 @@ func printInfo(info keys.Info) { switch viper.Get(cli.OutputFlag) { case "text": 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": out, err := json.MarshalIndent(ko, "", "\t") if err != nil { diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 29b4ba1124..840312ef6c 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -92,10 +92,13 @@ func TestKeys(t *testing.T) { err = cdc.UnmarshalJSON([]byte(body), &m) 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].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].Address, addr, "Did not serve keys Address correctly") + assert.Equal(t, m[1].Address, addrAcc, "Did not serve keys Address correctly") // select key keyEndpoint := fmt.Sprintf("/keys/%s", newName) @@ -106,7 +109,7 @@ func TestKeys(t *testing.T) { require.Nil(t, err) 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 jsonStr = []byte(fmt.Sprintf(`{"old_password":"%s", "new_password":"12345678901"}`, newPassword)) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 2d8b9d6a34..0f549d6d6f 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -13,9 +13,11 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/stake" + crypto "github.com/tendermint/go-crypto" ) func TestGaiaCLISend(t *testing.T) { @@ -38,24 +40,32 @@ func TestGaiaCLISend(t *testing.T) { fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --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")) 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 - 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")) - 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")) // test autosequencing 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 - 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")) - 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")) } @@ -77,21 +87,32 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { defer cmd.Process.Kill() 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 - 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")) - 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")) // 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(" --address-candidate=%v", barAddr) - declStr += fmt.Sprintf(" --pubkey=%v", barPubKey) + declStr += fmt.Sprintf(" --validator-address=%v", bechVal) declStr += fmt.Sprintf(" --amount=%v", "3steak") declStr += fmt.Sprintf(" --moniker=%v", "bar-vally") 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)) assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("steak")) candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) - assert.Equal(t, candidate.Address.String(), barAddr) - assert.Equal(t, int64(3), candidate.BondedShares.Evaluate()) + assert.Equal(t, candidate.Owner.String(), barAddr) + assert.Equal(t, int64(3), candidate.PoolShares) // TODO timeout issues if not connected to the internet // unbond a single share @@ -125,6 +146,9 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) { for _, write := range writes { _, err := wc.Write([]byte(write + "\n")) + if err != nil { + fmt.Println(err) + } require.NoError(t, err) } fmt.Printf("debug waiting cmdStr: %v\n", cmdStr) @@ -159,7 +183,7 @@ func executeInit(t *testing.T, cmdStr string) (chainID string) { 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) var ko keys.KeyOutput keys.UnmarshalJSON([]byte(out), &ko) @@ -180,9 +204,9 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { 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) - var candidate stake.Candidate + var candidate stake.Validator cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &candidate) require.NoError(t, err, "out %v, err %v", out, err) diff --git a/docs/spec/governance/state.md b/docs/spec/governance/state.md index e533ec6fe1..91cfa1f764 100644 --- a/docs/spec/governance/state.md +++ b/docs/spec/governance/state.md @@ -103,9 +103,9 @@ type ValidatorGovInfo struct { * `Proposals: int64 => Proposal` maps `proposalID` to the `Proposal` `proposalID` -* `Options: => VoteType`: maps to the vote of the `voterAddress` for `proposalID` re its delegation to `validatorAddress`. +* `Options: => 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. -* `ValidatorGovInfos: => ValidatorGovInfo`: maps to the gov info for the `validatorAddress` and `proposalID`. +* `ValidatorGovInfos: => 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 address of a validator when proposal entered voting period. diff --git a/docs/spec/governance/transactions.md b/docs/spec/governance/transactions.md index 5f5401de87..aacf046c13 100644 --- a/docs/spec/governance/transactions.md +++ b/docs/spec/governance/transactions.md @@ -184,7 +184,7 @@ vote on the proposal. type TxGovVote struct { ProposalID int64 // proposalID of the proposal 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 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 -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 handled: @@ -223,39 +223,39 @@ handled: // There is no proposal for this proposalID throw - validator = load(CurrentValidators, txGovVote.ValidatorAddress) + validator = load(CurrentValidators, txGovVote.Address) if !proposal.InitProcedure.OptionSet.includes(txGovVote.Option) OR (validator == nil) then // Throws 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 - option = load(Options, ::) + option = load(Options, ::) if (option != nil) - // sender has already voted with the Atoms bonded to ValidatorAddress + // sender has already voted with the Atoms bonded to Address throw if (proposal.VotingStartBlock < 0) 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.Votes.YesVotes/proposal.InitTotalVotingPower >= 2/3) then // Throws if // Vote has not started OR if // Vote had ended OR if - // sender bonded Atoms to ValidatorAddress after start of vote OR if - // sender unbonded Atoms from ValidatorAddress after start of vote OR if + // sender bonded Atoms to Address 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 throw - validatorGovInfo = load(ValidatorGovInfos, :) + validatorGovInfo = load(ValidatorGovInfos, :) if (validatorGovInfo == nil) // 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 - store(Options, ::, txGovVote.Option) + store(Options, ::, txGovVote.Option) 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 throw - validatorOption = load(Options, ::) + validatorOption = load(Options, ::) if (validatorOption == nil) // Validator has not voted already - validatorGovInfo.Minus += sender.bondedAmounTo(txGovVote.ValidatorAddress) - store(ValidatorGovInfos, :, validatorGovInfo) + validatorGovInfo.Minus += sender.bondedAmounTo(txGovVote.Address) + store(ValidatorGovInfos, :, validatorGovInfo) else // Validator has already voted // 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 senderOption = txGovVote.Option - propoal.Votes.senderOption -= sender.bondedAmountTo(txGovVote.ValidatorAddress) + propoal.Votes.senderOption -= sender.bondedAmountTo(txGovVote.Address) store(Proposals, txGovVote.ProposalID, proposal) 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 proposal.Votes.validatorOption += (validatorGovInfo.InitVotingPower - validatorGovInfo.Minus) diff --git a/server/tm_cmds.go b/server/tm_cmds.go index d581ca5f76..72598a80e5 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -1,14 +1,13 @@ package server import ( - "encoding/hex" "fmt" - "strings" "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" "github.com/spf13/viper" + sdk "github.com/cosmos/cosmos-sdk/types" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/p2p" pvm "github.com/tendermint/tendermint/types/priv_validator" @@ -41,21 +40,24 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { cfg := ctx.Config privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()) - pubKey := privValidator.PubKey + valAddr := sdk.Address(privValidator.PubKey.Address()) if viper.GetBool(flagJSON) { cdc := wire.NewCodec() wire.RegisterCrypto(cdc) - pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) + pubKeyJSONBytes, err := cdc.MarshalJSON(valAddr) if err != nil { return err } fmt.Println(string(pubKeyJSONBytes)) return nil } - pubKeyHex := strings.ToUpper(hex.EncodeToString(pubKey.Bytes())) - fmt.Println(pubKeyHex) + addr, err := sdk.Bech32CosmosifyVal(valAddr) + if err != nil { + return err + } + fmt.Println(addr) return nil }, } diff --git a/types/account.go b/types/account.go index be8b90a1cd..cf02d1d423 100644 --- a/types/account.go +++ b/types/account.go @@ -3,15 +3,38 @@ package types import ( "encoding/hex" "errors" + "fmt" + bech32cosmos "github.com/cosmos/bech32cosmos/go" + crypto "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" ) -// Address in go-crypto style +//Address is a go crypto-style Address 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 -func GetAddress(address string) (addr Address, err error) { +func GetAccAddressHex(address string) (addr Address, err error) { if len(address) == 0 { return addr, errors.New("must use provide address") } @@ -21,3 +44,51 @@ func GetAddress(address string) (addr Address, err error) { } 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 +} diff --git a/types/stake.go b/types/stake.go index df74a705b9..c640e98e77 100644 --- a/types/stake.go +++ b/types/stake.go @@ -15,6 +15,20 @@ const ( 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 type Validator interface { GetStatus() BondStatus // status of the validator diff --git a/x/auth/account_test.go b/x/auth/account_test.go index d3363e4fb0..a06545d3b8 100644 --- a/x/auth/account_test.go +++ b/x/auth/account_test.go @@ -18,7 +18,7 @@ func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.Address) { return key, pub, addr } -func TestBaseAccountAddressPubKey(t *testing.T) { +func TestBaseAddressPubKey(t *testing.T) { _, pub1, addr1 := keyPubAddr() _, pub2, addr2 := keyPubAddr() acc := NewBaseAccountWithAddress(addr1) diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index 08bd520fb1..4006baa149 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -1,7 +1,6 @@ package cli import ( - "encoding/hex" "fmt" "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 addr := args[0] - bz, err := hex.DecodeString(addr) + + key, err := sdk.GetAccAddressBech32Cosmos(addr) if err != nil { return err } - key := sdk.Address(bz) // perform query ctx := context.NewCoreContextFromViper() diff --git a/x/bank/client/cli/sendtx.go b/x/bank/client/cli/sendtx.go index 9109842887..5ed56a85b4 100644 --- a/x/bank/client/cli/sendtx.go +++ b/x/bank/client/cli/sendtx.go @@ -1,7 +1,6 @@ package cli import ( - "encoding/hex" "fmt" "github.com/spf13/cobra" @@ -34,12 +33,11 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command { } toStr := viper.GetString(flagTo) - bz, err := hex.DecodeString(toStr) + + to, err := sdk.GetAccAddressBech32Cosmos(toStr) if err != nil { return err } - to := sdk.Address(bz) - // parse coins amount := viper.GetString(flagAmount) coins, err := sdk.ParseCoins(amount) diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index 6ce472b6fd..916aa08fe1 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -1,7 +1,6 @@ package rest import ( - "encoding/hex" "encoding/json" "io/ioutil" "net/http" @@ -58,13 +57,12 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont return } - bz, err := hex.DecodeString(address) + to, err := sdk.GetAccAddressHex(address) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - to := sdk.Address(bz) // build message msg := client.BuildMsg(info.PubKey.Address(), to, m.Amount) diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index 079dd003d8..491ad1a7b8 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -1,13 +1,11 @@ package cli import ( - "encoding/hex" "fmt" "github.com/spf13/cobra" "github.com/spf13/viper" - - crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/tmlibs/cli" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" @@ -23,7 +21,7 @@ func GetCmdQueryValidator(storeName string, cdc *wire.Codec) *cobra.Command { Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - addr, err := sdk.GetAddress(args[0]) + addr, err := sdk.GetAccAddressBech32Cosmos(args[0]) if err != nil { return err } @@ -33,13 +31,25 @@ func GetCmdQueryValidator(storeName string, cdc *wire.Codec) *cobra.Command { if err != nil { return err } - - // parse out the validator validator := new(stake.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. return nil }, @@ -70,11 +80,23 @@ func GetCmdQueryValidators(storeName string, cdc *wire.Codec) *cobra.Command { candidates = append(candidates, validator) } - output, err := wire.MarshalJSONIndent(cdc, candidates) - if err != nil { - return err + switch viper.Get(cli.OutputFlag) { + case "text": + 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 // 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", 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 { return err } - bz, err := hex.DecodeString(viper.GetString(FlagAddressDelegator)) + delAddr, err := sdk.GetValAddressHex(viper.GetString(FlagAddressDelegator)) if err != nil { return err } - delegation := crypto.Address(bz) - key := stake.GetDelegationKey(delegation, addr, cdc) + key := stake.GetDelegationKey(delAddr, addr, cdc) ctx := context.NewCoreContextFromViper() res, err := ctx.Query(key, storeName) if err != nil { @@ -110,15 +131,24 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command { // parse out the bond 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), RunE: func(cmd *cobra.Command, args []string) error { - delegatorAddr, err := sdk.GetAddress(args[0]) + delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(args[0]) if err != nil { return err } diff --git a/x/stake/client/cli/tx.go b/x/stake/client/cli/tx.go index dd9c97a72c..acb3d026f4 100644 --- a/x/stake/client/cli/tx.go +++ b/x/stake/client/cli/tx.go @@ -28,7 +28,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { if err != nil { return err } - validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) + validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) if err != nil { return err } @@ -82,7 +82,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command { Short: "edit and existing validator account", 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 { return err } @@ -123,8 +123,8 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { return err } - delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator)) - validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) + delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressDelegator)) + validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) if err != nil { return err } @@ -171,8 +171,8 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { } } - delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator)) - validatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressValidator)) + delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressDelegator)) + validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) if err != nil { return err } diff --git a/x/stake/delegation.go b/x/stake/delegation.go index 89afe8e907..37c68d9525 100644 --- a/x/stake/delegation.go +++ b/x/stake/delegation.go @@ -2,6 +2,7 @@ package stake import ( "bytes" + "fmt" 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) GetValidator() sdk.Address { return b.ValidatorAddr } 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 + +} diff --git a/x/stake/msg.go b/x/stake/msg.go index 0adff84d9b..41220acc62 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -47,8 +47,10 @@ func NewMsgDeclareCandidacy(validatorAddr sdk.Address, pubkey crypto.PubKey, } //nolint -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) Type() string { return MsgType } //TODO update "stake/declarecandidacy" +func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { + return []sdk.Address{msg.ValidatorAddr} +} // get the bytes for the message signer to sign on func (msg MsgDeclareCandidacy) GetSignBytes() []byte { @@ -89,8 +91,10 @@ func NewMsgEditCandidacy(validatorAddr sdk.Address, description Description) Msg } //nolint -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) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" +func (msg MsgEditCandidacy) GetSigners() []sdk.Address { + return []sdk.Address{msg.ValidatorAddr} +} // get the bytes for the message signer to sign on func (msg MsgEditCandidacy) GetSignBytes() []byte { @@ -131,8 +135,10 @@ func NewMsgDelegate(delegatorAddr, validatorAddr sdk.Address, bond sdk.Coin) Msg } //nolint -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) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" +func (msg MsgDelegate) GetSigners() []sdk.Address { + return []sdk.Address{msg.DelegatorAddr} +} // get the bytes for the message signer to sign on func (msg MsgDelegate) GetSignBytes() []byte { diff --git a/x/stake/test_common.go b/x/stake/test_common.go index b7a5152c09..bf3e665513 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -1,6 +1,7 @@ package stake import ( + "bytes" "encoding/hex" "testing" @@ -21,16 +22,16 @@ import ( // dummy addresses used for testing var ( addrs = []sdk.Address{ - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6162"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6163"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6164"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6165"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6166"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6167"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6168"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6169"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctqyxjnwh"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctpesxxn9"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6162", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctzhrnsa6"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6163", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctr2489qg"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6164", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctytvs4pd"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6165", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ct9k6yqul"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6166", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctxcf3kjq"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6167", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ct89l9r0j"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6168", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctg6jkls2"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6169", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctf8yz2dc"), } // dummy pubkeys used for testing @@ -137,10 +138,27 @@ func newPubKey(pk string) (res crypto.PubKey) { } // for incode address generation -func testAddr(addr string) sdk.Address { - res, err := sdk.GetAddress(addr) +func testAddr(addr string, bech string) sdk.Address { + + res, err := sdk.GetAccAddressHex(addr) if err != nil { 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 } diff --git a/x/stake/validator.go b/x/stake/validator.go index 88f061f315..cf4ee85fda 100644 --- a/x/stake/validator.go +++ b/x/stake/validator.go @@ -2,6 +2,7 @@ package stake import ( "bytes" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" "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) GetPower() sdk.Rat { return v.PoolShares.Bonded() } 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 +} diff --git a/x/stake/view_slash_keeper.go b/x/stake/view_slash_keeper.go index 38ba227bde..cb7d16ce94 100644 --- a/x/stake/view_slash_keeper.go +++ b/x/stake/view_slash_keeper.go @@ -18,7 +18,7 @@ func NewViewSlashKeeper(k Keeper) ViewSlashKeeper { // load a delegator bond 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) } From a163a3558f85908ce8435c5d01d607840873713d Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 27 May 2018 14:21:15 +0200 Subject: [PATCH 4/8] Use public keys consistently for validators and all addresses are for accounts --- server/tm_cmds.go | 6 +++--- types/account.go | 27 +++++++++++++++++++++++++-- x/stake/client/cli/tx.go | 18 +++++------------- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 72598a80e5..fcec57f090 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -40,20 +40,20 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { cfg := ctx.Config privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()) - valAddr := sdk.Address(privValidator.PubKey.Address()) + valPubKey := privValidator.PubKey if viper.GetBool(flagJSON) { cdc := wire.NewCodec() wire.RegisterCrypto(cdc) - pubKeyJSONBytes, err := cdc.MarshalJSON(valAddr) + pubKeyJSONBytes, err := cdc.MarshalJSON(valPubKey) if err != nil { return err } fmt.Println(string(pubKeyJSONBytes)) return nil } - addr, err := sdk.Bech32CosmosifyVal(valAddr) + addr, err := sdk.Bech32CosmosifyValPub(valPubKey) if err != nil { return err } diff --git a/types/account.go b/types/account.go index cf02d1d423..615fd30c17 100644 --- a/types/account.go +++ b/types/account.go @@ -63,7 +63,7 @@ func GetAccAddressBech32Cosmos(address string) (addr Address, err error) { return Address(bz), nil } -// create an Address from a string +// create an Address from a hex string func GetValAddressHex(address string) (addr Address, err error) { if len(address) == 0 { return addr, errors.New("must use provide address") @@ -75,7 +75,7 @@ func GetValAddressHex(address string) (addr Address, err error) { return Address(bz), nil } -// create an Address from a string +// create an Address from a bech32cosmos string func GetValAddressBech32Cosmos(address string) (addr Address, err error) { if len(address) == 0 { return addr, errors.New("must use provide address") @@ -92,3 +92,26 @@ func GetValAddressBech32Cosmos(address string) (addr Address, err error) { } return Address(bz), nil } + +//Decode a validator publickey into a public key +func GetValPubKeyBech32Cosmos(pubkey string) (pk crypto.PubKey, err error) { + if len(pubkey) == 0 { + return pk, errors.New("must use provide pubkey") + } + hrp, bz, err := bech32cosmos.DecodeAndConvert(pubkey) + + if hrp != "cosmosvalpub" { + return pk, fmt.Errorf("Invalid Validator Pubkey Prefix. Expected cosmosvalpub, Got %s", hrp) + } + + if err != nil { + return nil, err + } + + pk, err = crypto.PubKeyFromBytes(bz) + if err != nil { + return nil, err + } + + return pk, nil +} diff --git a/x/stake/client/cli/tx.go b/x/stake/client/cli/tx.go index acb3d026f4..dc88bfc209 100644 --- a/x/stake/client/cli/tx.go +++ b/x/stake/client/cli/tx.go @@ -1,14 +1,11 @@ package cli import ( - "encoding/hex" "fmt" "github.com/spf13/cobra" "github.com/spf13/viper" - crypto "github.com/tendermint/go-crypto" - "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" @@ -28,7 +25,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { if err != nil { return err } - validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) + validatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) if err != nil { return err } @@ -37,15 +34,10 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { if len(pkStr) == 0 { return fmt.Errorf("must use --pubkey flag") } - pkBytes, err := hex.DecodeString(pkStr) + pk, err := sdk.GetValPubKeyBech32Cosmos(pkStr) if err != nil { return err } - pk, err := crypto.PubKeyFromBytes(pkBytes) - if err != nil { - return err - } - if viper.GetString(FlagMoniker) == "" { return fmt.Errorf("please enter a moniker for the validator using --moniker") } @@ -82,7 +74,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command { Short: "edit and existing validator account", RunE: func(cmd *cobra.Command, args []string) error { - validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) + validatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) if err != nil { return err } @@ -124,7 +116,7 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { } delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressDelegator)) - validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) + validatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) if err != nil { return err } @@ -172,7 +164,7 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { } delegatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressDelegator)) - validatorAddr, err := sdk.GetValAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) + validatorAddr, err := sdk.GetAccAddressBech32Cosmos(viper.GetString(FlagAddressValidator)) if err != nil { return err } From ba7d1c0b8e196b7614e8fcc0748e96020ba507a6 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 27 May 2018 14:24:18 +0200 Subject: [PATCH 5/8] Use the account encoding for the validator address --- x/stake/delegation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/stake/delegation.go b/x/stake/delegation.go index 37c68d9525..6877034d71 100644 --- a/x/stake/delegation.go +++ b/x/stake/delegation.go @@ -39,7 +39,7 @@ func (b Delegation) HumanReadableString() (string, error) { if err != nil { return "", err } - bechVal, err := sdk.Bech32CosmosifyVal(b.ValidatorAddr) + bechVal, err := sdk.Bech32CosmosifyAcc(b.ValidatorAddr) if err != nil { return "", err } From ca9af7462a14fddb8fc3bc2bc269fdac9c1149a6 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 27 May 2018 14:51:19 +0200 Subject: [PATCH 6/8] Update change log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e429a1c8e..5f3202bff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ BREAKING CHANGES * [x/auth] got rid of AccountMapper interface (in favor of the struct already in auth module) * [x/auth] removed the FeeHandler function from the AnteHandler, Replaced with FeeKeeper * [x/auth] Removed GetSignatures() from Tx interface (as different Tx styles might use something different than StdSignature) +* Switch to bech32cosmos on all human readable inputs and outputs BUG FIXES From f946b630a44c0d0ffc879c90c9cd019d07f0ac92 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 28 May 2018 19:27:34 -0400 Subject: [PATCH 7/8] fixes from review --- client/keys/utils.go | 24 ++++++++++------- types/account.go | 64 +++++++++++++++++++++----------------------- types/stake.go | 2 +- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/client/keys/utils.go b/client/keys/utils.go index eaf1e4c2fb..a49ac63c0e 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -74,15 +74,7 @@ func printInfo(info keys.Info) { switch viper.Get(cli.OutputFlag) { case "text": fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n") - 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) + printKeyOutput(ko) case "json": out, err := json.MarshalIndent(ko, "", "\t") if err != nil { @@ -98,7 +90,7 @@ func printInfos(infos []keys.Info) { case "text": fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n") for _, ko := range kos { - fmt.Printf("%s\t%s\t%s\n", ko.Name, ko.Address, ko.PubKey) + printKeyOutput(ko) } case "json": out, err := json.MarshalIndent(kos, "", "\t") @@ -108,3 +100,15 @@ func printInfos(infos []keys.Info) { fmt.Println(string(out)) } } + +func printKeyOutput(ko KeyOutput) { + 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) +} diff --git a/types/account.go b/types/account.go index 615fd30c17..b593dfb539 100644 --- a/types/account.go +++ b/types/account.go @@ -13,24 +13,32 @@ import ( //Address is a go crypto-style Address type Address = cmn.HexBytes +// Bech32 prefixes +const ( + Bech32PrefixAccAddr = "cosmosaccaddr" + Bech32PrefixAccPub = "cosmosaccpub" + Bech32PrefixValAddr = "cosmosvaladdr" + Bech32PrefixValPub = "cosmosvalpub" +) + // Bech32CosmosifyAcc takes Address and returns the Bech32Cosmos encoded string func Bech32CosmosifyAcc(addr Address) (string, error) { - return bech32cosmos.ConvertAndEncode("cosmosaccaddr", addr.Bytes()) + return bech32cosmos.ConvertAndEncode(Bech32PrefixAccAddr, addr.Bytes()) } // Bech32CosmosifyAccPub takes AccountPubKey and returns the Bech32Cosmos encoded string func Bech32CosmosifyAccPub(pub crypto.PubKey) (string, error) { - return bech32cosmos.ConvertAndEncode("cosmosaccpub", pub.Bytes()) + return bech32cosmos.ConvertAndEncode(Bech32PrefixAccPub, pub.Bytes()) } // Bech32CosmosifyVal returns the Bech32Cosmos encoded string for a validator address func Bech32CosmosifyVal(addr Address) (string, error) { - return bech32cosmos.ConvertAndEncode("cosmosvaladdr", addr.Bytes()) + return bech32cosmos.ConvertAndEncode(Bech32PrefixValAddr, 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()) + return bech32cosmos.ConvertAndEncode(Bech32PrefixValPub, pub.Bytes()) } // create an Address from a string @@ -47,16 +55,7 @@ func GetAccAddressHex(address string) (addr Address, err error) { // 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) - } - + bz, err := getFromBech32Cosmos(address, Bech32PrefixAccAddr) if err != nil { return nil, err } @@ -77,16 +76,7 @@ func GetValAddressHex(address string) (addr Address, err error) { // create an Address from a bech32cosmos 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) - } - + bz, err := getFromBech32Cosmos(address, Bech32PrefixValAddr) if err != nil { return nil, err } @@ -95,15 +85,7 @@ func GetValAddressBech32Cosmos(address string) (addr Address, err error) { //Decode a validator publickey into a public key func GetValPubKeyBech32Cosmos(pubkey string) (pk crypto.PubKey, err error) { - if len(pubkey) == 0 { - return pk, errors.New("must use provide pubkey") - } - hrp, bz, err := bech32cosmos.DecodeAndConvert(pubkey) - - if hrp != "cosmosvalpub" { - return pk, fmt.Errorf("Invalid Validator Pubkey Prefix. Expected cosmosvalpub, Got %s", hrp) - } - + bz, err := getFromBech32Cosmos(pubkey, Bech32PrefixValPub) if err != nil { return nil, err } @@ -115,3 +97,19 @@ func GetValPubKeyBech32Cosmos(pubkey string) (pk crypto.PubKey, err error) { return pk, nil } + +func getFromBech32Cosmos(bech32, prefix string) ([]byte, error) { + if len(bech32) == 0 { + return nil, errors.New("must provide non-empty string") + } + hrp, bz, err := bech32cosmos.DecodeAndConvert(bech32) + if err != nil { + return nil, err + } + + if hrp != prefix { + return nil, fmt.Errorf("Invalid bech32 prefix. Expected %s, Got %s", prefix, hrp) + } + + return bz, nil +} diff --git a/types/stake.go b/types/stake.go index c640e98e77..6a1a3a95f6 100644 --- a/types/stake.go +++ b/types/stake.go @@ -19,7 +19,7 @@ const ( func BondStatusToString(b BondStatus) string { switch b { case 0x00: - return "Ubbonded" + return "Unbonded" case 0x01: return "Unbonding" case 0x02: From 5055a4af4531ba711a2c3cde065a25cb100f210c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 29 May 2018 04:51:11 +0200 Subject: [PATCH 8/8] Tiny indentation fix --- client/keys/utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/keys/utils.go b/client/keys/utils.go index a49ac63c0e..1a358cfc9c 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -73,7 +73,7 @@ func printInfo(info keys.Info) { ko := NewKeyOutput(info) switch viper.Get(cli.OutputFlag) { case "text": - fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n") + fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n") printKeyOutput(ko) case "json": out, err := json.MarshalIndent(ko, "", "\t") @@ -88,7 +88,7 @@ func printInfos(infos []keys.Info) { kos := NewKeyOutputs(infos) switch viper.Get(cli.OutputFlag) { case "text": - fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n") + fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n") for _, ko := range kos { printKeyOutput(ko) }