From 9bd1b374a7b6679261c53911212a9621f1cb77bd Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Thu, 21 Jun 2018 15:37:46 +0200 Subject: [PATCH 01/16] Refactor https and socketio to internal and public interface --- blockbook.go | 51 ++++---- server/{https.go => internal.go} | 42 +++---- server/public.go | 207 +++++++++++++++++++++++++++++++ server/socketio.go | 158 +---------------------- 4 files changed, 257 insertions(+), 201 deletions(-) rename server/{https.go => internal.go} (79%) create mode 100644 server/public.go diff --git a/blockbook.go b/blockbook.go index 41fbfb34..8c4b7828 100644 --- a/blockbook.go +++ b/blockbook.go @@ -54,9 +54,9 @@ var ( syncWorkers = flag.Int("workers", 8, "number of workers to process blocks") dryRun = flag.Bool("dryrun", false, "do not index blocks, only download") - httpServerBinding = flag.String("httpserver", "", "http server binding [address]:port, (default no http server)") + internalBinding = flag.String("httpserver", "", "http server binding [address]:port, (default no http server)") - socketIoBinding = flag.String("socketio", "", "socketio server binding [address]:port[/path], (default no socket.io server)") + publicBinding = flag.String("socketio", "", "socketio server binding [address]:port[/path], (default no socket.io server)") certFiles = flag.String("certfile", "", "to enable SSL specify path to certificate files without extension, expecting .crt and .key, (default no SSL)") @@ -232,18 +232,18 @@ func main() { return } - var httpServer *server.HTTPServer - if *httpServerBinding != "" { - httpServer, err = server.NewHTTPServer(*httpServerBinding, *certFiles, index, chain, txCache, internalState) + var internalServer *server.InternalServer + if *internalBinding != "" { + internalServer, err = server.NewInternalServer(*internalBinding, *certFiles, index, chain, txCache, internalState) if err != nil { glog.Error("https: ", err) return } go func() { - err = httpServer.Run() + err = internalServer.Run() if err != nil { if err.Error() == "http: Server closed" { - glog.Info(err) + glog.Info("internal server: closed") } else { glog.Error(err) return @@ -263,27 +263,26 @@ func main() { } } - var socketIoServer *server.SocketIoServer - if *socketIoBinding != "" { - socketIoServer, err = server.NewSocketIoServer( - *socketIoBinding, *certFiles, index, chain, txCache, *explorerURL, metrics, internalState) + var publicServer *server.PublicServer + if *publicBinding != "" { + publicServer, err = server.NewPublicServer(*publicBinding, *certFiles, index, chain, txCache, *explorerURL, metrics, internalState) if err != nil { glog.Error("socketio: ", err) return } go func() { - err = socketIoServer.Run() + err = publicServer.Run() if err != nil { if err.Error() == "http: Server closed" { - glog.Info(err) + glog.Info("public server: closed") } else { glog.Error(err) return } } }() - callbacksOnNewBlockHash = append(callbacksOnNewBlockHash, socketIoServer.OnNewBlockHash) - callbacksOnNewTxAddr = append(callbacksOnNewTxAddr, socketIoServer.OnNewTxAddr) + callbacksOnNewBlockHash = append(callbacksOnNewBlockHash, publicServer.OnNewBlockHash) + callbacksOnNewTxAddr = append(callbacksOnNewTxAddr, publicServer.OnNewTxAddr) } if *synchronize { @@ -314,8 +313,8 @@ func main() { } } - if httpServer != nil || socketIoServer != nil || chain != nil { - waitForSignalAndShutdown(httpServer, socketIoServer, chain, 10*time.Second) + if internalServer != nil || publicServer != nil || chain != nil { + waitForSignalAndShutdown(internalServer, publicServer, chain, 10*time.Second) } if *synchronize { @@ -464,29 +463,29 @@ func pushSynchronizationHandler(nt bchain.NotificationType) { } } -func waitForSignalAndShutdown(https *server.HTTPServer, socketio *server.SocketIoServer, chain bchain.BlockChain, timeout time.Duration) { +func waitForSignalAndShutdown(internal *server.InternalServer, public *server.PublicServer, chain bchain.BlockChain, timeout time.Duration) { sig := <-chanOsSignal atomic.StoreInt32(&inShutdown, 1) - glog.Infof("Shutdown: %v", sig) + glog.Infof("shutdown: %v", sig) ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - if https != nil { - if err := https.Shutdown(ctx); err != nil { - glog.Error("HttpServer.Shutdown error: ", err) + if internal != nil { + if err := internal.Shutdown(ctx); err != nil { + glog.Error("internal server: shutdown error: ", err) } } - if socketio != nil { - if err := socketio.Shutdown(ctx); err != nil { - glog.Error("SocketIo.Shutdown error: ", err) + if public != nil { + if err := public.Shutdown(ctx); err != nil { + glog.Error("public server: shutdown error: ", err) } } if chain != nil { if err := chain.Shutdown(ctx); err != nil { - glog.Error("BlockChain.Shutdown error: ", err) + glog.Error("rpc: shutdown error: ", err) } } } diff --git a/server/https.go b/server/internal.go similarity index 79% rename from server/https.go rename to server/internal.go index 0af9c3a1..a4752b86 100644 --- a/server/https.go +++ b/server/internal.go @@ -18,8 +18,8 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" ) -// HTTPServer is handle to HttpServer -type HTTPServer struct { +// InternalServer is handle to internal http server +type InternalServer struct { https *http.Server certFiles string db *db.RocksDB @@ -44,14 +44,14 @@ type resAboutBlockbookInternal struct { DbColumns []common.InternalStateColumn `json:"dbColumns"` } -// NewHTTPServer creates new REST interface to blockbook and returns its handle -func NewHTTPServer(httpServerBinding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, is *common.InternalState) (*HTTPServer, error) { +// 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() https := &http.Server{ Addr: httpServerBinding, Handler: r, } - s := &HTTPServer{ + s := &InternalServer{ https: https, certFiles: certFiles, db: db, @@ -73,30 +73,30 @@ func NewHTTPServer(httpServerBinding string, certFiles string, db *db.RocksDB, c } // Run starts the server -func (s *HTTPServer) Run() error { +func (s *InternalServer) Run() error { if s.certFiles == "" { - glog.Info("http server starting to listen on http://", s.https.Addr) + glog.Info("internal server: starting to listen on http://", s.https.Addr) return s.https.ListenAndServe() } - glog.Info("http server starting to listen on https://", s.https.Addr) + glog.Info("internal server: starting to listen on https://", s.https.Addr) return s.https.ListenAndServeTLS(fmt.Sprint(s.certFiles, ".crt"), fmt.Sprint(s.certFiles, ".key")) } // Close closes the server -func (s *HTTPServer) Close() error { - glog.Infof("http server closing") +func (s *InternalServer) Close() error { + glog.Infof("internal server: closing") return s.https.Close() } // Shutdown shuts down the server -func (s *HTTPServer) Shutdown(ctx context.Context) error { - glog.Infof("http server shutdown") +func (s *InternalServer) Shutdown(ctx context.Context) error { + glog.Infof("internal server: shutdown") return s.https.Shutdown(ctx) } func respondError(w http.ResponseWriter, err error, context string) { w.WriteHeader(http.StatusBadRequest) - glog.Errorf("http server (context %s) error: %v", context, err) + glog.Errorf("internal server: (context %s) error: %v", context, err) } func respondHashData(w http.ResponseWriter, hash string) { @@ -108,7 +108,7 @@ func respondHashData(w http.ResponseWriter, hash string) { }) } -func (s *HTTPServer) index(w http.ResponseWriter, r *http.Request) { +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() @@ -133,7 +133,7 @@ func (s *HTTPServer) index(w http.ResponseWriter, r *http.Request) { w.Write(buf) } -func (s *HTTPServer) bestBlockHash(w http.ResponseWriter, r *http.Request) { +func (s *InternalServer) bestBlockHash(w http.ResponseWriter, r *http.Request) { _, hash, err := s.db.GetBestBlock() if err != nil { respondError(w, err, "bestBlockHash") @@ -142,7 +142,7 @@ func (s *HTTPServer) bestBlockHash(w http.ResponseWriter, r *http.Request) { respondHashData(w, hash) } -func (s *HTTPServer) blockHash(w http.ResponseWriter, r *http.Request) { +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) @@ -156,7 +156,7 @@ func (s *HTTPServer) blockHash(w http.ResponseWriter, r *http.Request) { } } -func (s *HTTPServer) getAddress(r *http.Request) (address string, err error) { +func (s *InternalServer) getAddress(r *http.Request) (address string, err error) { address, ok := mux.Vars(r)["address"] if !ok { err = errors.New("Empty address") @@ -164,7 +164,7 @@ func (s *HTTPServer) getAddress(r *http.Request) (address string, err error) { return } -func (s *HTTPServer) getAddressAndHeightRange(r *http.Request) (address string, lower, higher uint32, err error) { +func (s *InternalServer) getAddressAndHeightRange(r *http.Request) (address string, lower, higher uint32, err error) { address, err = s.getAddress(r) if err != nil { return @@ -184,7 +184,7 @@ type transactionList struct { Txid []string `json:"txid"` } -func (s *HTTPServer) unconfirmedTransactions(w http.ResponseWriter, r *http.Request) { +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)) @@ -197,7 +197,7 @@ func (s *HTTPServer) unconfirmedTransactions(w http.ResponseWriter, r *http.Requ json.NewEncoder(w).Encode(txList) } -func (s *HTTPServer) confirmedTransactions(w http.ResponseWriter, r *http.Request) { +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)) @@ -213,7 +213,7 @@ func (s *HTTPServer) confirmedTransactions(w http.ResponseWriter, r *http.Reques json.NewEncoder(w).Encode(txList) } -func (s *HTTPServer) transactions(w http.ResponseWriter, r *http.Request) { +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)) diff --git a/server/public.go b/server/public.go new file mode 100644 index 00000000..f52da14a --- /dev/null +++ b/server/public.go @@ -0,0 +1,207 @@ +package server + +import ( + "blockbook/bchain" + "blockbook/common" + "blockbook/db" + "context" + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + "github.com/golang/glog" +) + +const blockbookAbout = "Blockbook - blockchain indexer for TREZOR wallet https://trezor.io/. Do not use for any other purpose." + +// PublicServer is handle to public http server +type PublicServer struct { + binding string + certFiles string + socketio *SocketIoServer + https *http.Server + db *db.RocksDB + txCache *db.TxCache + chain bchain.BlockChain + chainParser bchain.BlockChainParser + explorerURL string + metrics *common.Metrics + is *common.InternalState +} + +// NewPublicServerS creates new public server http interface to blockbook and returns its handle +func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, explorerURL string, metrics *common.Metrics, is *common.InternalState) (*PublicServer, error) { + + socketio, err := NewSocketIoServer(db, chain, txCache, metrics, is) + if err != nil { + return nil, err + } + + addr, path := splitBinding(binding) + serveMux := http.NewServeMux() + https := &http.Server{ + Addr: addr, + Handler: serveMux, + } + + s := &PublicServer{ + binding: binding, + certFiles: certFiles, + https: https, + socketio: socketio, + db: db, + txCache: txCache, + chain: chain, + chainParser: chain.GetChainParser(), + explorerURL: explorerURL, + metrics: metrics, + is: is, + } + + // support for tests of socket.io interface + serveMux.Handle(path+"test.html", http.FileServer(http.Dir("./static/"))) + // redirect to Bitcore for details of transaction + serveMux.HandleFunc(path+"tx/", s.txRedirect) + serveMux.HandleFunc(path+"address/", s.addressRedirect) + // API call used to detect state of Blockbook + serveMux.HandleFunc(path+"api/block-index/", s.apiBlockIndex) + // handle socket.io + serveMux.Handle(path+"socket.io/", socketio.GetHandler()) + // default handler + serveMux.HandleFunc(path, s.index) + return s, nil +} + +// Run starts the server +func (s *PublicServer) Run() error { + if s.certFiles == "" { + glog.Info("public server: starting to listen on http://", s.https.Addr) + return s.https.ListenAndServe() + } + glog.Info("public server starting to listen on https://", s.https.Addr) + return s.https.ListenAndServeTLS(fmt.Sprint(s.certFiles, ".crt"), fmt.Sprint(s.certFiles, ".key")) +} + +// Close closes the server +func (s *PublicServer) Close() error { + glog.Infof("public server: closing") + return s.https.Close() +} + +// Shutdown shuts down the server +func (s *PublicServer) Shutdown(ctx context.Context) error { + glog.Infof("public server: shutdown") + return s.https.Shutdown(ctx) +} + +// OnNewBlockHash notifies users subscribed to bitcoind/hashblock about new block +func (s *PublicServer) OnNewBlockHash(hash string) { + s.socketio.OnNewBlockHash(hash) +} + +// OnNewTxAddr notifies users subscribed to bitcoind/addresstxid about new block +func (s *PublicServer) OnNewTxAddr(txid string, addr string) { + s.socketio.OnNewTxAddr(txid, addr) +} + +func splitBinding(binding string) (addr string, path string) { + i := strings.Index(binding, "/") + if i >= 0 { + return binding[0:i], binding[i:] + } + return binding, "/" +} + +func joinURL(base string, part string) string { + if len(base) > 0 { + if len(base) > 0 && base[len(base)-1] == '/' && len(part) > 0 && part[0] == '/' { + return base + part[1:] + } + return base + part + } + return part +} + +func (s *PublicServer) txRedirect(w http.ResponseWriter, r *http.Request) { + if s.explorerURL != "" { + http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302) + s.metrics.ExplorerViews.With(common.Labels{"action": "tx"}).Inc() + } +} + +func (s *PublicServer) addressRedirect(w http.ResponseWriter, r *http.Request) { + if s.explorerURL != "" { + http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302) + s.metrics.ExplorerViews.With(common.Labels{"action": "address"}).Inc() + } +} + +type resAboutBlockbookPublic 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"` + About string `json:"about"` +} + +func (s *PublicServer) index(w http.ResponseWriter, r *http.Request) { + vi := common.GetVersionInfo() + ss, bh, st := s.is.GetSyncState() + ms, mt, _ := s.is.GetMempoolSyncState() + a := resAboutBlockbookPublic{ + 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, + About: blockbookAbout, + } + buf, err := json.MarshalIndent(a, "", " ") + if err != nil { + glog.Error(err) + } + w.Write(buf) +} + +func (s *PublicServer) apiBlockIndex(w http.ResponseWriter, r *http.Request) { + type resBlockIndex struct { + BlockHash string `json:"blockHash"` + About string `json:"about"` + } + var err error + var hash string + height := -1 + if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 { + if h, err := strconv.Atoi(r.URL.Path[i+1:]); err == nil { + height = h + } + } + if height >= 0 { + hash, err = s.db.GetBlockHash(uint32(height)) + } else { + _, hash, err = s.db.GetBestBlock() + } + if err != nil { + glog.Error(err) + } else { + r := resBlockIndex{ + BlockHash: hash, + About: blockbookAbout, + } + json.NewEncoder(w).Encode(r) + } +} diff --git a/server/socketio.go b/server/socketio.go index eedda503..14293f48 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -4,11 +4,8 @@ import ( "blockbook/bchain" "blockbook/common" "blockbook/db" - "context" "encoding/json" - "fmt" "net/http" - "strconv" "strings" "time" @@ -19,25 +16,19 @@ import ( "github.com/martinboehm/golang-socketio/transport" ) -const blockbookAbout = "Blockbook - blockchain indexer for TREZOR wallet https://trezor.io/. Do not use for any other purpose." - // SocketIoServer is handle to SocketIoServer type SocketIoServer struct { - binding string - certFiles string server *gosocketio.Server - https *http.Server db *db.RocksDB txCache *db.TxCache chain bchain.BlockChain chainParser bchain.BlockChainParser - explorerURL string metrics *common.Metrics is *common.InternalState } // NewSocketIoServer creates new SocketIo interface to blockbook and returns its handle -func NewSocketIoServer(binding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, explorerURL string, metrics *common.Metrics, is *common.InternalState) (*SocketIoServer, error) { +func NewSocketIoServer(db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, metrics *common.Metrics, is *common.InternalState) (*SocketIoServer, error) { server := gosocketio.NewServer(transport.GetDefaultWebsocketTransport()) server.On(gosocketio.OnConnection, func(c *gosocketio.Channel) { @@ -58,166 +49,25 @@ func NewSocketIoServer(binding string, certFiles string, db *db.RocksDB, chain b Name string `json:"name"` Message string `json:"message"` } - - addr, path := splitBinding(binding) - serveMux := http.NewServeMux() - https := &http.Server{ - Addr: addr, - Handler: serveMux, - } - s := &SocketIoServer{ - binding: binding, - certFiles: certFiles, - https: https, server: server, db: db, txCache: txCache, chain: chain, chainParser: chain.GetChainParser(), - explorerURL: explorerURL, metrics: metrics, is: is, } - // support for tests of socket.io interface - serveMux.Handle(path+"test.html", http.FileServer(http.Dir("./static/"))) - // redirect to Bitcore for details of transaction - serveMux.HandleFunc(path+"tx/", s.txRedirect) - serveMux.HandleFunc(path+"address/", s.addressRedirect) - // API call used to detect state of Blockbook - serveMux.HandleFunc(path+"api/block-index/", s.apiBlockIndex) - // handle socket.io - serveMux.Handle(path+"socket.io/", server) - // default handler - serveMux.HandleFunc(path, s.index) - server.On("message", s.onMessage) server.On("subscribe", s.onSubscribe) return s, nil } -func splitBinding(binding string) (addr string, path string) { - i := strings.Index(binding, "/") - if i >= 0 { - return binding[0:i], binding[i:] - } - return binding, "/" -} - -// Run starts the server -func (s *SocketIoServer) Run() error { - if s.certFiles == "" { - glog.Info("socketio server starting to listen on ws://", s.https.Addr) - return s.https.ListenAndServe() - } - glog.Info("socketio server starting to listen on wss://", s.https.Addr) - return s.https.ListenAndServeTLS(fmt.Sprint(s.certFiles, ".crt"), fmt.Sprint(s.certFiles, ".key")) -} - -// Close closes the server -func (s *SocketIoServer) Close() error { - glog.Infof("socketio server closing") - return s.https.Close() -} - -// Shutdown shuts down the server -func (s *SocketIoServer) Shutdown(ctx context.Context) error { - glog.Infof("socketio server shutdown") - return s.https.Shutdown(ctx) -} - -func joinURL(base string, part string) string { - if len(base) > 0 { - if len(base) > 0 && base[len(base)-1] == '/' && len(part) > 0 && part[0] == '/' { - return base + part[1:] - } else { - return base + part - } - } - return part -} - -func (s *SocketIoServer) txRedirect(w http.ResponseWriter, r *http.Request) { - if s.explorerURL != "" { - http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302) - s.metrics.ExplorerViews.With(common.Labels{"action": "tx"}).Inc() - } -} - -func (s *SocketIoServer) addressRedirect(w http.ResponseWriter, r *http.Request) { - if s.explorerURL != "" { - http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302) - s.metrics.ExplorerViews.With(common.Labels{"action": "address"}).Inc() - } -} - -type resAboutBlockbookPublic 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"` - About string `json:"about"` -} - -func (s *SocketIoServer) index(w http.ResponseWriter, r *http.Request) { - vi := common.GetVersionInfo() - ss, bh, st := s.is.GetSyncState() - ms, mt, _ := s.is.GetMempoolSyncState() - a := resAboutBlockbookPublic{ - 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, - About: blockbookAbout, - } - buf, err := json.MarshalIndent(a, "", " ") - if err != nil { - glog.Error(err) - } - w.Write(buf) -} - -func (s *SocketIoServer) apiBlockIndex(w http.ResponseWriter, r *http.Request) { - type resBlockIndex struct { - BlockHash string `json:"blockHash"` - About string `json:"about"` - } - var err error - var hash string - height := -1 - if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 { - if h, err := strconv.Atoi(r.URL.Path[i+1:]); err == nil { - height = h - } - } - if height >= 0 { - hash, err = s.db.GetBlockHash(uint32(height)) - } else { - _, hash, err = s.db.GetBestBlock() - } - if err != nil { - glog.Error(err) - } else { - r := resBlockIndex{ - BlockHash: hash, - About: blockbookAbout, - } - json.NewEncoder(w).Encode(r) - } +// GetHandler returns socket.io http handler +func (s *SocketIoServer) GetHandler() http.Handler { + return s.server } type addrOpts struct { From 278b18a37fd719c4c199e38e353b3d954098d6ef Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Thu, 21 Jun 2018 15:42:21 +0200 Subject: [PATCH 02/16] Rename httpserver and socketio flags to internal and public --- README.md | 2 +- bchain/coins/btc/btc.md | 2 +- bchain/coins/btc/btctestnet.md | 2 +- bchain/coins/eth/eth.md | 2 +- bchain/coins/eth/ethropsten.md | 2 +- bchain/coins/zec/zec.md | 2 +- blockbook.go | 4 ++-- build/deb/debian/blockbook-bcash-testnet.service | 2 +- build/deb/debian/blockbook-bcash.service | 2 +- build/deb/debian/blockbook-bgold.service | 2 +- build/deb/debian/blockbook-bitcoin-testnet.service | 2 +- build/deb/debian/blockbook-bitcoin.service | 2 +- build/deb/debian/blockbook-dash-testnet.service | 2 +- build/deb/debian/blockbook-dash.service | 2 +- build/deb/debian/blockbook-dogecoin.service | 2 +- build/deb/debian/blockbook-ethereum-testnet-ropsten.service | 2 +- build/deb/debian/blockbook-ethereum.service | 2 +- build/deb/debian/blockbook-litecoin-testnet.service | 2 +- build/deb/debian/blockbook-litecoin.service | 2 +- build/deb/debian/blockbook-namecoin.service | 2 +- build/deb/debian/blockbook-zcash-testnet.service | 2 +- build/deb/debian/blockbook-zcash.service | 2 +- 22 files changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 586f43e8..6cbacaa6 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ go build ## Example command To run blockbook with fast synchronization, connection to ZeroMQ and providing https and socket.io interface, with database in local directory *data* and connected to local bitcoind with configuration specified by parameter *-blockchaincfg*: ``` -./blockbook -sync -blockchaincfg=configs/bitcoin_testnet.json -httpserver=127.0.0.1:8333 -socketio=127.0.01:8334 -certfile=server/testcert -logtostderr +./blockbook -sync -blockchaincfg=configs/bitcoin_testnet.json -internal=127.0.0.1:8333 -public=127.0.01:8334 -certfile=server/testcert -logtostderr ``` Blockbook logs to stderr *-logtostderr* or to directory specified by parameter *-log_dir* . Verbosity of logs can be tuned by command line parameters *-v* and *-vmodule*, details at https://godoc.org/github.com/golang/glog diff --git a/bchain/coins/btc/btc.md b/bchain/coins/btc/btc.md index f6770962..2be2fdd7 100644 --- a/bchain/coins/btc/btc.md +++ b/bchain/coins/btc/btc.md @@ -41,7 +41,7 @@ Create script that runs blockbook *run-btc-blockbook.sh* #!/bin/bash cd go/src/blockbook -./blockbook -coin=btc -blockchaincfg=/data/btc/blockbook/btc.json -datadir=/data/btc/blockbook/db -sync -httpserver=:9030 -socketio=:9130 -certfile=server/testcert -explorer=https://bitcore1.trezor.io/ $1 +./blockbook -coin=btc -blockchaincfg=/data/btc/blockbook/btc.json -datadir=/data/btc/blockbook/db -sync -internal=:9030 -public=:9130 -certfile=server/testcert -explorer=https://bitcore1.trezor.io/ $1 ``` To run blockbook with logging to file (run with nohup or daemonize or using screen) ``` diff --git a/bchain/coins/btc/btctestnet.md b/bchain/coins/btc/btctestnet.md index c2543ca9..bbb59ac0 100644 --- a/bchain/coins/btc/btctestnet.md +++ b/bchain/coins/btc/btctestnet.md @@ -41,7 +41,7 @@ Create script that runs blockbook *run-testnet-blockbook.sh* #!/bin/bash cd go/src/blockbook -./blockbook -coin=btc-testnet -blockchaincfg=/data/testnet/blockbook/btc-testnet.json -datadir=/data/testnet/blockbook/db -sync -httpserver=:19030 -socketio=:19130 -certfile=server/testcert -explorer=https://testnet-bitcore1.trezor.io $1 +./blockbook -coin=btc-testnet -blockchaincfg=/data/testnet/blockbook/btc-testnet.json -datadir=/data/testnet/blockbook/db -sync -internal=:19030 -public=:19130 -certfile=server/testcert -explorer=https://testnet-bitcore1.trezor.io $1 ``` To run blockbook with logging to file (run with nohup or daemonize or using screen) ``` diff --git a/bchain/coins/eth/eth.md b/bchain/coins/eth/eth.md index 16fb3ba0..1db56280 100644 --- a/bchain/coins/eth/eth.md +++ b/bchain/coins/eth/eth.md @@ -17,7 +17,7 @@ Create script that runs blockbook *run-eth-blockbook.sh* #!/bin/bash cd go/src/blockbook -./blockbook -coin=eth -blockchaincfg=/data/eth/blockbook/eth.json -datadir=/data/eth/blockbook/db -sync -httpserver=:8555 -socketio=:8556 -certfile=server/testcert $1 +./blockbook -coin=eth -blockchaincfg=/data/eth/blockbook/eth.json -datadir=/data/eth/blockbook/db -sync -internal=:8555 -public=:8556 -certfile=server/testcert $1 ``` To run blockbook with logging to file (run with nohup or daemonize or using screen) ``` diff --git a/bchain/coins/eth/ethropsten.md b/bchain/coins/eth/ethropsten.md index 604bc220..0e4bb161 100644 --- a/bchain/coins/eth/ethropsten.md +++ b/bchain/coins/eth/ethropsten.md @@ -17,7 +17,7 @@ Create script that runs blockbook *run-eth-testnet-blockbook.sh* #!/bin/bash cd go/src/blockbook -./blockbook -coin=eth-testnet -blockchaincfg=/data/eth-testnet/blockbook/eth-testnet.json -datadir=/data/eth-testnet/blockbook/db -sync -httpserver=:18555 -socketio=:18556 -certfile=server/testcert $1 +./blockbook -coin=eth-testnet -blockchaincfg=/data/eth-testnet/blockbook/eth-testnet.json -datadir=/data/eth-testnet/blockbook/db -sync -internal=:18555 -public=:18556 -certfile=server/testcert $1 ``` To run blockbook with logging to file (run with nohup or daemonize or using screen) ``` diff --git a/bchain/coins/zec/zec.md b/bchain/coins/zec/zec.md index 22c96687..e7cf690d 100644 --- a/bchain/coins/zec/zec.md +++ b/bchain/coins/zec/zec.md @@ -48,7 +48,7 @@ Create blockchain configuration file */data/zec/blockbook/zec.json* Create *run-zec-blockbook.sh* script that starts blockbook ``` #!/bin/bash -./blockbook -coin=zec -blockchaincfg=/data/zec/blockbook/zec.json -datadir=/data/zec/blockbook/db -sync -httpserver=:9032 -socketio=:9132 -certfile=server/testcert -explorer=https://zec-bitcore1.trezor.io $1 +./blockbook -coin=zec -blockchaincfg=/data/zec/blockbook/zec.json -datadir=/data/zec/blockbook/db -sync -internal=:9032 -public=:9132 -certfile=server/testcert -explorer=https://zec-bitcore1.trezor.io $1 ``` To run blockbook with logging to file (run with nohup or daemonize using screen) diff --git a/blockbook.go b/blockbook.go index 8c4b7828..f10c1b2f 100644 --- a/blockbook.go +++ b/blockbook.go @@ -54,9 +54,9 @@ var ( syncWorkers = flag.Int("workers", 8, "number of workers to process blocks") dryRun = flag.Bool("dryrun", false, "do not index blocks, only download") - internalBinding = flag.String("httpserver", "", "http server binding [address]:port, (default no http server)") + internalBinding = flag.String("internal", "", "internal http server binding [address]:port, (default no internal server)") - publicBinding = flag.String("socketio", "", "socketio server binding [address]:port[/path], (default no socket.io server)") + publicBinding = flag.String("public", "", "public http server binding [address]:port[/path], (default no public server)") certFiles = flag.String("certfile", "", "to enable SSL specify path to certificate files without extension, expecting .crt and .key, (default no SSL)") diff --git a/build/deb/debian/blockbook-bcash-testnet.service b/build/deb/debian/blockbook-bcash-testnet.service index bf662598..165fe74c 100644 --- a/build/deb/debian/blockbook-bcash-testnet.service +++ b/build/deb/debian/blockbook-bcash-testnet.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-bcash-testnet.service [Service] -ExecStart=/opt/coins/blockbook/bcash_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bcash_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/bcash_testnet/blockbook/db -sync -httpserver=:19031 -socketio=:19131 -certfile=/opt/coins/blockbook/bcash_testnet/cert/blockbook -explorer=https://bitcoincash.blockexplorer.com/ -log_dir=/opt/coins/blockbook/bcash_testnet/logs +ExecStart=/opt/coins/blockbook/bcash_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bcash_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/bcash_testnet/blockbook/db -sync -internal=:19031 -public=:19131 -certfile=/opt/coins/blockbook/bcash_testnet/cert/blockbook -explorer=https://bitcoincash.blockexplorer.com/ -log_dir=/opt/coins/blockbook/bcash_testnet/logs User=blockbook-bcash Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-bcash.service b/build/deb/debian/blockbook-bcash.service index 0dc29e39..6c2121a5 100644 --- a/build/deb/debian/blockbook-bcash.service +++ b/build/deb/debian/blockbook-bcash.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-bcash.service [Service] -ExecStart=/opt/coins/blockbook/bcash/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bcash/config/blockchaincfg.json -datadir=/opt/coins/data/bcash/blockbook/db -sync -httpserver=:9031 -socketio=:9131 -certfile=/opt/coins/blockbook/bcash/cert/blockbook -explorer=https://bitcoincash.blockexplorer.com/ -log_dir=/opt/coins/blockbook/bcash/logs +ExecStart=/opt/coins/blockbook/bcash/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bcash/config/blockchaincfg.json -datadir=/opt/coins/data/bcash/blockbook/db -sync -internal=:9031 -public=:9131 -certfile=/opt/coins/blockbook/bcash/cert/blockbook -explorer=https://bitcoincash.blockexplorer.com/ -log_dir=/opt/coins/blockbook/bcash/logs User=blockbook-bcash Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-bgold.service b/build/deb/debian/blockbook-bgold.service index 24c0db1e..f740d32e 100644 --- a/build/deb/debian/blockbook-bgold.service +++ b/build/deb/debian/blockbook-bgold.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-bgold.service [Service] -ExecStart=/opt/coins/blockbook/bgold/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bgold/config/blockchaincfg.json -datadir=/opt/coins/data/bgold/blockbook/db -sync -httpserver=:9035 -socketio=:9135 -certfile=/opt/coins/blockbook/bgold/cert/blockbook -explorer=https://btg-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/bgold/logs +ExecStart=/opt/coins/blockbook/bgold/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bgold/config/blockchaincfg.json -datadir=/opt/coins/data/bgold/blockbook/db -sync -internal=:9035 -public=:9135 -certfile=/opt/coins/blockbook/bgold/cert/blockbook -explorer=https://btg-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/bgold/logs User=blockbook-bgold Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-bitcoin-testnet.service b/build/deb/debian/blockbook-bitcoin-testnet.service index a9de2f1b..f81e05e0 100644 --- a/build/deb/debian/blockbook-bitcoin-testnet.service +++ b/build/deb/debian/blockbook-bitcoin-testnet.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-bitcoin-testnet.service [Service] -ExecStart=/opt/coins/blockbook/bitcoin_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bitcoin_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/bitcoin_testnet/blockbook/db -sync -httpserver=:19030 -socketio=:19130 -certfile=/opt/coins/blockbook/bitcoin_testnet/cert/blockbook -explorer=https://btc-testnet-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/bitcoin_testnet/logs +ExecStart=/opt/coins/blockbook/bitcoin_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bitcoin_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/bitcoin_testnet/blockbook/db -sync -internal=:19030 -public=:19130 -certfile=/opt/coins/blockbook/bitcoin_testnet/cert/blockbook -explorer=https://btc-testnet-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/bitcoin_testnet/logs User=blockbook-bitcoin Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-bitcoin.service b/build/deb/debian/blockbook-bitcoin.service index 1da3f0fe..019ecaad 100644 --- a/build/deb/debian/blockbook-bitcoin.service +++ b/build/deb/debian/blockbook-bitcoin.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-bitcoin.service [Service] -ExecStart=/opt/coins/blockbook/bitcoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bitcoin/config/blockchaincfg.json -datadir=/opt/coins/data/bitcoin/blockbook/db -sync -httpserver=:9030 -socketio=:9130 -certfile=/opt/coins/blockbook/bitcoin/cert/blockbook -explorer=https://btc-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/bitcoin/logs +ExecStart=/opt/coins/blockbook/bitcoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/bitcoin/config/blockchaincfg.json -datadir=/opt/coins/data/bitcoin/blockbook/db -sync -internal=:9030 -public=:9130 -certfile=/opt/coins/blockbook/bitcoin/cert/blockbook -explorer=https://btc-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/bitcoin/logs User=blockbook-bitcoin Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-dash-testnet.service b/build/deb/debian/blockbook-dash-testnet.service index 5f3eb719..45f0e3b6 100644 --- a/build/deb/debian/blockbook-dash-testnet.service +++ b/build/deb/debian/blockbook-dash-testnet.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-dash-testnet.service [Service] -ExecStart=/opt/coins/blockbook/dash_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/dash_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/dash_testnet/blockbook/db -sync -httpserver=:19033 -socketio=:19133 -certfile=/opt/coins/blockbook/dash_testnet/cert/blockbook -explorer=https://dash-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/dash_testnet/logs +ExecStart=/opt/coins/blockbook/dash_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/dash_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/dash_testnet/blockbook/db -sync -internal=:19033 -public=:19133 -certfile=/opt/coins/blockbook/dash_testnet/cert/blockbook -explorer=https://dash-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/dash_testnet/logs User=blockbook-dash Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-dash.service b/build/deb/debian/blockbook-dash.service index f4838f63..7bc2936f 100644 --- a/build/deb/debian/blockbook-dash.service +++ b/build/deb/debian/blockbook-dash.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-dash.service [Service] -ExecStart=/opt/coins/blockbook/dash/bin/blockbook -blockchaincfg=/opt/coins/blockbook/dash/config/blockchaincfg.json -datadir=/opt/coins/data/dash/blockbook/db -sync -httpserver=:9033 -socketio=:9133 -certfile=/opt/coins/blockbook/dash/cert/blockbook -explorer=https://dash-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/dash/logs +ExecStart=/opt/coins/blockbook/dash/bin/blockbook -blockchaincfg=/opt/coins/blockbook/dash/config/blockchaincfg.json -datadir=/opt/coins/data/dash/blockbook/db -sync -internal=:9033 -public=:9133 -certfile=/opt/coins/blockbook/dash/cert/blockbook -explorer=https://dash-explorer.trezor.io/ -log_dir=/opt/coins/blockbook/dash/logs User=blockbook-dash Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-dogecoin.service b/build/deb/debian/blockbook-dogecoin.service index 00d2dd19..00f7c647 100644 --- a/build/deb/debian/blockbook-dogecoin.service +++ b/build/deb/debian/blockbook-dogecoin.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-dogecoin.service [Service] -ExecStart=/opt/coins/blockbook/dogecoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/dogecoin/config/blockchaincfg.json -datadir=/opt/coins/data/dogecoin/blockbook/db -sync -httpserver=:9038 -socketio=:9138 -certfile=/opt/coins/blockbook/dogecoin/cert/blockbook -explorer=https://dogechain.info/ -resyncindexperiod=30011 -resyncmempoolperiod=2011 -log_dir=/opt/coins/blockbook/dogecoin/logs +ExecStart=/opt/coins/blockbook/dogecoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/dogecoin/config/blockchaincfg.json -datadir=/opt/coins/data/dogecoin/blockbook/db -sync -internal=:9038 -public=:9138 -certfile=/opt/coins/blockbook/dogecoin/cert/blockbook -explorer=https://dogechain.info/ -resyncindexperiod=30011 -resyncmempoolperiod=2011 -log_dir=/opt/coins/blockbook/dogecoin/logs User=blockbook-dogecoin Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-ethereum-testnet-ropsten.service b/build/deb/debian/blockbook-ethereum-testnet-ropsten.service index 9769553d..35c9f45f 100644 --- a/build/deb/debian/blockbook-ethereum-testnet-ropsten.service +++ b/build/deb/debian/blockbook-ethereum-testnet-ropsten.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-ethereum-testnet-ropsten.service [Service] -ExecStart=/opt/coins/blockbook/ethereum_testnet_ropsten/bin/blockbook -blockchaincfg=/opt/coins/blockbook/ethereum_testnet_ropsten/config/blockchaincfg.json -datadir=/opt/coins/data/ethereum_testnet_ropsten/blockbook/db -sync -httpserver=:19036 -socketio=:19136 -certfile=/opt/coins/blockbook/ethereum_testnet_ropsten/cert/blockbook -explorer=https://ropsten.etherscan.io/ -log_dir=/opt/coins/blockbook/ethereum_testnet_ropsten/logs +ExecStart=/opt/coins/blockbook/ethereum_testnet_ropsten/bin/blockbook -blockchaincfg=/opt/coins/blockbook/ethereum_testnet_ropsten/config/blockchaincfg.json -datadir=/opt/coins/data/ethereum_testnet_ropsten/blockbook/db -sync -internal=:19036 -public=:19136 -certfile=/opt/coins/blockbook/ethereum_testnet_ropsten/cert/blockbook -explorer=https://ropsten.etherscan.io/ -log_dir=/opt/coins/blockbook/ethereum_testnet_ropsten/logs User=blockbook-ethereum Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-ethereum.service b/build/deb/debian/blockbook-ethereum.service index 9d6dc97d..627c00e4 100644 --- a/build/deb/debian/blockbook-ethereum.service +++ b/build/deb/debian/blockbook-ethereum.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-ethereum.service [Service] -ExecStart=/opt/coins/blockbook/ethereum/bin/blockbook -blockchaincfg=/opt/coins/blockbook/ethereum/config/blockchaincfg.json -datadir=/opt/coins/data/ethereum/blockbook/db -sync -httpserver=:9036 -socketio=:9136 -certfile=/opt/coins/blockbook/ethereum/cert/blockbook -explorer=https://etherscan.io/ -log_dir=/opt/coins/blockbook/ethereum/logs +ExecStart=/opt/coins/blockbook/ethereum/bin/blockbook -blockchaincfg=/opt/coins/blockbook/ethereum/config/blockchaincfg.json -datadir=/opt/coins/data/ethereum/blockbook/db -sync -internal=:9036 -public=:9136 -certfile=/opt/coins/blockbook/ethereum/cert/blockbook -explorer=https://etherscan.io/ -log_dir=/opt/coins/blockbook/ethereum/logs User=blockbook-ethereum Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-litecoin-testnet.service b/build/deb/debian/blockbook-litecoin-testnet.service index d19c9f0a..f7a7dfc6 100644 --- a/build/deb/debian/blockbook-litecoin-testnet.service +++ b/build/deb/debian/blockbook-litecoin-testnet.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-litecoin-testnet.service [Service] -ExecStart=/opt/coins/blockbook/litecoin_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/litecoin_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/litecoin_testnet/blockbook/db -sync -httpserver=:19034 -socketio=:19134 -certfile=/opt/coins/blockbook/litecoin_testnet/cert/blockbook -explorer=http://explorer.litecointools.com/ -log_dir=/opt/coins/blockbook/litecoin_testnet/logs +ExecStart=/opt/coins/blockbook/litecoin_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/litecoin_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/litecoin_testnet/blockbook/db -sync -internal=:19034 -public=:19134 -certfile=/opt/coins/blockbook/litecoin_testnet/cert/blockbook -explorer=http://explorer.litecointools.com/ -log_dir=/opt/coins/blockbook/litecoin_testnet/logs User=blockbook-litecoin Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-litecoin.service b/build/deb/debian/blockbook-litecoin.service index dff213a9..561ac0f3 100644 --- a/build/deb/debian/blockbook-litecoin.service +++ b/build/deb/debian/blockbook-litecoin.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-litecoin.service [Service] -ExecStart=/opt/coins/blockbook/litecoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/litecoin/config/blockchaincfg.json -datadir=/opt/coins/data/litecoin/blockbook/db -sync -httpserver=:9034 -socketio=:9134 -certfile=/opt/coins/blockbook/litecoin/cert/blockbook -explorer=https://ltc-bitcore1.trezor.io/ -log_dir=/opt/coins/blockbook/litecoin/logs +ExecStart=/opt/coins/blockbook/litecoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/litecoin/config/blockchaincfg.json -datadir=/opt/coins/data/litecoin/blockbook/db -sync -internal=:9034 -public=:9134 -certfile=/opt/coins/blockbook/litecoin/cert/blockbook -explorer=https://ltc-bitcore1.trezor.io/ -log_dir=/opt/coins/blockbook/litecoin/logs User=blockbook-litecoin Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-namecoin.service b/build/deb/debian/blockbook-namecoin.service index db5f440b..a8f2b1c1 100644 --- a/build/deb/debian/blockbook-namecoin.service +++ b/build/deb/debian/blockbook-namecoin.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-namecoin.service [Service] -ExecStart=/opt/coins/blockbook/namecoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/namecoin/config/blockchaincfg.json -datadir=/opt/coins/data/namecoin/blockbook/db -sync -httpserver=:9039 -socketio=:9139 -certfile=/opt/coins/blockbook/namecoin/cert/blockbook -explorer=https://namecha.in/ -log_dir=/opt/coins/blockbook/namecoin/logs +ExecStart=/opt/coins/blockbook/namecoin/bin/blockbook -blockchaincfg=/opt/coins/blockbook/namecoin/config/blockchaincfg.json -datadir=/opt/coins/data/namecoin/blockbook/db -sync -internal=:9039 -public=:9139 -certfile=/opt/coins/blockbook/namecoin/cert/blockbook -explorer=https://namecha.in/ -log_dir=/opt/coins/blockbook/namecoin/logs User=blockbook-namecoin Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-zcash-testnet.service b/build/deb/debian/blockbook-zcash-testnet.service index cd190610..dc460551 100644 --- a/build/deb/debian/blockbook-zcash-testnet.service +++ b/build/deb/debian/blockbook-zcash-testnet.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-zcash-testnet.service [Service] -ExecStart=/opt/coins/blockbook/zcash_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/zcash_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/zcash_testnet/blockbook/db -sync -httpserver=:19032 -socketio=:19132 -certfile=/opt/coins/blockbook/zcash_testnet/cert/blockbook -explorer=https://explorer.testnet.z.cash/ -log_dir=/opt/coins/blockbook/zcash_testnet/logs +ExecStart=/opt/coins/blockbook/zcash_testnet/bin/blockbook -blockchaincfg=/opt/coins/blockbook/zcash_testnet/config/blockchaincfg.json -datadir=/opt/coins/data/zcash_testnet/blockbook/db -sync -internal=:19032 -public=:19132 -certfile=/opt/coins/blockbook/zcash_testnet/cert/blockbook -explorer=https://explorer.testnet.z.cash/ -log_dir=/opt/coins/blockbook/zcash_testnet/logs User=blockbook-zcash Type=simple Restart=on-failure diff --git a/build/deb/debian/blockbook-zcash.service b/build/deb/debian/blockbook-zcash.service index e7933e0c..d2de00cc 100644 --- a/build/deb/debian/blockbook-zcash.service +++ b/build/deb/debian/blockbook-zcash.service @@ -10,7 +10,7 @@ After=network.target Wants=backend-zcash.service [Service] -ExecStart=/opt/coins/blockbook/zcash/bin/blockbook -blockchaincfg=/opt/coins/blockbook/zcash/config/blockchaincfg.json -datadir=/opt/coins/data/zcash/blockbook/db -sync -httpserver=:9032 -socketio=:9132 -certfile=/opt/coins/blockbook/zcash/cert/blockbook -explorer=https://zcash.blockexplorer.com/ -log_dir=/opt/coins/blockbook/zcash/logs +ExecStart=/opt/coins/blockbook/zcash/bin/blockbook -blockchaincfg=/opt/coins/blockbook/zcash/config/blockchaincfg.json -datadir=/opt/coins/data/zcash/blockbook/db -sync -internal=:9032 -public=:9132 -certfile=/opt/coins/blockbook/zcash/cert/blockbook -explorer=https://zcash.blockexplorer.com/ -log_dir=/opt/coins/blockbook/zcash/logs User=blockbook-zcash Type=simple Restart=on-failure From 604b41f10a71db4e3d0dda896e9c70a9aad1e28d Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Tue, 26 Jun 2018 13:02:53 +0200 Subject: [PATCH 03/16] Add explorer api worker --- api/types.go | 49 ++++++++++++++++++++++++ api/worker.go | 95 ++++++++++++++++++++++++++++++++++++++++++++++ bchain/types.go | 6 +-- server/public.go | 29 ++++++++++++++ server/socketio.go | 2 +- 5 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 api/types.go create mode 100644 api/worker.go diff --git a/api/types.go b/api/types.go new file mode 100644 index 00000000..b00915ad --- /dev/null +++ b/api/types.go @@ -0,0 +1,49 @@ +package api + +type ScriptSig struct { + Hex string `json:"hex"` + Asm string `json:"asm,omitempty"` +} + +type Vin struct { + Txid string `json:"txid"` + Vout uint32 `json:"vout"` + Sequence int64 `json:"sequence,omitempty"` + N int `json:"n"` + ScriptSig ScriptSig `json:"scriptSig"` + Addr string `json:"addr"` + ValueSat int64 `json:"valueSat"` + Value float64 `json:"value"` +} + +type ScriptPubKey struct { + Hex string `json:"hex"` + Asm string `json:"asm,omitempty"` + Addresses []string `json:"addresses"` + Type string `json:"type,omitempty"` +} +type Vout struct { + Value float64 `json:"value"` + N int `json:"n"` + ScriptPubKey ScriptPubKey `json:"scriptPubKey"` + SpentTxID string `json:"spentTxId,omitempty"` + SpentIndex int `json:"spentIndex,omitempty"` + SpentHeight int `json:"spentHeight,omitempty"` +} + +type Tx struct { + Txid string `json:"txid"` + Version int32 `json:"version,omitempty"` + Locktime uint32 `json:"locktime,omitempty"` + Vin []Vin `json:"vin"` + Vout []Vout `json:"vout"` + Blockhash string `json:"blockhash,omitempty"` + Blockheight int `json:"blockheight"` + Confirmations uint32 `json:"confirmations"` + Time int64 `json:"time,omitempty"` + Blocktime int64 `json:"blocktime"` + ValueOut float64 `json:"valueOut"` + Size int `json:"size,omitempty"` + ValueIn float64 `json:"valueIn"` + Fees float64 `json:"fees"` +} diff --git a/api/worker.go b/api/worker.go new file mode 100644 index 00000000..9a8c91a5 --- /dev/null +++ b/api/worker.go @@ -0,0 +1,95 @@ +package api + +import ( + "blockbook/bchain" + "blockbook/db" +) + +// Worker is handle to api worker +type Worker struct { + db *db.RocksDB + txCache *db.TxCache + chain bchain.BlockChain + chainParser bchain.BlockChainParser +} + +// NewWorker creates new api worker +func NewWorker(db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache) (*Worker, error) { + w := &Worker{ + db: db, + txCache: txCache, + chain: chain, + chainParser: chain.GetChainParser(), + } + return w, nil +} + +func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool) (*Tx, error) { + bchainTx, height, err := w.txCache.GetTransaction(txid, bestheight) + if err != nil { + return nil, err + } + var blockhash string + if bchainTx.Confirmations > 0 { + blockhash, err = w.db.GetBlockHash(height) + if err != nil { + return nil, err + } + } + var valIn, valOut, fees float64 + vins := make([]Vin, len(bchainTx.Vin)) + for i := range bchainTx.Vin { + bchainVin := &bchainTx.Vin[i] + vin := &vins[i] + vin.Txid = bchainVin.Txid + vin.N = i + vin.Vout = bchainVin.Vout + vin.ScriptSig.Hex = bchainVin.ScriptSig.Hex + otx, _, err := w.txCache.GetTransaction(bchainVin.Txid, bestheight) + if err != nil { + return nil, err + } + if len(otx.Vout) > int(vin.Vout) { + vout := &otx.Vout[vin.Vout] + vin.Value = vout.Value + valIn += vout.Value + vin.ValueSat = int64(vout.Value*1E8 + 0.5) + if vout.Address != nil { + a := vout.Address.String() + vin.Addr = a + } + } + } + vouts := make([]Vout, len(bchainTx.Vout)) + for i := range bchainTx.Vout { + bchainVout := &bchainTx.Vout[i] + vout := &vouts[i] + vout.N = i + vout.Value = bchainVout.Value + valOut += bchainVout.Value + vout.ScriptPubKey.Hex = bchainVout.ScriptPubKey.Hex + vout.ScriptPubKey.Addresses = bchainVout.ScriptPubKey.Addresses + if spendingTx { + // TODO + } + } + // for now do not return size, we would have to compute vsize of segwit transactions + // size:=len(bchainTx.Hex) / 2 + fees = valIn - valOut + r := &Tx{ + Blockhash: blockhash, + Blockheight: int(height), + Blocktime: bchainTx.Blocktime, + Confirmations: bchainTx.Confirmations, + Fees: fees, + Locktime: bchainTx.LockTime, + Time: bchainTx.Time, + Txid: txid, + ValueIn: valIn, + ValueOut: valOut, + Version: bchainTx.Version, + Vin: vins, + Vout: vouts, + } + return r, nil +} diff --git a/bchain/types.go b/bchain/types.go index 582e50b3..09052918 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -58,9 +58,9 @@ type Vout struct { // Tx is blockchain transaction // unnecessary fields are commented out to avoid overhead type Tx struct { - Hex string `json:"hex"` - Txid string `json:"txid"` - // Version int32 `json:"version"` + Hex string `json:"hex"` + Txid string `json:"txid"` + Version int32 `json:"version"` LockTime uint32 `json:"locktime"` Vin []Vin `json:"vin"` Vout []Vout `json:"vout"` diff --git a/server/public.go b/server/public.go index f52da14a..368f99e7 100644 --- a/server/public.go +++ b/server/public.go @@ -1,6 +1,7 @@ package server import ( + "blockbook/api" "blockbook/bchain" "blockbook/common" "blockbook/db" @@ -27,6 +28,7 @@ type PublicServer struct { txCache *db.TxCache chain bchain.BlockChain chainParser bchain.BlockChainParser + api *api.Worker explorerURL string metrics *common.Metrics is *common.InternalState @@ -35,6 +37,11 @@ type PublicServer struct { // NewPublicServerS creates new public server http interface to blockbook and returns its handle func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, explorerURL string, metrics *common.Metrics, is *common.InternalState) (*PublicServer, error) { + api, err := api.NewWorker(db, chain, txCache) + if err != nil { + return nil, err + } + socketio, err := NewSocketIoServer(db, chain, txCache, metrics, is) if err != nil { return nil, err @@ -51,6 +58,7 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch binding: binding, certFiles: certFiles, https: https, + api: api, socketio: socketio, db: db, txCache: txCache, @@ -66,6 +74,8 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch // redirect to Bitcore for details of transaction serveMux.HandleFunc(path+"tx/", s.txRedirect) serveMux.HandleFunc(path+"address/", s.addressRedirect) + // explorer + serveMux.HandleFunc(path+"explorer/tx/", s.explorerTx) // API call used to detect state of Blockbook serveMux.HandleFunc(path+"api/block-index/", s.apiBlockIndex) // handle socket.io @@ -139,6 +149,25 @@ func (s *PublicServer) addressRedirect(w http.ResponseWriter, r *http.Request) { } } +func (s *PublicServer) explorerTx(w http.ResponseWriter, r *http.Request) { + var tx *api.Tx + var err error + if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 { + txid := r.URL.Path[i+1:] + bestheight, _, err := s.db.GetBestBlock() + if err == nil { + tx, err = s.api.GetTransaction(txid, bestheight, true) + } + } + if err == nil { + buf, err := json.MarshalIndent(tx, "", " ") + if err != nil { + glog.Error(err) + } + w.Write(buf) + } +} + type resAboutBlockbookPublic struct { Coin string `json:"coin"` Host string `json:"host"` diff --git a/server/socketio.go b/server/socketio.go index 14293f48..e996d513 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -598,7 +598,7 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai return res, err } if len(otx.Vout) > int(vin.Vout) { - vout := otx.Vout[vin.Vout] + vout := &otx.Vout[vin.Vout] if vout.Address != nil { a := vout.Address.String() ai.Address = &a From 94873f4d8688aefbac7fae60f360907c20397a16 Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Tue, 26 Jun 2018 13:03:59 +0200 Subject: [PATCH 04/16] Return tx version, update parser tests --- bchain/coins/bch/bcashparser_test.go | 2 ++ bchain/coins/btc/bitcoinparser.go | 4 ++-- bchain/coins/btc/bitcoinparser_test.go | 2 ++ bchain/coins/dogecoin/dogecoinparser_test.go | 2 ++ bchain/coins/litecoin/litecoinparser_test.go | 1 + 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/bchain/coins/bch/bcashparser_test.go b/bchain/coins/bch/bcashparser_test.go index 1d042b9f..3e1cb4c1 100644 --- a/bchain/coins/bch/bcashparser_test.go +++ b/bchain/coins/bch/bcashparser_test.go @@ -146,6 +146,7 @@ func init() { Blocktime: 1519053802, Txid: "056e3d82e5ffd0e915fb9b62797d76263508c34fe3e5dbed30dd3e943930f204", LockTime: 512115, + Version: 1, Vin: []bchain.Vin{ { ScriptSig: bchain.ScriptSig{ @@ -176,6 +177,7 @@ func init() { Blocktime: 1235678901, Txid: "474e6795760ebe81cb4023dc227e5a0efe340e1771c89a0035276361ed733de7", LockTime: 0, + Version: 1, Vin: []bchain.Vin{ { ScriptSig: bchain.ScriptSig{ diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index 41c52759..861c7f31 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -130,8 +130,8 @@ func (p *BitcoinParser) TxFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.T } } tx := bchain.Tx{ - Txid: t.TxHash().String(), - // skip: Version, + Txid: t.TxHash().String(), + Version: t.Version, LockTime: t.LockTime, Vin: vin, Vout: vout, diff --git a/bchain/coins/btc/bitcoinparser_test.go b/bchain/coins/btc/bitcoinparser_test.go index 46490f6c..d605f45b 100644 --- a/bchain/coins/btc/bitcoinparser_test.go +++ b/bchain/coins/btc/bitcoinparser_test.go @@ -139,6 +139,7 @@ func init() { Blocktime: 1519053802, Txid: "056e3d82e5ffd0e915fb9b62797d76263508c34fe3e5dbed30dd3e943930f204", LockTime: 512115, + Version: 1, Vin: []bchain.Vin{ { ScriptSig: bchain.ScriptSig{ @@ -169,6 +170,7 @@ func init() { Blocktime: 1235678901, Txid: "474e6795760ebe81cb4023dc227e5a0efe340e1771c89a0035276361ed733de7", LockTime: 0, + Version: 1, Vin: []bchain.Vin{ { ScriptSig: bchain.ScriptSig{ diff --git a/bchain/coins/dogecoin/dogecoinparser_test.go b/bchain/coins/dogecoin/dogecoinparser_test.go index 658d4b1c..b8ea585f 100644 --- a/bchain/coins/dogecoin/dogecoinparser_test.go +++ b/bchain/coins/dogecoin/dogecoinparser_test.go @@ -98,6 +98,7 @@ func init() { Blocktime: 1519053456, Txid: "097ea09ba284f3f2a9e880e11f837edf7e5cea81c8da2238f5bc7c2c4c407943", LockTime: 0, + Version: 1, Vin: []bchain.Vin{ { ScriptSig: bchain.ScriptSig{ @@ -139,6 +140,7 @@ func init() { Blocktime: 1519050987, Txid: "b276545af246e3ed5a4e3e5b60d359942a1808579effc53ff4f343e4f6cfc5a0", LockTime: 0, + Version: 1, Vin: []bchain.Vin{ { ScriptSig: bchain.ScriptSig{ diff --git a/bchain/coins/litecoin/litecoinparser_test.go b/bchain/coins/litecoin/litecoinparser_test.go index a28a4a35..11c55f1e 100644 --- a/bchain/coins/litecoin/litecoinparser_test.go +++ b/bchain/coins/litecoin/litecoinparser_test.go @@ -144,6 +144,7 @@ func init() { Blocktime: 1519053456, Txid: "1c50c1770374d7de2f81a87463a5225bb620d25fd467536223a5b715a47c9e32", LockTime: 0, + Version: 2, Vin: []bchain.Vin{ { ScriptSig: bchain.ScriptSig{ From b52b861db2f89947d1bb2312509b6806b50580e0 Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Wed, 27 Jun 2018 00:44:23 +0200 Subject: [PATCH 05/16] Add initial tx explorer template + favicon --- server/public.go | 46 ++++++++++++++++++++++++++++++------- static/favicon.ico | Bin 0 -> 856 bytes static/templates/base.html | 17 ++++++++++++++ static/templates/tx.html | 3 +++ static/test.html | 5 ++-- 5 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 static/favicon.ico create mode 100644 static/templates/base.html create mode 100644 static/templates/tx.html diff --git a/server/public.go b/server/public.go index 368f99e7..af2c16d1 100644 --- a/server/public.go +++ b/server/public.go @@ -8,6 +8,7 @@ import ( "context" "encoding/json" "fmt" + "html/template" "net/http" "strconv" "strings" @@ -32,6 +33,7 @@ type PublicServer struct { explorerURL string metrics *common.Metrics is *common.InternalState + txTpl *template.Template } // NewPublicServerS creates new public server http interface to blockbook and returns its handle @@ -69,6 +71,8 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch is: is, } + // favicon + serveMux.Handle(path+"favicon.ico", http.FileServer(http.Dir("./static/"))) // support for tests of socket.io interface serveMux.Handle(path+"test.html", http.FileServer(http.Dir("./static/"))) // redirect to Bitcore for details of transaction @@ -76,12 +80,16 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch serveMux.HandleFunc(path+"address/", s.addressRedirect) // explorer serveMux.HandleFunc(path+"explorer/tx/", s.explorerTx) - // API call used to detect state of Blockbook + // API calls serveMux.HandleFunc(path+"api/block-index/", s.apiBlockIndex) + serveMux.HandleFunc(path+"api/tx/", s.apiTx) // handle socket.io serveMux.Handle(path+"socket.io/", socketio.GetHandler()) // default handler serveMux.HandleFunc(path, s.index) + + s.txTpl = template.Must(template.New("tx").ParseFiles("./static/templates/tx.html", "./static/templates/base.html")) + return s, nil } @@ -151,20 +159,22 @@ func (s *PublicServer) addressRedirect(w http.ResponseWriter, r *http.Request) { func (s *PublicServer) explorerTx(w http.ResponseWriter, r *http.Request) { var tx *api.Tx - var err error if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 { txid := r.URL.Path[i+1:] bestheight, _, err := s.db.GetBestBlock() if err == nil { tx, err = s.api.GetTransaction(txid, bestheight, true) - } - } - if err == nil { - buf, err := json.MarshalIndent(tx, "", " ") - if err != nil { + } else { glog.Error(err) } - w.Write(buf) + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + data := struct { + CoinName string + Tx *api.Tx + }{s.is.Coin, tx} + if err := s.txTpl.ExecuteTemplate(w, "base.html", data); err != nil { + glog.Error(err) } } @@ -199,6 +209,7 @@ func (s *PublicServer) index(w http.ResponseWriter, r *http.Request) { LastMempoolTime: mt, About: blockbookAbout, } + w.Header().Set("Content-Type", "application/json; charset=utf-8") buf, err := json.MarshalIndent(a, "", " ") if err != nil { glog.Error(err) @@ -231,6 +242,25 @@ func (s *PublicServer) apiBlockIndex(w http.ResponseWriter, r *http.Request) { BlockHash: hash, About: blockbookAbout, } + w.Header().Set("Content-Type", "application/json; charset=utf-8") json.NewEncoder(w).Encode(r) } } + +func (s *PublicServer) apiTx(w http.ResponseWriter, r *http.Request) { + var tx *api.Tx + var err error + if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 { + txid := r.URL.Path[i+1:] + bestheight, _, err := s.db.GetBestBlock() + if err == nil { + tx, err = s.api.GetTransaction(txid, bestheight, true) + } else { + glog.Error(err) + } + } + if err == nil { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + json.NewEncoder(w).Encode(tx) + } +} diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a1b20e0a2698c47a454a5143ad4adb622c828eba GIT binary patch literal 856 zcmV-e1E>6nP)Px&5=lfsR9Fe^S5HV3Q5gTenUzh~%GDw$#2IGVH8xY&OCB`OQ5bgc(jkbv1QHf? z^;YI72s#)g^ykp22%2n(n;5Sr~h7_U+EtA0%)t@B9D# z-uJ$J?^}d*etUJjn=y707#v~Bk`s@MoBRp2TxrQ|ICf&p|@F!97SRGGs~@rLO4eEyjythR;%5Np_Smx6Rl z0xcq-TSdjE>uPF@zarV-%w{&+{~bBkIuE$?IiwFaQAI zm{fJikp*&PR2fmn=%xtxA~L<9Y5i+*2HV$YA{HFy80qJEnMc$4cX+hBQj@fMv1%ic z*B>k^%j;cQiqL4$ga-3F{T8pN16eye=JySA1b&~t%5OLTX%Ccd5uc(0)8+Ci5(Y=9 zCz`8RlvJSrD1f)<@)3UHL4i$8H_0Xtz=j{eCVHJQ&|p)kR3lwN zyMit&S0Da0M4X~oa5P$1cRQ2G{E!7V45Jx~#UXl!Pt$W66KwwYHDoNw9Cl;5uwWay zemiv#kcmnqkK^fiF6u&buF|i`^ zsR+O`Zfk3cFBJ-BsI-H$)4(Cq^`pcu8K@(cZ9SAt&|d74EzeY=J3BjTzs=2^qAB?t zHJK)}rNmE2e%Z?9p3C$ySzrbHPCY$6k=dD + + + + + + + + + TREZOR {{.CoinName}} Explorer + + + + {{template "tx" .Tx}} + + + \ No newline at end of file diff --git a/static/templates/tx.html b/static/templates/tx.html new file mode 100644 index 00000000..ea3233e6 --- /dev/null +++ b/static/templates/tx.html @@ -0,0 +1,3 @@ +{{define "tx"}} +{{.Txid}} +{{end}} \ No newline at end of file diff --git a/static/test.html b/static/test.html index 2d0d1733..e5e0789f 100644 --- a/static/test.html +++ b/static/test.html @@ -4,8 +4,7 @@ - +