diff --git a/api/worker.go b/api/worker.go index cad14df1..87eb56a2 100644 --- a/api/worker.go +++ b/api/worker.go @@ -2075,19 +2075,20 @@ func (w *Worker) GetSystemInfo(internal bool) (*SystemInfo, error) { About: Text.BlockbookAbout, } backendInfo := &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, + 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, + ConsensusVersion: ci.ConsensusVersion, + Consensus: ci.Consensus, } w.is.SetBackendInfo(backendInfo) glog.Info("GetSystemInfo, ", time.Since(start)) diff --git a/bchain/coins/eth/ethrpc.go b/bchain/coins/eth/ethrpc.go index 1e48bc54..001a199c 100644 --- a/bchain/coins/eth/ethrpc.go +++ b/bchain/coins/eth/ethrpc.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" "math/big" + "net/http" "strconv" "strings" "sync" @@ -46,6 +48,7 @@ type Configuration struct { QueryBackendOnMempoolResync bool `json:"queryBackendOnMempoolResync"` ProcessInternalTransactions bool `json:"processInternalTransactions"` ProcessZeroInternalTransactions bool `json:"processZeroInternalTransactions"` + ConsensusNodeVersionURL string `json:"consensusNodeVersion"` } // EthereumRPC is an interface to JSON-RPC eth service. @@ -335,6 +338,37 @@ func (b *EthereumRPC) GetSubversion() string { return "" } +func (b *EthereumRPC) getConsensusVersion() string { + if b.ChainConfig.ConsensusNodeVersionURL == "" { + return "" + } + httpClient := &http.Client{ + Timeout: 2 * time.Second, + } + resp, err := httpClient.Get(b.ChainConfig.ConsensusNodeVersionURL) + if err != nil || resp.StatusCode != http.StatusOK { + glog.Error("getConsensusVersion ", err) + return "" + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + glog.Error("getConsensusVersion ", err) + return "" + } + type consensusVersion struct { + Data struct { + Version string `json:"version"` + } `json:"data"` + } + var v consensusVersion + err = json.Unmarshal(body, &v) + if err != nil { + glog.Error("getConsensusVersion ", err) + return "" + } + return v.Data.Version +} + // GetChainInfo returns information about the connected backend func (b *EthereumRPC) GetChainInfo() (*bchain.ChainInfo, error) { h, err := b.getBestHeader() @@ -351,11 +385,13 @@ func (b *EthereumRPC) GetChainInfo() (*bchain.ChainInfo, error) { if err := b.rpc.CallContext(ctx, &ver, "web3_clientVersion"); err != nil { return nil, err } + consensusVersion := b.getConsensusVersion() rv := &bchain.ChainInfo{ - Blocks: int(h.Number.Int64()), - Bestblockhash: h.Hash().Hex(), - Difficulty: h.Difficulty.String(), - Version: ver, + Blocks: int(h.Number.Int64()), + Bestblockhash: h.Hash().Hex(), + Difficulty: h.Difficulty.String(), + Version: ver, + ConsensusVersion: consensusVersion, } idi := int(id.Uint64()) if idi == 1 { diff --git a/bchain/types.go b/bchain/types.go index 4d9af1f9..713b30be 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -192,18 +192,19 @@ type MempoolEntry struct { // ChainInfo is used to get information about blockchain type ChainInfo struct { - Chain string `json:"chain"` - Blocks int `json:"blocks"` - Headers int `json:"headers"` - Bestblockhash string `json:"bestblockhash"` - Difficulty string `json:"difficulty"` - SizeOnDisk int64 `json:"size_on_disk"` - Version string `json:"version"` - Subversion string `json:"subversion"` - ProtocolVersion string `json:"protocolversion"` - Timeoffset float64 `json:"timeoffset"` - Warnings string `json:"warnings"` - Consensus interface{} `json:"consensus,omitempty"` + Chain string `json:"chain"` + Blocks int `json:"blocks"` + Headers int `json:"headers"` + Bestblockhash string `json:"bestblockhash"` + Difficulty string `json:"difficulty"` + SizeOnDisk int64 `json:"size_on_disk"` + Version string `json:"version"` + Subversion string `json:"subversion"` + ProtocolVersion string `json:"protocolversion"` + Timeoffset float64 `json:"timeoffset"` + Warnings string `json:"warnings"` + ConsensusVersion string `json:"consensus_version,omitempty"` + Consensus interface{} `json:"consensus,omitempty"` } // RPCError defines rpc error returned by backend diff --git a/common/internalstate.go b/common/internalstate.go index 3829094d..a7090c80 100644 --- a/common/internalstate.go +++ b/common/internalstate.go @@ -31,19 +31,20 @@ type InternalStateColumn struct { // 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"` + 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"` + ConsensusVersion string `json:"consensus_version,omitempty"` + Consensus interface{} `json:"consensus,omitempty"` } // InternalState contains the data of the internal state diff --git a/configs/coins/ethereum.json b/configs/coins/ethereum.json index c3c0898c..7a11de2b 100644 --- a/configs/coins/ethereum.json +++ b/configs/coins/ethereum.json @@ -51,10 +51,11 @@ "mempool_sub_workers": 2, "block_addresses_to_keep": 300, "additional_params": { + "consensusNodeVersion": "http://localhost:7536/eth/v1/node/version", "mempoolTxTimeoutHours": 48, "queryBackendOnMempoolResync": false, "fiat_rates": "coingecko", - "fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"ethereum\", \"periodSeconds\": 60}" + "fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"ethereum\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}" } } }, diff --git a/configs/coins/ethereum_archive.json b/configs/coins/ethereum_archive.json index ff341ccd..c03bbbc1 100644 --- a/configs/coins/ethereum_archive.json +++ b/configs/coins/ethereum_archive.json @@ -51,6 +51,7 @@ "mempool_sub_workers": 2, "block_addresses_to_keep": 600, "additional_params": { + "consensusNodeVersion": "http://localhost:7516/eth/v1/node/version", "address_aliases": true, "mempoolTxTimeoutHours": 48, "processInternalTransactions": true, diff --git a/configs/coins/ethereum_testnet_goerli.json b/configs/coins/ethereum_testnet_goerli.json index f4c3b83b..e9d78421 100644 --- a/configs/coins/ethereum_testnet_goerli.json +++ b/configs/coins/ethereum_testnet_goerli.json @@ -51,6 +51,7 @@ "mempool_sub_workers": 2, "block_addresses_to_keep": 3000, "additional_params": { + "consensusNodeVersion": "http://localhost:17526/eth/v1/node/version", "mempoolTxTimeoutHours": 12, "queryBackendOnMempoolResync": false } diff --git a/configs/coins/ethereum_testnet_goerli_archive.json b/configs/coins/ethereum_testnet_goerli_archive.json index 08deb11d..9bdf5590 100644 --- a/configs/coins/ethereum_testnet_goerli_archive.json +++ b/configs/coins/ethereum_testnet_goerli_archive.json @@ -51,6 +51,7 @@ "mempool_sub_workers": 2, "block_addresses_to_keep": 3000, "additional_params": { + "consensusNodeVersion": "http://localhost:17506/eth/v1/node/version", "address_aliases": true, "mempoolTxTimeoutHours": 12, "processInternalTransactions": true, diff --git a/configs/coins/ethereum_testnet_ropsten.json b/configs/coins/ethereum_testnet_ropsten.json index 41dbd55f..c607f101 100644 --- a/configs/coins/ethereum_testnet_ropsten.json +++ b/configs/coins/ethereum_testnet_ropsten.json @@ -51,6 +51,7 @@ "mempool_sub_workers": 2, "block_addresses_to_keep": 3000, "additional_params": { + "consensusNodeVersion": "http://localhost:17536/eth/v1/node/version", "mempoolTxTimeoutHours": 12, "queryBackendOnMempoolResync": false } diff --git a/configs/coins/ethereum_testnet_ropsten_archive.json b/configs/coins/ethereum_testnet_ropsten_archive.json index 1e7d19cb..a24e036c 100644 --- a/configs/coins/ethereum_testnet_ropsten_archive.json +++ b/configs/coins/ethereum_testnet_ropsten_archive.json @@ -51,6 +51,7 @@ "mempool_sub_workers": 2, "block_addresses_to_keep": 3000, "additional_params": { + "consensusNodeVersion": "http://localhost:17516/eth/v1/node/version", "address_aliases": true, "mempoolTxTimeoutHours": 12, "processInternalTransactions": true, diff --git a/db/sync.go b/db/sync.go index 895edf28..823ec9aa 100644 --- a/db/sync.go +++ b/db/sync.go @@ -58,19 +58,20 @@ func (w *SyncWorker) updateBackendInfo() { 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, + 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, + ConsensusVersion: ci.ConsensusVersion, + Consensus: ci.Consensus, }) } diff --git a/server/websocket.go b/server/websocket.go index 17ea76a3..e02793a0 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -569,9 +569,10 @@ func (s *WebsocketServer) getInfo() (interface{}, error) { return nil, err } type backendInfo struct { - Version string `json:"version,omitempty"` - Subversion string `json:"subversion,omitempty"` - Consensus interface{} `json:"consensus,omitempty"` + Version string `json:"version,omitempty"` + Subversion string `json:"subversion,omitempty"` + ConsensusVersion string `json:"consensus_version,omitempty"` + Consensus interface{} `json:"consensus,omitempty"` } type info struct { Name string `json:"name"` @@ -594,9 +595,10 @@ func (s *WebsocketServer) getInfo() (interface{}, error) { Block0Hash: s.block0hash, Testnet: s.chain.IsTestnet(), Backend: backendInfo{ - Version: bi.Version, - Subversion: bi.Subversion, - Consensus: bi.Consensus, + Version: bi.Version, + Subversion: bi.Subversion, + ConsensusVersion: bi.ConsensusVersion, + Consensus: bi.Consensus, }, }, nil } diff --git a/static/templates/index.html b/static/templates/index.html index 2dc6a826..77080622 100644 --- a/static/templates/index.html +++ b/static/templates/index.html @@ -72,14 +72,24 @@ Version {{$be.Version}} + {{- if $be.Subversion -}} Subversion {{$be.Subversion}} + {{- end -}} + {{- if $be.ProtocolVersion -}} Protocol Version {{$be.ProtocolVersion}} + {{- end -}} + {{- if $be.ConsensusVersion -}} + + Consensus Version + {{$be.ConsensusVersion}} + + {{- end -}} Last Block {{$be.Blocks}}