diff --git a/x/stake/commands/query.go b/x/stake/commands/query.go index aa455d3474..46fc029526 100644 --- a/x/stake/commands/query.go +++ b/x/stake/commands/query.go @@ -1,16 +1,21 @@ package commands import ( + "encoding/hex" + "encoding/json" + "fmt" + + "github.com/pkg/errors" "github.com/spf13/cobra" flag "github.com/spf13/pflag" "github.com/spf13/viper" crypto "github.com/tendermint/go-crypto" - "github.com/cosmos/cosmos-sdk/client/commands" - "github.com/cosmos/cosmos-sdk/client/commands/query" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/examples/basecoin/app" coin "github.com/cosmos/cosmos-sdk/x/bank" // XXX fix - "github.com/cosmos/gaia/x/stake" + "github.com/cosmos/cosmos-sdk/x/stake" ) // XXX remove dependancy @@ -61,18 +66,59 @@ func init() { CmdQueryDelegatorCandidates.Flags().AddFlagSet(fsAddr) } +// XXX move to common directory in client helpers +func makeQuery(key, storeName string) (res []byte, err error) { + + path := fmt.Sprintf("/%s/key", a.storeName) + + uri := viper.GetString(client.FlagNode) + if uri == "" { + return res, errors.New("Must define which node to query with --node") + } + node := client.GetNode(uri) + + opts := rpcclient.ABCIQueryOptions{ + Height: viper.GetInt64(client.FlagHeight), + Trusted: viper.GetBool(client.FlagTrustNode), + } + result, err := node.ABCIQueryWithOptions(path, key, opts) + if err != nil { + return res, err + } + resp := result.Response + if resp.Code != uint32(0) { + return res, errors.Errorf("Query failed: (%d) %s", resp.Code, resp.Log) + } + return resp.val, nil +} + func cmdQueryCandidates(cmd *cobra.Command, args []string) error { var pks []crypto.PubKey - prove := !viper.GetBool(commands.FlagTrustNode) + prove := !viper.GetBool(client.FlagTrustNode) key := PrefixedKey(stake.Name(), stake.CandidatesPubKeysKey) - height, err := query.GetParsed(key, &pks, query.GetHeight(), prove) + + res, err := makeQuery(key, "gaia-store-name") // XXX move gaia store name out of here if err != nil { return err } - return query.OutputProof(pks, height) + // parse out the candidates + candidates := new(stake.Candidates) + cdc := app.MakeTxCodec() // XXX create custom Tx for Staking Module + err = cdc.UnmarshalBinary(res, candidates) + if err != nil { + return err + } + output, err := json.MarshalIndent(candidates, "", " ") + if err != nil { + return err + } + fmt.Println(string(output)) + return nil + + // TODO output with proofs / machine parseable etc. } func cmdQueryCandidate(cmd *cobra.Command, args []string) error { @@ -84,58 +130,85 @@ func cmdQueryCandidate(cmd *cobra.Command, args []string) error { return err } - prove := !viper.GetBool(commands.FlagTrustNode) + prove := !viper.GetBool(client.FlagTrustNode) key := PrefixedKey(stake.Name(), stake.GetCandidateKey(pk)) - height, err := query.GetParsed(key, &candidate, query.GetHeight(), prove) + + // parse out the candidate + candidate := new(stake.Candidate) + cdc := app.MakeTxCodec() // XXX create custom Tx for Staking Module + err = cdc.UnmarshalBinary(res, candidate) if err != nil { return err } + output, err := json.MarshalIndent(candidate, "", " ") + if err != nil { + return err + } + fmt.Println(string(output)) + return nil - return query.OutputProof(candidate, height) + // TODO output with proofs / machine parseable etc. } func cmdQueryDelegatorBond(cmd *cobra.Command, args []string) error { - var bond stake.DelegatorBond - pk, err := GetPubKey(viper.GetString(FlagPubKey)) if err != nil { return err } - delegatorAddr := viper.GetString(FlagDelegatorAddress) - delegator, err := commands.ParseActor(delegatorAddr) + bz, err := hex.DecodeString(viper.GetString(FlagDelegatorAddress)) if err != nil { return err } + delegator := crypto.Address(bz) delegator = coin.ChainAddr(delegator) - prove := !viper.GetBool(commands.FlagTrustNode) + prove := !viper.GetBool(client.FlagTrustNode) key := PrefixedKey(stake.Name(), stake.GetDelegatorBondKey(delegator, pk)) - height, err := query.GetParsed(key, &bond, query.GetHeight(), prove) + + // parse out the bond + var bond stake.DelegatorBond + cdc := app.MakeTxCodec() // XXX create custom Tx for Staking Module + err = cdc.UnmarshalBinary(res, bond) if err != nil { return err } + output, err := json.MarshalIndent(bond, "", " ") + if err != nil { + return err + } + fmt.Println(string(output)) + return nil - return query.OutputProof(bond, height) + // TODO output with proofs / machine parseable etc. } func cmdQueryDelegatorCandidates(cmd *cobra.Command, args []string) error { - delegatorAddr := viper.GetString(FlagDelegatorAddress) - delegator, err := commands.ParseActor(delegatorAddr) + bz, err := hex.DecodeString(viper.GetString(FlagDelegatorAddress)) if err != nil { return err } + delegator := crypto.Address(bz) delegator = coin.ChainAddr(delegator) - prove := !viper.GetBool(commands.FlagTrustNode) + prove := !viper.GetBool(client.FlagTrustNode) key := PrefixedKey(stake.Name(), stake.GetDelegatorBondsKey(delegator)) + + // parse out the candidates list var candidates []crypto.PubKey - height, err := query.GetParsed(key, &candidates, query.GetHeight(), prove) + cdc := app.MakeTxCodec() // XXX create custom Tx for Staking Module + err = cdc.UnmarshalBinary(res, candidates) if err != nil { return err } + output, err := json.MarshalIndent(candidates, "", " ") + if err != nil { + return err + } + fmt.Println(string(output)) + return nil - return query.OutputProof(candidates, height) + // TODO output with proofs / machine parseable etc. } diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index e14ac8cec1..76bf5753dd 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -4,17 +4,16 @@ import ( "encoding/hex" "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" flag "github.com/spf13/pflag" "github.com/spf13/viper" crypto "github.com/tendermint/go-crypto" - "github.com/tendermint/tmlibs/rational" - txcmd "github.com/cosmos/cosmos-sdk/client/commands/txs" - "github.com/cosmos/cosmos-sdk/modules/coin" - - "github.com/cosmos/gaia/modules/stake" + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake" ) // nolint @@ -87,7 +86,7 @@ func init() { } func cmdDeclareCandidacy(cmd *cobra.Command, args []string) error { - amount, err := coin.ParseCoin(viper.GetString(FlagAmount)) + amount, err := sdk.ParseCoin(viper.GetString(FlagAmount)) if err != nil { return err } @@ -109,7 +108,7 @@ func cmdDeclareCandidacy(cmd *cobra.Command, args []string) error { } tx := stake.NewTxDeclareCandidacy(amount, pk, description) - return txcmd.DoTx(tx) + return doTx(tx) } func cmdEditCandidacy(cmd *cobra.Command, args []string) error { @@ -127,11 +126,11 @@ func cmdEditCandidacy(cmd *cobra.Command, args []string) error { } tx := stake.NewTxEditCandidacy(pk, description) - return txcmd.DoTx(tx) + return doTx(tx) } func cmdDelegate(cmd *cobra.Command, args []string) error { - amount, err := coin.ParseCoin(viper.GetString(FlagAmount)) + amount, err := sdk.ParseCoin(viper.GetString(FlagAmount)) if err != nil { return err } @@ -142,7 +141,7 @@ func cmdDelegate(cmd *cobra.Command, args []string) error { } tx := stake.NewTxDelegate(amount, pk) - return txcmd.DoTx(tx) + return doTx(tx) } func cmdUnbond(cmd *cobra.Command, args []string) error { @@ -151,14 +150,14 @@ func cmdUnbond(cmd *cobra.Command, args []string) error { // check the shares before broadcasting sharesStr := viper.GetString(FlagShares) - var shares rational.Rat + var shares sdk.Rat if sharesStr != "MAX" { var err error - shares, err = rational.NewFromDecimal(sharesStr) + shares, err = sdk.NewRatFromDecimal(sharesStr) if err != nil { return err } - if !shares.GT(rational.Zero) { + if !shares.GT(sdk.ZeroRat) { return fmt.Errorf("shares must be positive integer or decimal (ex. 123, 1.23456789)") } } @@ -169,7 +168,7 @@ func cmdUnbond(cmd *cobra.Command, args []string) error { } tx := stake.NewTxUnbond(sharesStr, pk) - return txcmd.DoTx(tx) + return doTx(tx) } // GetPubKey - create the pubkey from a pubkey string @@ -193,3 +192,34 @@ func GetPubKey(pubKeyStr string) (pk crypto.PubKey, err error) { pk = pkEd.Wrap() return } + +//-------------------------------------------------------------------- +// XXX consolidate to client + +func doTx(tx []byte) { + + uri := viper.GetString(client.FlagNode) + if uri == "" { + return errors.New("Must define which node to query with --node") + } + node := client.GetNode(uri) + + result, err := node.BroadcastTxCommit(tx) + if err != nil { + return err + } + + if result.CheckTx.Code != uint32(0) { + fmt.Printf("CheckTx failed: (%d) %s\n", + result.CheckTx.Code, + result.CheckTx.Log) + } + if result.DeliverTx.Code != uint32(0) { + fmt.Printf("DeliverTx failed: (%d) %s\n", + result.DeliverTx.Code, + result.DeliverTx.Log) + } + + fmt.Printf("Committed at block %d. Hash: %s\n", result.Height, result.Hash.String()) + return nil +} diff --git a/x/stake/tx.go b/x/stake/tx.go index 3d5a6c4083..13080bf9bc 100644 --- a/x/stake/tx.go +++ b/x/stake/tx.go @@ -4,7 +4,6 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - coin "github.com/cosmos/cosmos-sdk/x/bank" // XXX fix crypto "github.com/tendermint/go-crypto" ) @@ -38,7 +37,7 @@ const ( // BondUpdate - struct for bonding or unbonding transactions type BondUpdate struct { PubKey crypto.PubKey `json:"pub_key"` - Bond coin.Coin `json:"amount"` + Bond sdk.Coin `json:"amount"` } // ValidateBasic - Check for non-empty candidate, and valid coins @@ -46,9 +45,9 @@ func (tx BondUpdate) ValidateBasic() error { if tx.PubKey.Empty() { return errCandidateEmpty } - coins := coin.Coins{tx.Bond} - if !coins.IsValid() { - return coin.ErrInvalidCoins() + coins := sdk.Coins{tx.Bond} + if !sdk.IsValid() { + return sdk.ErrInvalidCoins() } if !coins.IsPositive() { return fmt.Errorf("Amount must be > 0") @@ -63,7 +62,7 @@ type TxDeclareCandidacy struct { } // NewTxDeclareCandidacy - new TxDeclareCandidacy -func NewTxDeclareCandidacy(bond coin.Coin, pubKey crypto.PubKey, description Description) sdk.Tx { +func NewTxDeclareCandidacy(bond sdk.Coin, pubKey crypto.PubKey, description Description) sdk.Tx { return TxDeclareCandidacy{ BondUpdate{ PubKey: pubKey, @@ -110,7 +109,7 @@ func (tx TxEditCandidacy) ValidateBasic() error { type TxDelegate struct{ BondUpdate } // NewTxDelegate - new TxDelegate -func NewTxDelegate(bond coin.Coin, pubKey crypto.PubKey) sdk.Tx { +func NewTxDelegate(bond sdk.Coin, pubKey crypto.PubKey) sdk.Tx { return TxDelegate{BondUpdate{ PubKey: pubKey, Bond: bond, diff --git a/x/stake/tx_test.go b/x/stake/tx_test.go index f6d814589d..4324d9446a 100644 --- a/x/stake/tx_test.go +++ b/x/stake/tx_test.go @@ -6,30 +6,29 @@ import ( "github.com/stretchr/testify/assert" - "github.com/cosmos/cosmos-sdk" - "github.com/cosmos/cosmos-sdk/modules/coin" - crypto "github.com/tendermint/go-crypto" wire "github.com/tendermint/go-wire" + + sdk "github.com/cosmos/cosmos-sdk/types" ) var ( validator = sdk.Actor{"testChain", "testapp", []byte("addressvalidator1")} empty sdk.Actor - coinPos = coin.Coin{"fermion", 1000} - coinZero = coin.Coin{"fermion", 0} - coinNeg = coin.Coin{"fermion", -10000} - coinPosNotAtoms = coin.Coin{"foo", 10000} - coinZeroNotAtoms = coin.Coin{"foo", 0} - coinNegNotAtoms = coin.Coin{"foo", -10000} + coinPos = sdk.Coin{"fermion", 1000} + coinZero = sdk.Coin{"fermion", 0} + coinNeg = sdk.Coin{"fermion", -10000} + coinPosNotAtoms = sdk.Coin{"foo", 10000} + coinZeroNotAtoms = sdk.Coin{"foo", 0} + coinNegNotAtoms = sdk.Coin{"foo", -10000} ) func TestBondUpdateValidateBasic(t *testing.T) { tests := []struct { name string PubKey crypto.PubKey - Bond coin.Coin + Bond sdk.Coin wantErr bool }{ {"basic good", pks[0], coinPos, false}, @@ -49,40 +48,38 @@ func TestBondUpdateValidateBasic(t *testing.T) { } func TestAllAreTx(t *testing.T) { - assert := assert.New(t) // make sure all types construct properly pubKey := newPubKey("1234567890") bondAmt := 1234321 - bond := coin.Coin{Denom: "ATOM", Amount: int64(bondAmt)} + bond := sdk.Coin{Denom: "ATOM", Amount: int64(bondAmt)} // Note that Wrap is only defined on BondUpdate, so when you call it, // you lose all info on the embedding type. Please add Wrap() // method to all the parents txDelegate := NewTxDelegate(bond, pubKey) _, ok := txDelegate.Unwrap().(TxDelegate) - assert.True(ok, "%#v", txDelegate) + assert.True(t, ok, "%#v", txDelegate) txUnbond := NewTxUnbond(strconv.Itoa(bondAmt), pubKey) _, ok = txUnbond.Unwrap().(TxUnbond) - assert.True(ok, "%#v", txUnbond) + assert.True(t, ok, "%#v", txUnbond) txDecl := NewTxDeclareCandidacy(bond, pubKey, Description{}) _, ok = txDecl.Unwrap().(TxDeclareCandidacy) - assert.True(ok, "%#v", txDecl) + assert.True(t, ok, "%#v", txDecl) txEditCan := NewTxEditCandidacy(pubKey, Description{}) _, ok = txEditCan.Unwrap().(TxEditCandidacy) - assert.True(ok, "%#v", txEditCan) + assert.True(t, ok, "%#v", txEditCan) } func TestSerializeTx(t *testing.T) { - assert := assert.New(t) // make sure all types construct properly pubKey := newPubKey("1234567890") bondAmt := 1234321 - bond := coin.Coin{Denom: "ATOM", Amount: int64(bondAmt)} + bond := sdk.Coin{Denom: "ATOM", Amount: int64(bondAmt)} tests := []struct { tx sdk.Tx @@ -97,8 +94,8 @@ func TestSerializeTx(t *testing.T) { var tx sdk.Tx bs := wire.BinaryBytes(tc.tx) err := wire.ReadBinaryBytes(bs, &tx) - if assert.NoError(err, "%d", i) { - assert.Equal(tc.tx, tx, "%d", i) + if assert.NoError(t, err, "%d", i) { + assert.Equal(t, tc.tx, tx, "%d", i) } } }