From dac4d9e1559e48a35e55f8389c285e9a58352517 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Fri, 11 Aug 2017 15:57:20 -0700 Subject: [PATCH] Started implementing nonce REST query handler --- cmd/baseserver/main.go | 4 ++ modules/nonce/rest/handlers.go | 72 ++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 modules/nonce/rest/handlers.go diff --git a/cmd/baseserver/main.go b/cmd/baseserver/main.go index 82cff3d7bc..422b445dec 100644 --- a/cmd/baseserver/main.go +++ b/cmd/baseserver/main.go @@ -13,6 +13,7 @@ import ( "github.com/tendermint/basecoin/client/commands" rest "github.com/tendermint/basecoin/client/rest" coinrest "github.com/tendermint/basecoin/modules/coin/rest" + noncerest "github.com/tendermint/basecoin/modules/nonce/rest" rolerest "github.com/tendermint/basecoin/modules/roles/rest" "github.com/tendermint/tmlibs/cli" ) @@ -58,6 +59,9 @@ func serve(cmd *cobra.Command, args []string) error { rest.RegisterSignTx, // Basecoin post transaction handler rest.RegisterPostTx, + + // Nonce query handler + noncerest.RegisterQueryNonce, } for _, routeRegistrar := range routeRegistrars { diff --git a/modules/nonce/rest/handlers.go b/modules/nonce/rest/handlers.go new file mode 100644 index 0000000000..630d055f80 --- /dev/null +++ b/modules/nonce/rest/handlers.go @@ -0,0 +1,72 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + "github.com/spf13/viper" + + "github.com/tendermint/basecoin" + "github.com/tendermint/basecoin/client/commands" + "github.com/tendermint/basecoin/client/commands/query" + "github.com/tendermint/basecoin/errors" + "github.com/tendermint/basecoin/modules/coin" + "github.com/tendermint/basecoin/modules/nonce" + "github.com/tendermint/basecoin/stack" + wire "github.com/tendermint/go-wire" + lightclient "github.com/tendermint/light-client" + "github.com/tendermint/tmlibs/common" +) + +// doQueryNonce is the HTTP handlerfunc to query a nonce +func doQueryNonce(w http.ResponseWriter, r *http.Request) { + args := mux.Vars(r) + signature := args["signature"] + actor, err := commands.ParseActor(signature) + if err != nil { + common.WriteError(w, err) + return + } + actor = coin.ChainAddr(actor) + key := nonce.GetSeqKey([]basecoin.Actor{actor}) + key = stack.PrefixedKey(nonce.NameNonce, key) + + prove := !viper.GetBool(commands.FlagTrustNode) + + // query sequence number + data, height, err := query.Get(key, prove) + if lightclient.IsNoDataErr(err) { + err = fmt.Errorf("nonce empty for address: %q", signature) + common.WriteError(w, err) + return + } else if err != nil { + common.WriteError(w, err) + return + } + + // unmarshal sequence number + var seq uint32 + err = wire.ReadBinaryBytes(data, &seq) + if err != nil { + msg := fmt.Sprintf("Error reading sequence for %X", key) + common.WriteError(w, errors.ErrInternal(msg)) + return + } + + // write result to client + if err := query.FoutputProof(w, seq, height); err != nil { + common.WriteError(w, err) + } +} + +// mux.Router registrars + +// RegisterQueryNonce is a mux.Router handler that exposes GET +// method access on route /query/nonce/{signature} to query nonces +func RegisterQueryNonce(r *mux.Router) error { + r.HandleFunc("/query/nonce/{signature}", doQueryNonce).Methods("GET") + return nil +} + +// End of mux.Router registrars