From bb48f2d26e71b4ab0fdc39d9c5f250ad35782dfd Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Wed, 19 Sep 2018 15:59:49 +0200 Subject: [PATCH] Cleanup of internal http interface --- api/types.go | 28 ++++--- api/worker.go | 37 ++++++---- server/internal.go | 180 +++++---------------------------------------- server/public.go | 4 +- 4 files changed, 58 insertions(+), 191 deletions(-) diff --git a/api/types.go b/api/types.go index 60952a71..bdc8df04 100644 --- a/api/types.go +++ b/api/types.go @@ -2,6 +2,7 @@ package api import ( "blockbook/bchain" + "blockbook/common" "blockbook/db" "math/big" "time" @@ -112,18 +113,21 @@ type Block struct { } type BlockbookInfo struct { - Coin string `json:"coin"` - Host string `json:"host"` - Version string `json:"version"` - GitCommit string `json:"gitcommit"` - BuildTime string `json:"buildtime"` - InSync bool `json:"inSync"` - BestHeight uint32 `json:"bestHeight"` - LastBlockTime time.Time `json:"lastBlockTime"` - InSyncMempool bool `json:"inSyncMempool"` - LastMempoolTime time.Time `json:"lastMempoolTime"` - DbSize int64 `json:"dbSize"` - About string `json:"about"` + Coin string `json:"coin"` + Host string `json:"host"` + Version string `json:"version"` + GitCommit string `json:"gitcommit"` + BuildTime string `json:"buildtime"` + InSync bool `json:"inSync"` + BestHeight uint32 `json:"bestHeight"` + LastBlockTime time.Time `json:"lastBlockTime"` + InSyncMempool bool `json:"inSyncMempool"` + LastMempoolTime time.Time `json:"lastMempoolTime"` + MempoolSize int `json:"mempoolSize"` + DbSize int64 `json:"dbSize"` + DbSizeFromColumns int64 `json:"dbSizeFromColumns,omitempty"` + DbColumns []common.InternalStateColumn `json:"dbColumns,omitempty"` + About string `json:"about"` } type SystemInfo struct { diff --git a/api/worker.go b/api/worker.go index 132d40aa..68d2fdb8 100644 --- a/api/worker.go +++ b/api/worker.go @@ -526,7 +526,7 @@ func (w *Worker) GetBlock(bid string, page int, txsOnPage int) (*Block, error) { } // GetSystemInfo returns information about system -func (w *Worker) GetSystemInfo() (*SystemInfo, error) { +func (w *Worker) GetSystemInfo(internal bool) (*SystemInfo, error) { start := time.Now() ci, err := w.chain.GetChainInfo() if err != nil { @@ -534,20 +534,29 @@ func (w *Worker) GetSystemInfo() (*SystemInfo, error) { } vi := common.GetVersionInfo() ss, bh, st := w.is.GetSyncState() - ms, mt, _ := w.is.GetMempoolSyncState() + ms, mt, msz := w.is.GetMempoolSyncState() + var dbc []common.InternalStateColumn + var dbs int64 + if internal { + dbc = w.is.GetAllDBColumnStats() + dbs = w.is.DBSizeTotal() + } bi := &BlockbookInfo{ - Coin: w.is.Coin, - Host: w.is.Host, - Version: vi.Version, - GitCommit: vi.GitCommit, - BuildTime: vi.BuildTime, - InSync: ss, - BestHeight: bh, - LastBlockTime: st, - InSyncMempool: ms, - LastMempoolTime: mt, - About: BlockbookAbout, - DbSize: w.db.DatabaseSizeOnDisk(), + Coin: w.is.Coin, + Host: w.is.Host, + Version: vi.Version, + GitCommit: vi.GitCommit, + BuildTime: vi.BuildTime, + InSync: ss, + BestHeight: bh, + LastBlockTime: st, + InSyncMempool: ms, + LastMempoolTime: mt, + MempoolSize: msz, + DbSize: w.db.DatabaseSizeOnDisk(), + DbSizeFromColumns: dbs, + DbColumns: dbc, + About: BlockbookAbout, } glog.Info("GetSystemInfo finished in ", time.Since(start)) return &SystemInfo{bi, ci}, nil diff --git a/server/internal.go b/server/internal.go index a4752b86..a20eda1a 100644 --- a/server/internal.go +++ b/server/internal.go @@ -1,20 +1,17 @@ package server import ( + "blockbook/api" "blockbook/bchain" "blockbook/common" "blockbook/db" "context" "encoding/json" - "errors" "fmt" "net/http" - "strconv" - "time" "github.com/golang/glog" - "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -27,29 +24,21 @@ type InternalServer struct { chain bchain.BlockChain chainParser bchain.BlockChainParser is *common.InternalState -} - -type resAboutBlockbookInternal struct { - Coin string `json:"coin"` - Host string `json:"host"` - Version string `json:"version"` - GitCommit string `json:"gitcommit"` - BuildTime string `json:"buildtime"` - InSync bool `json:"inSync"` - BestHeight uint32 `json:"bestHeight"` - LastBlockTime time.Time `json:"lastBlockTime"` - InSyncMempool bool `json:"inSyncMempool"` - LastMempoolTime time.Time `json:"lastMempoolTime"` - MempoolSize int `json:"mempoolSize"` - DbColumns []common.InternalStateColumn `json:"dbColumns"` + api *api.Worker } // NewInternalServer creates new internal http interface to blockbook and returns its handle -func NewInternalServer(httpServerBinding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, is *common.InternalState) (*InternalServer, error) { - r := mux.NewRouter() +func NewInternalServer(binding, certFiles string, db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, is *common.InternalState) (*InternalServer, error) { + api, err := api.NewWorker(db, chain, txCache, is) + if err != nil { + return nil, err + } + + addr, path := splitBinding(binding) + serveMux := http.NewServeMux() https := &http.Server{ - Addr: httpServerBinding, - Handler: r, + Addr: addr, + Handler: serveMux, } s := &InternalServer{ https: https, @@ -59,15 +48,11 @@ func NewInternalServer(httpServerBinding string, certFiles string, db *db.RocksD chain: chain, chainParser: chain.GetChainParser(), is: is, + api: api, } - r.HandleFunc("/", s.index) - r.HandleFunc("/bestBlockHash", s.bestBlockHash) - r.HandleFunc("/blockHash/{height}", s.blockHash) - r.HandleFunc("/transactions/{address}/{lower}/{higher}", s.transactions) - r.HandleFunc("/confirmedTransactions/{address}/{lower}/{higher}", s.confirmedTransactions) - r.HandleFunc("/unconfirmedTransactions/{address}", s.unconfirmedTransactions) - r.HandleFunc("/metrics", promhttp.Handler().ServeHTTP) + serveMux.HandleFunc(path+"metrics", promhttp.Handler().ServeHTTP) + serveMux.HandleFunc(path, s.index) return s, nil } @@ -94,142 +79,11 @@ func (s *InternalServer) Shutdown(ctx context.Context) error { return s.https.Shutdown(ctx) } -func respondError(w http.ResponseWriter, err error, context string) { - w.WriteHeader(http.StatusBadRequest) - glog.Errorf("internal server: (context %s) error: %v", context, err) -} - -func respondHashData(w http.ResponseWriter, hash string) { - type hashData struct { - Hash string `json:"hash"` - } - json.NewEncoder(w).Encode(hashData{ - Hash: hash, - }) -} - func (s *InternalServer) index(w http.ResponseWriter, r *http.Request) { - vi := common.GetVersionInfo() - ss, bh, st := s.is.GetSyncState() - ms, mt, msz := s.is.GetMempoolSyncState() - a := resAboutBlockbookInternal{ - Coin: s.is.Coin, - Host: s.is.Host, - Version: vi.Version, - GitCommit: vi.GitCommit, - BuildTime: vi.BuildTime, - InSync: ss, - BestHeight: bh, - LastBlockTime: st, - InSyncMempool: ms, - LastMempoolTime: mt, - MempoolSize: msz, - DbColumns: s.is.GetAllDBColumnStats(), - } - buf, err := json.MarshalIndent(a, "", " ") + si, err := s.api.GetSystemInfo(true) + buf, err := json.MarshalIndent(si, "", " ") if err != nil { glog.Error(err) } w.Write(buf) } - -func (s *InternalServer) bestBlockHash(w http.ResponseWriter, r *http.Request) { - _, hash, err := s.db.GetBestBlock() - if err != nil { - respondError(w, err, "bestBlockHash") - return - } - respondHashData(w, hash) -} - -func (s *InternalServer) blockHash(w http.ResponseWriter, r *http.Request) { - heightString := mux.Vars(r)["height"] - var hash string - height, err := strconv.ParseUint(heightString, 10, 32) - if err == nil { - hash, err = s.db.GetBlockHash(uint32(height)) - } - if err != nil { - respondError(w, err, fmt.Sprintf("blockHash %s", heightString)) - } else { - respondHashData(w, hash) - } -} - -func (s *InternalServer) getAddress(r *http.Request) (address string, err error) { - address, ok := mux.Vars(r)["address"] - if !ok { - err = errors.New("Empty address") - } - return -} - -func (s *InternalServer) getAddressAndHeightRange(r *http.Request) (address string, lower, higher uint32, err error) { - address, err = s.getAddress(r) - if err != nil { - return - } - higher64, err := strconv.ParseUint(mux.Vars(r)["higher"], 10, 32) - if err != nil { - return - } - lower64, err := strconv.ParseUint(mux.Vars(r)["lower"], 10, 32) - if err != nil { - return - } - return address, uint32(lower64), uint32(higher64), err -} - -type transactionList struct { - Txid []string `json:"txid"` -} - -func (s *InternalServer) unconfirmedTransactions(w http.ResponseWriter, r *http.Request) { - address, err := s.getAddress(r) - if err != nil { - respondError(w, err, fmt.Sprint("unconfirmedTransactions for address", address)) - } - txs, err := s.chain.GetMempoolTransactions(address) - if err != nil { - respondError(w, err, fmt.Sprint("unconfirmedTransactions for address", address)) - } - txList := transactionList{Txid: txs} - json.NewEncoder(w).Encode(txList) -} - -func (s *InternalServer) confirmedTransactions(w http.ResponseWriter, r *http.Request) { - address, lower, higher, err := s.getAddressAndHeightRange(r) - if err != nil { - respondError(w, err, fmt.Sprint("confirmedTransactions for address", address)) - } - txList := transactionList{} - err = s.db.GetTransactions(address, lower, higher, func(txid string, vout uint32, isOutput bool) error { - txList.Txid = append(txList.Txid, txid) - return nil - }) - if err != nil { - respondError(w, err, fmt.Sprint("confirmedTransactions for address", address)) - } - json.NewEncoder(w).Encode(txList) -} - -func (s *InternalServer) transactions(w http.ResponseWriter, r *http.Request) { - address, lower, higher, err := s.getAddressAndHeightRange(r) - if err != nil { - respondError(w, err, fmt.Sprint("transactions for address", address)) - } - txList := transactionList{} - err = s.db.GetTransactions(address, lower, higher, func(txid string, vout uint32, isOutput bool) error { - txList.Txid = append(txList.Txid, txid) - return nil - }) - if err != nil { - respondError(w, err, fmt.Sprint("transactions for address", address)) - } - txs, err := s.chain.GetMempoolTransactions(address) - if err != nil { - respondError(w, err, fmt.Sprint("transactions for address", address)) - } - txList.Txid = append(txList.Txid, txs...) - json.NewEncoder(w).Encode(txList) -} diff --git a/server/public.go b/server/public.go index 302a2cf5..57ccd7c9 100644 --- a/server/public.go +++ b/server/public.go @@ -426,7 +426,7 @@ func (s *PublicServer) explorerIndex(w http.ResponseWriter, r *http.Request) (tp var si *api.SystemInfo var err error s.metrics.ExplorerViews.With(common.Labels{"action": "index"}).Inc() - si, err = s.api.GetSystemInfo() + si, err = s.api.GetSystemInfo(false) if err != nil { return errorTpl, nil, err } @@ -522,7 +522,7 @@ func getPagingRange(page int, total int) ([]int, int, int) { func (s *PublicServer) apiIndex(r *http.Request) (interface{}, error) { s.metrics.ExplorerViews.With(common.Labels{"action": "api-index"}).Inc() - return s.api.GetSystemInfo() + return s.api.GetSystemInfo(false) } func (s *PublicServer) apiBlockIndex(r *http.Request) (interface{}, error) {