Last active
April 13, 2019 21:19
-
-
Save chris-belcher/ed23486f4d5cd7bd5190db074bf7cbaa to your computer and use it in GitHub Desktop.
getpeerinfo-parse.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#run with | |
#/path/to/bitcoin/bin/bitcoin-cli getpeerinfo | python getpeerinfo-parse.py | |
#output looks like | |
#zlato@zlato:~/bitcoin-0.17.1/bin$ ./bitcoin-cli getpeerinfo | python getpeerinfo-parse.py | |
#services L=NODE_NETWORK_LIMITED N=NODE_NETWORK G=NODE_GETUTXO B=NODE_BLOOM R=NODE_REPLACE_BY_FEE W=NODE_WITNESS X=NODE_XTHIN U=UNKNOWN | |
# id addr user-agent iB se re conn'd ping serv lastr | |
# # host oO nt cv MMDD-HHMM msec ices HHMMSS | |
# 414 27.102.130.92 /Satoshi:0.17.1/ oF 20M 28M 0411-2005 358 LNBW 121021 | |
# 417 139.59.34.217 /Satoshi:0.15.1/ oF 17M 46M 0411-2006 163 NBW 121019 | |
# 421 24.241.102.26 /Satoshi:0.17.1/ oF 17M 46M 0411-2007 131 LNBW 121010 | |
# 425 127.0.0.1 /bitnodes.bitcoin-russia.ru:0.0.1f/ iF 21M 306k 0411-2012 557 121003 | |
# 429 127.0.0.1 /Satoshi:0.13.2/ iF 11M 66M 0411-2019 242 NBW 121019 | |
# 446 62.77.158.217 /Satoshi:0.16.0/ oF 17M 54M 0411-2048 65 LNBW 121021 | |
# 451 127.0.0.1 /Satoshi:0.16.3/ iF 21M 19M 0411-2054 516 LNBW 121016 | |
# 527 127.0.0.1 /Satoshi:0.17.0.1/ iF 46M 15M 0411-2305 335 LNBW 121020 | |
# 580 127.0.0.1 /Satoshi:0.17.1/ iT 187k 105k 0412-0035 292 LNBW 120905 | |
# 646 127.0.0.1 /Satoshi:0.17.0.1/ iF 26M 14M 0412-0238 517 LNBW 121019 | |
# 774 127.0.0.1 /Satoshi:0.17.0.1/ iF 11M 33M 0412-0642 212 LNBW 121020 | |
# 1160 127.0.0.1 /Satoshi:0.17.1/ iF 16M 7M 0412-1817 309 LNBW 121021 | |
# 1204 192.223.31.132 /Satoshi:0.17.1/ oF 7M 14M 0412-1950 81 LNBW 121017 | |
# 1311 93.104.213.244 /Satoshi:0.17.1/ oF 5M 11M 0412-2304 35 LNBW 121020 | |
# 1323 113.52.135.125 /Satoshi:0.17.0.1/ oF 5M 6M 0412-2331 267 LNBW 121020 | |
# 1377 127.0.0.1 /Satoshi:0.17.0/ iF 15M 4M 0413-0057 1066 LNBW 121021 | |
# 1470 127.0.0.1 /Satoshi:0.17.99/ iF 13M 3M 0413-0339 710 LNBW 121017 | |
# 1473 127.0.0.1 /Satoshi:0.17.1/ iF 7M 4M 0413-0344 232 LBW 121020 | |
# 1513 127.0.0.1 /Satoshi:0.17.0.1/ iF 5M 3M 0413-0502 603 LNBW 121020 | |
# 1550 127.0.0.1 /Satoshi:0.17.1/ iF 2M 5M 0413-0611 455 LNBW 121019 | |
# 1575 127.0.0.1 /Satoshi:0.17.1/Knots:20181229/ iF 10M 2M 0413-0655 760 LBW 121021 | |
# 1583 127.0.0.1 /Satoshi:0.17.1/ iF 2M 1M 0413-0710 705 LNBW 121021 | |
# 1757 52.39.235.86 /Satoshi:0.16.3/ oF 135k 105k 0413-1155 -1 LNBW 121020 | |
#23 connections | |
#explainations of some columns | |
#id = connection id | |
#io = incoming (i) or outgoing (o) connection | |
#BO = blocksonly, T=enabled, F=not enabled | |
import sys, json, pprint, datetime | |
from math import log | |
data = "".join(sys.stdin) | |
dataj = json.loads(data) | |
def tsstr_date(s): | |
return datetime.datetime.fromtimestamp(s).strftime("%m%d-%H%M") | |
def tsstr_time(s): | |
return datetime.datetime.fromtimestamp(s).strftime("%H%M%S") | |
unit_list = zip(['b', 'k', 'M', 'G', 'T', 'P'], [0, 0, 0, 0, 0, 0]) | |
#unit_list = zip(['b', 'k', 'M', 'G', 'T', 'P'], [0, 0, 1, 2, 2, 2]) | |
def bytes_fmt(num): | |
"""Human friendly file size""" | |
if num > 1: | |
exponent = min(int(log(num, 1024)), len(unit_list) - 1) | |
quotient = float(num) / 1024**exponent | |
unit, num_decimals = unit_list[exponent] | |
format_string = '{:.%sf}{}' % (num_decimals) | |
return format_string.format(quotient, unit) | |
if num == 0: | |
return '0 bytes' | |
if num == 1: | |
return '1 byte' | |
#https://github.com/bitcoin/bitcoin/blob/master/src/protocol.h | |
service_flags = {1: ("NODE_NETWORK", "N"), 1<<1: ("NODE_GETUTXO", "G"), 1<<2: ("NODE_BLOOM", "B"), | |
1<<3:("NODE_WITNESS", "W"), 1<<4: ("NODE_XTHIN", "X"), 1<<10: ("NODE_NETWORK_LIMITED", "L"), | |
1<<26: ("NODE_REPLACE_BY_FEE", "R")} | |
print("services " + " ".join([abr + "=" + name for name, abr in service_flags.values()]) + " U=UNKNOWN") | |
def make_service_bits_str(s): | |
#TODO split this up on many lines so its more readable | |
return "".join(filter(lambda l: len(l) > 0, [abr if s & bits != 0 else "" for bits, (name, abr) in service_flags.iteritems()] + ["U" if s & ~reduce(lambda a, b: a|b, service_flags.keys()) else ""])) | |
formatstr = "% 6s % 22s %-56s % 1s% 1s % 4s % 4s % 9s %4s % 5s % 6s" | |
print formatstr % ("id", "addr", "user-agent", "i", "B", "se", "re", "conn'd", "ping", "serv", "lastr") | |
print formatstr % ( "#", "host", "", "o", "O", "nt", "cv", "MMDD-HHMM", "msec", "ices", "HHMMSS") | |
for p in dataj: | |
print(formatstr % ((p['id']), p['addr'][:p['addr'].index(':')], p['subver'], | |
("i" if p["inbound"] else "o"), | |
("F" if p["relaytxes"] else "T"), | |
bytes_fmt(p["bytessent"]), bytes_fmt(p["bytesrecv"]), | |
tsstr_date(p['conntime']), str(int(p.get('pingtime', -0.001)*1000)), | |
make_service_bits_str(int(p["services"], 16)), tsstr_time(p['lastrecv']))) | |
print str(len(dataj)) + ' connections' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
One could also host this on a local apache server to get a nice interface with connected peers, graphs, ...