Added POST /stake/bondunbond endpoint

This commit is contained in:
Matt Bell 2018-05-14 16:43:51 -07:00
parent efd1a3ac44
commit ad3c63dded
3 changed files with 134 additions and 4 deletions

View File

@ -14,13 +14,12 @@ import (
"github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake"
) )
// RegisterRoutes - Central function to define routes that get registered by the main application func registerQueryRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", bondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
r.HandleFunc("/stake/{delegator}/bonding_status/{validator}", BondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
} }
// BondingStatusHandlerFn - http request handler to query delegator bonding status // BondingStatusHandlerFn - http request handler to query delegator bonding status
func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc { func bondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
// read parameters // read parameters
vars := mux.Vars(r) vars := mux.Vars(r)

View File

@ -0,0 +1,14 @@
package rest
import (
"github.com/gorilla/mux"
"github.com/tendermint/go-crypto/keys"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/wire"
)
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
registerQueryRoutes(ctx, r, cdc, kb)
registerTxRoutes(ctx, r, cdc, kb)
}

117
x/stake/client/rest/tx.go Normal file
View File

@ -0,0 +1,117 @@
package rest
import (
"encoding/json"
"io/ioutil"
"net/http"
"github.com/gorilla/mux"
"github.com/tendermint/go-crypto/keys"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/stake"
)
func registerTxRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
r.HandleFunc("/stake/bondunbond", bondUnbondRequestHandlerFn(cdc, kb, ctx)).Methods("POST")
}
type bond struct {
Amount sdk.Coin `json:"amount"`
Candidate sdk.Address `json:"candidate"`
}
type unbond struct {
Shares string `json:"shares"`
Candidate sdk.Address `json:"candidate"`
}
type bondUnbondBody struct {
// fees is not used currently
// Fees sdk.Coin `json="fees"`
LocalAccountName string `json:"name"`
Password string `json:"password"`
ChainID string `json:"chain_id"`
Sequence int64 `json:"sequence"`
Bond []bond `json:"bond"`
Unbond []unbond `json:"unbond"`
}
func bondUnbondRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var m bondUnbondBody
body, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
err = json.Unmarshal(body, &m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
info, err := kb.Get(m.LocalAccountName)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
return
}
// build messages
messages := make([]sdk.Msg, 0, len(m.Bond)+len(m.Unbond))
for _, bond := range m.Bond {
msg := stake.NewMsgDelegate(info.Address(), bond.Candidate, bond.Amount)
messages = append(messages, msg)
}
for _, unbond := range m.Unbond {
msg := stake.NewMsgUnbond(info.Address(), unbond.Candidate, unbond.Shares)
messages = append(messages, msg)
}
// sign messages
signedTxs := make([][]byte, 0, len(messages))
for _, msg := range messages {
// increment sequence for each message
ctx = ctx.WithSequence(m.Sequence)
m.Sequence++
txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
return
}
signedTxs = append(signedTxs, txBytes)
}
// send
// XXX the operation might not be atomic if a tx fails
// should we have a sdk.MultiMsg type to make sending atomic?
results := make([]*ctypes.ResultBroadcastTxCommit, 0, len(signedTxs))
for _, txBytes := range signedTxs {
res, err := ctx.BroadcastTx(txBytes)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
results = append(results, res)
}
output, err := json.MarshalIndent(results, "", " ")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}