Compare commits

...

2 Commits

Author SHA1 Message Date
Martin Boehm e9ea80b28c Return info about backend in websocket getInfo request 2020-12-29 01:43:08 +01:00
Martin Boehm 26702bf800 Show consensus in explorer index page 2020-12-29 01:43:08 +01:00
8 changed files with 101 additions and 29 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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()

View File

@ -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)

View File

@ -440,6 +440,7 @@ func (s *PublicServer) parseTemplates() []*template.Template {
"setTxToTemplateData": setTxToTemplateData,
"isOwnAddress": isOwnAddress,
"isOwnAddresses": isOwnAddresses,
"toJSON": toJSON,
}
var createTemplate func(filenames ...string) *template.Template
if s.debug {
@ -507,6 +508,14 @@ func formatTime(t time.Time) string {
return t.Format(time.RFC1123)
}
func toJSON(data interface{}) string {
json, err := json.Marshal(data)
if err != nil {
return ""
}
return string(json)
}
// for now return the string as it is
// in future could be used to do coin specific formatting
func (s *PublicServer) formatAmount(a *api.Amount) string {

View File

@ -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",

View File

@ -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
}

View File

@ -100,6 +100,12 @@
<td class="data">{{$be.SizeOnDisk}}</td>
</tr>
{{- end -}}
{{- if $be.Consensus -}}
<tr>
<td>Consensus</td>
<td class="data">{{toJSON $be.Consensus}}</td>
</tr>
{{- end -}}
{{- if $be.Warnings -}}
<tr>
<td>Warnings</td>