mirror of
https://github.com/janoside/btc-rpc-explorer.git
synced 2026-08-13 12:33:13 +02:00
361 lines
No EOL
15 KiB
Text
361 lines
No EOL
15 KiB
Text
extends layout
|
|
|
|
block headContent
|
|
title Node Details
|
|
|
|
block content
|
|
+pageTitle("Node Details")
|
|
|
|
if (getblockchaininfo)
|
|
if (false)
|
|
p Data from RPC commands
|
|
a(href="./rpc-browser?method=getblockchaininfo") getblockchaininfo
|
|
span ,
|
|
a(href="./rpc-browser?method=getnetworkinfo") getnetworkinfo
|
|
span , and
|
|
a(href="./rpc-browser?method=getnettotals") getnettotals
|
|
|
|
if (false)
|
|
pre
|
|
code.json #{JSON.stringify(getblockchaininfo, null, 4)}
|
|
|
|
|
|
+pageTabs(["Details", "JSON"])
|
|
|
|
|
|
div.tab-content
|
|
+pageTab("Details", true)
|
|
|
|
if (getblockchaininfo.warnings)
|
|
if (Array.isArray(getblockchaininfo.warnings) && getblockchaininfo.warnings.length > 0)
|
|
+contentSection("Active Warnings")
|
|
pre
|
|
code.json(data-lang="json") #{JSON.stringify(getblockchaininfo.warnings, null, 4)}
|
|
|
|
else if (typeof getblockchaininfo.warnings === "string" && getblockchaininfo.warnings.trim().length > 0)
|
|
+contentSection("Active Warnings")
|
|
span.text-danger #{getblockchaininfo.warnings}
|
|
|
|
+contentSection("Node Summary")
|
|
+summaryRow(4)
|
|
+summaryItem("Version", "Node version number and subversion string")
|
|
| #{getnetworkinfo.version} (#{getnetworkinfo.subversion})
|
|
|
|
+summaryItem("Protocol Version", "Protocol version number")
|
|
| #{getnetworkinfo.protocolversion}
|
|
|
|
+summaryItem("Status", "Block download progress or synchronized state")
|
|
if (getblockchaininfo.initialblockdownload || getblockchaininfo.headers > getblockchaininfo.blocks)
|
|
span Initial block download progress #{(100 * getblockchaininfo.verificationprogress).toLocaleString()}%
|
|
else
|
|
span.text-success Synchronized
|
|
|
|
+summaryItem("Uptime", "How long this node has been running")
|
|
- var startTimeAgo = moment.duration(uptimeSeconds * 1000);
|
|
span #{startTimeAgo.format()}
|
|
|
|
+contentSection("Blockchain")
|
|
+summaryRow(4 + (getblockchaininfo.size_on_disk ? 1 : 0) + (getblockchaininfo.pruned ? 1 : 0))
|
|
+summaryItem("Chain", "Network name (main, test, signet, regtest)")
|
|
if (getblockchaininfo.chain == "main")
|
|
span.text-success #{getblockchaininfo.chain}
|
|
else
|
|
span.text-warning #{getblockchaininfo.chain}
|
|
|
|
+summaryItem("Block Count", "Current height of the most-work fully-validated chain. Also number of headers this node has validated")
|
|
| #{getblockchaininfo.blocks.toLocaleString()}
|
|
if (getblockchaininfo.headers != getblockchaininfo.blocks)
|
|
br
|
|
small.text-muted (headers: #{getblockchaininfo.headers.toLocaleString()})
|
|
|
|
+summaryItem("Difficulty", "Mining difficulty (adjusted every 2016 blocks to maintain the time it takes to process one block at around 10 minutes)")
|
|
- var difficultyData = utils.formatLargeNumber(getblockchaininfo.difficulty, 3);
|
|
span.border-dotted(title=parseFloat(getblockchaininfo.difficulty).toLocaleString(), data-bs-toggle="tooltip")
|
|
span #{difficultyData[0]}
|
|
span x 10
|
|
sup #{difficultyData[1].exponent}
|
|
|
|
if (getblockchaininfo.size_on_disk)
|
|
+summaryItem("Data Size", "Estimated size of the block and undo files on disk")
|
|
- var sizeData = utils.formatLargeNumber(getblockchaininfo.size_on_disk, 1);
|
|
| #{sizeData[0]} #{sizeData[1].abbreviation}B
|
|
|
|
if (getblockchaininfo.pruned)
|
|
+summaryItem("Pruned?", "Whether your node prunes the blockchain. With pruning active, your node will delete some data that is non-essential for future verification needs, in order to reduce disk usage.")
|
|
span.text-warning Yes
|
|
small.ms-2.text-muted
|
|
| (
|
|
span.border-dotted(title="This is the latest block for which your node has all block data; blocks older than this one have had some or all non-essential details deleted.", data-bs-toggle="tooltip")
|
|
| #{getblockchaininfo.pruneheight.toLocaleString()}+
|
|
| )
|
|
|
|
if (false)
|
|
br
|
|
|
|
span.border-dotted(title="This is the approximate amount of non-essential blockchain data that your node will store.", data-bs-toggle="tooltip") Prune target size
|
|
|
|
span :
|
|
- var pruneTargetSize = utils.formatLargeNumber(getblockchaininfo.prune_target_size, 1);
|
|
|
|
span #{pruneTargetSize[0]} #{pruneTargetSize[1].abbreviation}B
|
|
|
|
+summaryItem("Data Indexes", "Status of available indices currently running in this node")
|
|
ul.list-unstyled.mb-0
|
|
li
|
|
span.me-2 txindex
|
|
if (global.txindexAvailable)
|
|
i.bi-check2.text-success
|
|
else
|
|
span.border-dotted(title="Your node's lack of a 'transaction index' means this explorer will be unable to show all blockchain data. See the project README for more details.", data-bs-toggle="tooltip")
|
|
i.bi-x.text-danger
|
|
|
|
li
|
|
span.me-2 coinstatsindex
|
|
if (getindexinfo && getindexinfo["coinstatsindex"])
|
|
i.bi-check2.text-success
|
|
else
|
|
i.bi-x.text-danger
|
|
|
|
li
|
|
span.me-2 blockfilterindex
|
|
if (getindexinfo && getindexinfo["basic block filter index"])
|
|
i.bi-check2.text-success
|
|
else
|
|
i.bi-x.text-danger
|
|
|
|
|
|
if (getdeploymentinfo && getdeploymentinfo.deployments)
|
|
-
|
|
var forkUrls = {
|
|
"bip34": { "link": "https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki", "title": "Block v2, Height in Coinbase" },
|
|
"bip65": { "link": "https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki", "title": "OP_CHECKLOCKTIMEVERIFY" },
|
|
"bip66": { "link": "https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki", "title": "Strict DER signatures" },
|
|
"csv": { "link": "https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki", "title": "OP_CHECKSEQUENCEVERIFY" },
|
|
"segwit": { "link": "https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki", "title": "Segregated Witness (Consensus layer)" },
|
|
"taproot":{ "link": "https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki", "title": "Taproot: SegWit version 1 spending rules" }
|
|
};
|
|
|
|
+contentSection("Deployments")
|
|
+summaryRow(utils.objectProperties(getdeploymentinfo.deployments).length)
|
|
each item, itemName in getdeploymentinfo.deployments
|
|
// (title, titleDesc, subtitle, subtitleDesc, linkText, linkUrl)
|
|
+summaryItem(itemName, forkUrls[itemName] ? forkUrls[itemName].title : null)
|
|
if (item.active)
|
|
span.me-2
|
|
span.text-success active
|
|
span.text-tiny.text-muted.ms-2 (
|
|
a.border-dotted(href=`./block-height/${item.height}`, title=`${itemName} has been active since block ${item.height.toLocaleString()}`, data-bs-toggle="tooltip") #{item.height.toLocaleString()}
|
|
| +)
|
|
|
|
else
|
|
if (item.type == "bip8") || (item.type == "bip9")
|
|
- var bip = item.type;
|
|
- var bip_status = item[bip].status
|
|
span.me-2
|
|
span.text-warning.text-lowercase #{bip_status}
|
|
small.text-muted.ms-2 (
|
|
a.border-dotted(title=`${itemName.toUpperCase()} ${bip_status.replace("_", " ")} since block ${item[bip].since.toLocaleString()} with BIP${bip.charAt(3)} and LockinOnTimeout=${item[bip].lockinontimeout}`, data-bs-toggle="tooltip") #{item[bip].since}
|
|
| +)
|
|
|
|
if (item.type == "bip9" && item.bip9 && (item.bip9.start_time || item.bip9.timeout))
|
|
div.small.text-muted
|
|
if (item.bip9.start_time)
|
|
span.me-2 start:
|
|
+timestamp(item.bip9.start_time, {includeAgo:false, formatString:"M/D"})
|
|
|
|
if (item.bip9.timeout)
|
|
if (item.bip9.start_time)
|
|
span.me-1 ,
|
|
span.me-2 timeout:
|
|
+timestamp(item.bip9.timeout, {includeAgo:false, formatString:"M/D"})
|
|
|
|
if (item.type == "bip9" && item.bip9 && item.bip9.min_activation_height)
|
|
div.small.text-muted
|
|
span.border-dotted(title="Minimum activation block height", data-bs-toggle="tooltip") min height
|
|
span.me-2 :
|
|
| #{item.bip9.min_activation_height.toLocaleString()}
|
|
|
|
if (forkUrls[itemName])
|
|
small
|
|
a(href=forkUrls[itemName].link, title=`More info about ${itemName}`, data-bs-toggle="tooltip", target="_blank")
|
|
i.bi-box-arrow-up-right.small
|
|
|
|
|
|
// deprecated, as of v23.0, which now has this data in getdeploymentinfo.deployments (see above)
|
|
if (getblockchaininfo.softforks)
|
|
if (getblockchaininfo.bip9_softforks)
|
|
// old format: ~ v0.18.0
|
|
- var softforks = [];
|
|
each item in getblockchaininfo.softforks
|
|
- softforks.push(item);
|
|
|
|
each item, itemName in getblockchaininfo.bip9_softforks
|
|
- item.id = itemName
|
|
- softforks.push(item);
|
|
|
|
+contentSection("Soft Forks")
|
|
+summaryRow(softforks.length)
|
|
each item in softforks
|
|
+summaryItem(item.id)
|
|
each propVal, propName in item
|
|
if (propName == "reject")
|
|
div reject: #{propVal.status}
|
|
|
|
else if (propName == "id")
|
|
else if (propName != "id")
|
|
div #{propName}: #{propVal}
|
|
|
|
else
|
|
// more modern format
|
|
- var forkUrls = {"bip34":"https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki", "bip65":"https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki", "bip66":"https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki", "csv":"https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki", "segwit":"https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki", "taproot":"https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki"};
|
|
|
|
+contentSection("Soft Forks")
|
|
+summaryRow(utils.objectProperties(getblockchaininfo.softforks).length)
|
|
each item, itemName in getblockchaininfo.softforks
|
|
+summaryItem(itemName)
|
|
if (item.active)
|
|
span.me-2
|
|
span.text-success active
|
|
small.text-muted.ms-2 (
|
|
a.border-dotted(href=`./block-height/${item.height}`, title=`${itemName} has been active since block ${item.height.toLocaleString()}`, data-bs-toggle="tooltip") #{item.height.toLocaleString()}
|
|
| +)
|
|
|
|
else if (item.type == "bip8") || (item.type == "bip9")
|
|
- var bip = item.type;
|
|
- var bip_status = item[bip].status
|
|
span.me-2
|
|
span.text-warning.text-lowercase #{bip_status}
|
|
small.text-muted.ms-2 (
|
|
a.border-dotted(title=`${itemName.toUpperCase()} ${bip_status.replace("_", " ")} since block ${item[bip].since.toLocaleString()} with BIP${bip.charAt(3)} and LockinOnTimeout=${item[bip].lockinontimeout}`, data-bs-toggle="tooltip") #{item[bip].since}
|
|
| +)
|
|
|
|
if (forkUrls[itemName])
|
|
small
|
|
a(href=forkUrls[itemName], title=`More info about ${itemName}`, data-bs-toggle="tooltip", target="_blank")
|
|
i.bi-box-arrow-up-right.small
|
|
|
|
if (item.type == "bip9" && item.bip9 && (item.bip9.start_time || item.bip9.timeout))
|
|
div.small.text-muted
|
|
if (item.bip9.start_time)
|
|
span.me-2 start:
|
|
+timestamp(item.bip9.start_time, {includeAgo:false, formatString:"M/D"})
|
|
|
|
if (item.bip9.timeout)
|
|
if (item.bip9.start_time)
|
|
span.me-1 ,
|
|
span.me-2 timeout:
|
|
+timestamp(item.bip9.timeout, {includeAgo:false, formatString:"M/D"})
|
|
|
|
if (item.type == "bip9" && item.bip9 && item.bip9.min_activation_height)
|
|
div.small.text-muted
|
|
span.border-dotted(title="Minimum activation block height", data-bs-toggle="tooltip") min height
|
|
span.me-2 :
|
|
| #{item.bip9.min_activation_height.toLocaleString()}
|
|
|
|
|
|
|
|
|
|
|
|
+contentSection("Network")
|
|
+summaryRow(4)
|
|
+summaryItem("Host", "IP address and port number of RPC node")
|
|
| #{global.rpcClient.options.host}
|
|
span.text-muted :#{global.rpcClient.options.port}
|
|
|
|
+summaryItem("Peers", "Number of peers connected to this node.", null, null, "icon:bi-diagram-3", "./peers", "Details about the peers connected to this node")
|
|
| #{getnetworkinfo.connections.toLocaleString()}
|
|
|
|
if (getnetworkinfo.connections_in)
|
|
br
|
|
span.text-muted (#{getnetworkinfo.connections_in.toLocaleString()} in; #{getnetworkinfo.connections_out.toLocaleString()} out)
|
|
|
|
+summaryItem("Upload", "Total bytes sent since this node started")
|
|
- var upData = utils.formatLargeNumber(getnettotals.totalbytessent, 1);
|
|
- var upRateData = utils.formatLargeNumber(getnettotals.totalbytessent / uptimeSeconds, 1);
|
|
|
|
i.bi-arrow-up.me-2
|
|
span.me-2 #{upData[0]} #{upData[1].abbreviation}B
|
|
small.text-muted (#{upRateData[0]} #{upRateData[1].abbreviation}B/s)
|
|
|
|
+summaryItem("Download", "Total bytes received since this node started")
|
|
- var downData = utils.formatLargeNumber(getnettotals.totalbytesrecv, 1);
|
|
- var downRateData = utils.formatLargeNumber(getnettotals.totalbytesrecv / uptimeSeconds, 1);
|
|
|
|
i.bi-arrow-down.me-2
|
|
span.me-2 #{downData[0]} #{downData[1].abbreviation}B
|
|
small.text-muted (#{downRateData[0]} #{downRateData[1].abbreviation}B/s)
|
|
|
|
if (getnetworkinfo.networks)
|
|
hr.my-4
|
|
|
|
+summaryRow(getnetworkinfo.networks.length)
|
|
each item, index in getnetworkinfo.networks
|
|
+summaryItem(item.name)
|
|
div
|
|
if (item.proxy)
|
|
small.text-muted.me-2 (#{item.proxy})
|
|
|
|
if (item.reachable)
|
|
span.border-dotted(title="Reachable", data-bs-toggle="tooltip")
|
|
i.bi-check2.text-success
|
|
|
|
else
|
|
span.border-dotted(title="Unreachable", data-bs-toggle="tooltip")
|
|
i.bi-x.text-danger
|
|
|
|
|
|
if (getnetworkinfo.localaddresses)
|
|
hr.my-4
|
|
|
|
.ms-3
|
|
+summaryTitle("Addresses")
|
|
.lead
|
|
ul
|
|
each item, index in getnetworkinfo.localaddresses
|
|
li
|
|
span.me-2 #{item.address}:#{item.port}
|
|
small.text-muted (score: #{item.score.toLocaleString()})
|
|
|
|
if (getnetworkinfo.localaddresses.length == 0)
|
|
li None
|
|
|
|
|
|
|
|
|
|
+pageTab("JSON")
|
|
|
|
ul.nav.nav-pills.mb-3
|
|
li.nav-item
|
|
a.nav-link.active(data-bs-toggle="tab", href="#tab-getblockchaininfo", role="tab") getblockchaininfo
|
|
li.nav-item
|
|
a.nav-link(data-bs-toggle="tab", href="#tab-getnettotals", role="tab") getnettotals
|
|
li.nav-item
|
|
a.nav-link(data-bs-toggle="tab", href="#tab-getnetworkinfo", role="tab") getnetworkinfo
|
|
li.nav-item
|
|
a.nav-link(data-bs-toggle="tab", href="#tab-getindexinfo", role="tab") getindexinfo
|
|
|
|
div.tab-content
|
|
div.tab-pane.active(id="tab-getblockchaininfo", role="tabpanel")
|
|
+contentSection("getblockchaininfo")
|
|
pre
|
|
code.json(data-lang="json") #{JSON.stringify(getblockchaininfo, null, 4)}
|
|
|
|
|
|
div.tab-pane(id="tab-getnettotals", role="tabpanel")
|
|
+contentSection("getnettotals")
|
|
pre
|
|
code.json(data-lang="json") #{JSON.stringify(getnettotals, null, 4)}
|
|
|
|
|
|
div.tab-pane(id="tab-getnetworkinfo", role="tabpanel")
|
|
+contentSection("getnetworkinfo")
|
|
pre
|
|
code.json(data-lang="json") #{JSON.stringify(getnetworkinfo, null, 4)}
|
|
|
|
|
|
div.tab-pane(id="tab-getindexinfo", role="tabpanel")
|
|
+contentSection("getindexinfo")
|
|
pre
|
|
code.json(data-lang="json") #{JSON.stringify(global.getindexinfo, null, 4)}
|
|
|
|
|