diff --git a/api/types.go b/api/types.go index 38f0fd87..9295558a 100644 --- a/api/types.go +++ b/api/types.go @@ -421,27 +421,10 @@ type BlockbookInfo struct { About string `json:"about"` } -// BackendInfo is used to get information about blockchain -type BackendInfo struct { - BackendError string `json:"error,omitempty"` - Chain string `json:"chain,omitempty"` - Blocks int `json:"blocks,omitempty"` - Headers int `json:"headers,omitempty"` - BestBlockHash string `json:"bestBlockHash,omitempty"` - Difficulty string `json:"difficulty,omitempty"` - SizeOnDisk int64 `json:"sizeOnDisk,omitempty"` - Version string `json:"version,omitempty"` - Subversion string `json:"subversion,omitempty"` - ProtocolVersion string `json:"protocolVersion,omitempty"` - Timeoffset float64 `json:"timeOffset,omitempty"` - Warnings string `json:"warnings,omitempty"` - Consensus interface{} `json:"consensus,omitempty"` -} - // SystemInfo contains information about the running blockbook and backend instance type SystemInfo struct { - Blockbook *BlockbookInfo `json:"blockbook"` - Backend *BackendInfo `json:"backend"` + Blockbook *BlockbookInfo `json:"blockbook"` + Backend *common.BackendInfo `json:"backend"` } // MempoolTxid contains information about a transaction in mempool diff --git a/api/worker.go b/api/worker.go index 63b5dc74..a8a2beee 100644 --- a/api/worker.go +++ b/api/worker.go @@ -1764,7 +1764,7 @@ func (w *Worker) GetSystemInfo(internal bool) (*SystemInfo, error) { DbColumns: columnStats, About: Text.BlockbookAbout, } - backendInfo := &BackendInfo{ + backendInfo := &common.BackendInfo{ BackendError: backendError, BestBlockHash: ci.Bestblockhash, Blocks: ci.Blocks, @@ -1779,6 +1779,7 @@ func (w *Worker) GetSystemInfo(internal bool) (*SystemInfo, error) { Warnings: ci.Warnings, Consensus: ci.Consensus, } + w.is.SetBackendInfo(backendInfo) glog.Info("GetSystemInfo finished in ", time.Since(start)) return &SystemInfo{blockbookInfo, backendInfo}, nil } diff --git a/common/internalstate.go b/common/internalstate.go index bfe84fc9..bf8a46b5 100644 --- a/common/internalstate.go +++ b/common/internalstate.go @@ -26,6 +26,23 @@ type InternalStateColumn struct { Updated time.Time `json:"updated"` } +// BackendInfo is used to get information about blockchain +type BackendInfo struct { + BackendError string `json:"error,omitempty"` + Chain string `json:"chain,omitempty"` + Blocks int `json:"blocks,omitempty"` + Headers int `json:"headers,omitempty"` + BestBlockHash string `json:"bestBlockHash,omitempty"` + Difficulty string `json:"difficulty,omitempty"` + SizeOnDisk int64 `json:"sizeOnDisk,omitempty"` + Version string `json:"version,omitempty"` + Subversion string `json:"subversion,omitempty"` + ProtocolVersion string `json:"protocolVersion,omitempty"` + Timeoffset float64 `json:"timeOffset,omitempty"` + Warnings string `json:"warnings,omitempty"` + Consensus interface{} `json:"consensus,omitempty"` +} + // InternalState contains the data of the internal state type InternalState struct { mux sync.Mutex @@ -55,6 +72,8 @@ type InternalState struct { DbColumns []InternalStateColumn `json:"dbColumns"` UtxoChecked bool `json:"utxoChecked"` + + BackendInfo BackendInfo `json:"-"` } // StartedSync signals start of synchronization @@ -216,6 +235,20 @@ func (is *InternalState) GetBlockHeightOfTime(time uint32) uint32 { return uint32(height) } +// SetBackendInfo sets new BackendInfo +func (is *InternalState) SetBackendInfo(bi *BackendInfo) { + is.mux.Lock() + defer is.mux.Unlock() + is.BackendInfo = *bi +} + +// GetBackendInfo gets BackendInfo +func (is *InternalState) GetBackendInfo() BackendInfo { + is.mux.Lock() + defer is.mux.Unlock() + return is.BackendInfo +} + // Pack marshals internal state to json func (is *InternalState) Pack() ([]byte, error) { is.mux.Lock() diff --git a/db/sync.go b/db/sync.go index fc0c0fbc..7b671667 100644 --- a/db/sync.go +++ b/db/sync.go @@ -49,6 +49,31 @@ var errFork = errors.New("fork") // ErrOperationInterrupted is returned when operation is interrupted by OS signal var ErrOperationInterrupted = errors.New("ErrOperationInterrupted") +func (w *SyncWorker) updateBackendInfo() { + ci, err := w.chain.GetChainInfo() + var backendError string + if err != nil { + glog.Error("GetChainInfo error ", err) + backendError = errors.Annotatef(err, "GetChainInfo").Error() + ci = &bchain.ChainInfo{} + } + w.is.SetBackendInfo(&common.BackendInfo{ + BackendError: backendError, + BestBlockHash: ci.Bestblockhash, + Blocks: ci.Blocks, + Chain: ci.Chain, + Difficulty: ci.Difficulty, + Headers: ci.Headers, + ProtocolVersion: ci.ProtocolVersion, + SizeOnDisk: ci.SizeOnDisk, + Subversion: ci.Subversion, + Timeoffset: ci.Timeoffset, + Version: ci.Version, + Warnings: ci.Warnings, + Consensus: ci.Consensus, + }) +} + // ResyncIndex synchronizes index to the top of the blockchain // onNewBlock is called when new block is connected, but not in initial parallel sync func (w *SyncWorker) ResyncIndex(onNewBlock bchain.OnNewBlockFunc, initialSync bool) error { @@ -57,6 +82,9 @@ func (w *SyncWorker) ResyncIndex(onNewBlock bchain.OnNewBlockFunc, initialSync b err := w.resyncIndex(onNewBlock, initialSync) + // update backend info after each resync + w.updateBackendInfo() + switch err { case nil: d := time.Since(start) diff --git a/server/public_test.go b/server/public_test.go index fee5b252..fd839750 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -1044,7 +1044,7 @@ func websocketTestsBitcoinType(t *testing.T, ts *httptest.Server) { req: websocketReq{ Method: "getInfo", }, - want: `{"id":"0","data":{"name":"Fakecoin","shortcut":"FAKE","decimals":8,"version":"unknown","bestHeight":225494,"bestHash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6","block0Hash":"","testnet":true}}`, + want: `{"id":"0","data":{"name":"Fakecoin","shortcut":"FAKE","decimals":8,"version":"unknown","bestHeight":225494,"bestHash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6","block0Hash":"","testnet":true,"backend":{"version":"001001","subversion":"/Fakecoin:0.0.1/"}}}`, }, { name: "websocket getBlockHash", diff --git a/server/websocket.go b/server/websocket.go index d7746085..3386450a 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -528,19 +528,26 @@ func (s *WebsocketServer) getTransactionSpecific(txid string) (interface{}, erro func (s *WebsocketServer) getInfo() (interface{}, error) { vi := common.GetVersionInfo() + bi := s.is.GetBackendInfo() height, hash, err := s.db.GetBestBlock() if err != nil { return nil, err } + type backendInfo struct { + Version string `json:"version,omitempty"` + Subversion string `json:"subversion,omitempty"` + Consensus interface{} `json:"consensus,omitempty"` + } type info struct { - Name string `json:"name"` - Shortcut string `json:"shortcut"` - Decimals int `json:"decimals"` - Version string `json:"version"` - BestHeight int `json:"bestHeight"` - BestHash string `json:"bestHash"` - Block0Hash string `json:"block0Hash"` - Testnet bool `json:"testnet"` + Name string `json:"name"` + Shortcut string `json:"shortcut"` + Decimals int `json:"decimals"` + Version string `json:"version"` + BestHeight int `json:"bestHeight"` + BestHash string `json:"bestHash"` + Block0Hash string `json:"block0Hash"` + Testnet bool `json:"testnet"` + Backend backendInfo `json:"backend"` } return &info{ Name: s.is.Coin, @@ -551,6 +558,11 @@ func (s *WebsocketServer) getInfo() (interface{}, error) { Version: vi.Version, Block0Hash: s.block0hash, Testnet: s.chain.IsTestnet(), + Backend: backendInfo{ + Version: bi.Version, + Subversion: bi.Subversion, + Consensus: bi.Consensus, + }, }, nil }