bump version

added rest server and status endpoint

added get block endpoint

added latest block endpoint

add 404 if height is out of bounds

add version endpoint

add validators endpoint

export GetBlockHeight

add keys endpoints

add txs endpoints

added verb limiters to ednpoints

only output node info + json structure improvement

fixed wrong body parsing

github PR template

crypto.Address -> sdk.Address

revert to old go-wire

update glide

remove print statement and update glide

fix #554

add .DS_Store to .gitignore

Massive consolidation: queue, data storage struct, store, logic, ...

Small fixes
This commit is contained in:
Ethan Buchman
2018-03-17 22:14:19 +01:00
parent 7c3213fa00
commit ad705fdea1
18 changed files with 1662 additions and 93 deletions
+76
View File
@@ -1,9 +1,12 @@
package keys
import (
"encoding/json"
"fmt"
"net/http"
"github.com/cosmos/cosmos-sdk/client"
"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@@ -120,3 +123,76 @@ func printCreate(info keys.Info, seed string) {
panic(fmt.Sprintf("I can't speak: %s", output))
}
}
// REST
type NewKeyBody struct {
Name string `json:"name"`
Password string `json:"password"`
// TODO make seed mandatory
// Seed string `json="seed"`
Type string `json:"type"`
}
func AddNewKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
var kb keys.Keybase
var m NewKeyBody
kb, err := GetKeyBase()
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
decoder := json.NewDecoder(r.Body)
err = decoder.Decode(&m)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
return
}
if m.Name == "" {
w.WriteHeader(400)
w.Write([]byte("You have to specify a name for the locally stored account."))
return
}
// algo type defaults to ed25519
if m.Type == "" {
m.Type = "ed25519"
}
algo := keys.CryptoAlgo(m.Type)
_, _, err = kb.Create(m.Name, m.Password, algo)
// TODO handle different errors
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(200)
}
// function to just a new seed to display in the UI before actually persisting it in the keybase
func getSeed(algo keys.CryptoAlgo) string {
kb := client.MockKeyBase()
pass := "throwing-this-key-away"
name := "inmemorykey"
_, seed, _ := kb.Create(name, pass, algo)
return seed
}
func SeedRequestHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
algoType := vars["type"]
// algo type defaults to ed25519
if algoType == "" {
algoType = "ed25519"
}
algo := keys.CryptoAlgo(algoType)
seed := getSeed(algo)
w.Write([]byte(seed))
}
+42
View File
@@ -1,10 +1,14 @@
package keys
import (
"encoding/json"
"fmt"
"net/http"
"github.com/cosmos/cosmos-sdk/client"
"github.com/gorilla/mux"
"github.com/pkg/errors"
keys "github.com/tendermint/go-crypto/keys"
"github.com/spf13/cobra"
)
@@ -43,3 +47,41 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error {
fmt.Println("Password deleted forever (uh oh!)")
return nil
}
// REST
type DeleteKeyBody struct {
Password string `json:"password"`
}
func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
var kb keys.Keybase
var m DeleteKeyBody
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&m)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
return
}
kb, err = GetKeyBase()
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
// TODO handle error if key is not available or pass is wrong
err = kb.Delete(name, m.Password)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(200)
}
+41 -1
View File
@@ -1,6 +1,13 @@
package keys
import "github.com/spf13/cobra"
import (
"encoding/json"
"net/http"
"github.com/spf13/cobra"
)
// CMD
// listKeysCmd represents the list command
var listKeysCmd = &cobra.Command{
@@ -23,3 +30,36 @@ func runListCmd(cmd *cobra.Command, args []string) error {
}
return err
}
//REST
func QueryKeysRequestHandler(w http.ResponseWriter, r *http.Request) {
kb, err := GetKeyBase()
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
infos, err := kb.List()
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
// an empty list will be JSONized as null, but we want to keep the empty list
if len(infos) == 0 {
w.Write([]byte("[]"))
return
}
keysOutput := make([]KeyOutput, len(infos))
for i, info := range infos {
keysOutput[i] = KeyOutput{Name: info.Name, Address: info.PubKey.Address().String()}
}
output, err := json.MarshalIndent(keysOutput, "", " ")
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
+42 -6
View File
@@ -1,7 +1,12 @@
package keys
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
"github.com/pkg/errors"
keys "github.com/tendermint/go-crypto/keys"
"github.com/spf13/cobra"
)
@@ -13,20 +18,51 @@ var showKeysCmd = &cobra.Command{
RunE: runShowCmd,
}
func getKey(name string) (keys.Info, error) {
kb, err := GetKeyBase()
if err != nil {
return keys.Info{}, err
}
return kb.Get(name)
}
// CMD
func runShowCmd(cmd *cobra.Command, args []string) error {
if len(args) != 1 || len(args[0]) == 0 {
return errors.New("You must provide a name for the key")
}
name := args[0]
kb, err := GetKeyBase()
if err != nil {
return err
}
info, err := kb.Get(name)
info, err := getKey(name)
if err == nil {
printInfo(info)
}
return err
}
// REST
func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
info, err := getKey(name)
// TODO check for the error if key actually does not exist, instead of assuming this as the reason
if err != nil {
w.WriteHeader(404)
w.Write([]byte(err.Error()))
return
}
keyOutput := KeyOutput{Name: info.Name, Address: info.PubKey.Address().String()}
output, err := json.MarshalIndent(keyOutput, "", " ")
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
+43
View File
@@ -1,10 +1,14 @@
package keys
import (
"encoding/json"
"fmt"
"net/http"
"github.com/cosmos/cosmos-sdk/client"
"github.com/gorilla/mux"
"github.com/pkg/errors"
keys "github.com/tendermint/go-crypto/keys"
"github.com/spf13/cobra"
)
@@ -48,3 +52,42 @@ func runUpdateCmd(cmd *cobra.Command, args []string) error {
fmt.Println("Password successfully updated!")
return nil
}
// REST
type UpdateKeyBody struct {
NewPassword string `json:"new_password"`
OldPassword string `json:"old_password"`
}
func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
var kb keys.Keybase
var m UpdateKeyBody
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&m)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
return
}
kb, err = GetKeyBase()
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
// TODO check if account exists and if password is correct
err = kb.Update(name, m.OldPassword, m.NewPassword)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(200)
}
+8
View File
@@ -20,6 +20,14 @@ var (
keybase keys.Keybase
)
// used for outputting keys.Info over REST
type KeyOutput struct {
Name string `json:"name"`
Address string `json:"address"`
// TODO add pubkey?
// Pubkey string `json:"pubkey"`
}
// GetKeyBase initializes a keybase based on the configuration
func GetKeyBase() (keys.Keybase, error) {
if keybase == nil {