OSDN Git Service

modify get-block-count API (#447)
[bytom/bytom-spv.git] / blockchain / rpc_reactor.go
1 package blockchain
2
3 import (
4         "net/http"
5         "time"
6
7         log "github.com/sirupsen/logrus"
8
9         "github.com/bytom/blockchain/accesstoken"
10         "github.com/bytom/dashboard"
11         "github.com/bytom/errors"
12         "github.com/bytom/net/http/authn"
13         "github.com/bytom/net/http/httpjson"
14         "github.com/bytom/net/http/static"
15 )
16
17 var (
18         errNotAuthenticated = errors.New("not authenticated")
19 )
20
21 // json handler
22 func jsonHandler(f interface{}) http.Handler {
23         h, err := httpjson.Handler(f, errorFormatter.Write)
24         if err != nil {
25                 panic(err)
26         }
27         return h
28 }
29
30 // error handler
31 func alwaysError(err error) http.Handler {
32         return jsonHandler(func() error { return err })
33 }
34
35 // serve http
36 func (bcr *BlockchainReactor) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
37         if bcr.handler != nil {
38                 bcr.handler.ServeHTTP(rw, req)
39         }
40 }
41
42 func webAssetsHandler(next http.Handler) http.Handler {
43         mux := http.NewServeMux()
44         mux.Handle("/dashboard/", http.StripPrefix("/dashboard/", static.Handler{
45                 Assets:  dashboard.Files,
46                 Default: "index.html",
47         }))
48         mux.Handle("/", next)
49
50         return mux
51 }
52
53 // BuildHandler is in charge of all the rpc handling.
54 func (bcr *BlockchainReactor) BuildHandler() {
55         m := bcr.mux
56         if bcr.accounts != nil && bcr.assets != nil {
57                 m.Handle("/create-account", jsonHandler(bcr.createAccount))
58                 m.Handle("/update-account-tags", jsonHandler(bcr.updateAccountTags))
59                 m.Handle("/create-account-receiver", jsonHandler(bcr.createAccountReceiver))
60                 m.Handle("/list-accounts", jsonHandler(bcr.listAccounts))
61                 m.Handle("/list-addresses", jsonHandler(bcr.listAddresses))
62                 m.Handle("/delete-account", jsonHandler(bcr.deleteAccount))
63                 m.Handle("/validate-address", jsonHandler(bcr.validateAddress))
64
65                 m.Handle("/create-asset", jsonHandler(bcr.createAsset))
66                 m.Handle("/update-asset-alias", jsonHandler(bcr.updateAssetAlias))
67                 m.Handle("/update-asset-tags", jsonHandler(bcr.updateAssetTags))
68                 m.Handle("/list-assets", jsonHandler(bcr.listAssets))
69
70                 m.Handle("/create-key", jsonHandler(bcr.pseudohsmCreateKey))
71                 m.Handle("/list-keys", jsonHandler(bcr.pseudohsmListKeys))
72                 m.Handle("/delete-key", jsonHandler(bcr.pseudohsmDeleteKey))
73
74                 m.Handle("/get-transaction", jsonHandler(bcr.getTransaction))
75                 m.Handle("/list-transactions", jsonHandler(bcr.listTransactions))
76                 m.Handle("/list-balances", jsonHandler(bcr.listBalances))
77                 m.Handle("/reset-password", jsonHandler(bcr.pseudohsmResetPassword))
78         } else {
79                 log.Warn("Please enable wallet")
80         }
81
82         m.Handle("/", alwaysError(errors.New("not Found")))
83
84         m.Handle("/build-transaction", jsonHandler(bcr.build))
85         m.Handle("/sign-transaction", jsonHandler(bcr.pseudohsmSignTemplates))
86         m.Handle("/submit-transaction", jsonHandler(bcr.submit))
87         m.Handle("/sign-submit-transaction", jsonHandler(bcr.signSubmit))
88
89         m.Handle("/create-transaction-feed", jsonHandler(bcr.createTxFeed))
90         m.Handle("/get-transaction-feed", jsonHandler(bcr.getTxFeed))
91         m.Handle("/update-transaction-feed", jsonHandler(bcr.updateTxFeed))
92         m.Handle("/delete-transaction-feed", jsonHandler(bcr.deleteTxFeed))
93         m.Handle("/list-transaction-feeds", jsonHandler(bcr.listTxFeeds))
94         m.Handle("/list-unspent-outputs", jsonHandler(bcr.listUnspentOutputs))
95         m.Handle("/info", jsonHandler(bcr.info))
96
97         m.Handle("/create-access-token", jsonHandler(bcr.createAccessToken))
98         m.Handle("/list-access-tokens", jsonHandler(bcr.listAccessTokens))
99         m.Handle("/delete-access-token", jsonHandler(bcr.deleteAccessToken))
100         m.Handle("/check-access-token", jsonHandler(bcr.checkAccessToken))
101
102         m.Handle("/block-hash", jsonHandler(bcr.getBestBlockHash))
103
104         m.Handle("/export-private-key", jsonHandler(bcr.walletExportKey))
105         m.Handle("/import-private-key", jsonHandler(bcr.walletImportKey))
106         m.Handle("/import-key-progress", jsonHandler(bcr.keyImportProgress))
107
108         m.Handle("/get-block-header-by-hash", jsonHandler(bcr.getBlockHeaderByHash))
109         m.Handle("/get-block-header-by-height", jsonHandler(bcr.getBlockHeaderByHeight))
110         m.Handle("/get-block", jsonHandler(bcr.getBlock))
111         m.Handle("/get-block-count", jsonHandler(bcr.getBlockCount))
112         m.Handle("/get-block-transactions-count-by-hash", jsonHandler(bcr.getBlockTransactionsCountByHash))
113         m.Handle("/get-block-transactions-count-by-height", jsonHandler(bcr.getBlockTransactionsCountByHeight))
114
115         m.Handle("/net-info", jsonHandler(bcr.getNetInfo))
116
117         m.Handle("/is-mining", jsonHandler(bcr.isMining))
118         m.Handle("/gas-rate", jsonHandler(bcr.gasRate))
119         m.Handle("/getwork", jsonHandler(bcr.getWork))
120         m.Handle("/submitwork", jsonHandler(bcr.submitWork))
121
122         latencyHandler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
123                 if l := latency(m, req); l != nil {
124                         defer l.RecordSince(time.Now())
125                 }
126                 m.ServeHTTP(w, req)
127         })
128         handler := maxBytes(latencyHandler) // TODO(tessr): consider moving this to non-core specific mux
129         handler = webAssetsHandler(handler)
130
131         bcr.handler = handler
132 }
133
134 //AuthHandler access token auth handler
135 func AuthHandler(handler http.Handler, accessTokens *accesstoken.CredentialStore) http.Handler {
136
137         authenticator := authn.NewAPI(accessTokens)
138
139         return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
140                 // TODO(tessr): check that this path exists; return early if this path isn't legit
141                 req, err := authenticator.Authenticate(req)
142                 if err != nil {
143                         log.WithField("error", errors.Wrap(err, "Serve")).Error("Authenticate fail")
144                         err = errors.Sub(errNotAuthenticated, err)
145                         errorFormatter.Write(req.Context(), rw, err)
146                         return
147                 }
148                 handler.ServeHTTP(rw, req)
149         })
150 }