Skip to content

Instantly share code, notes, and snippets.

@jwinterm
Last active March 30, 2020 07:11
Show Gist options
  • Save jwinterm/c417d05d819bbefd22d0 to your computer and use it in GitHub Desktop.
Save jwinterm/c417d05d819bbefd22d0 to your computer and use it in GitHub Desktop.
Monero pool hashrate checker
#!/usr/bin/env python
import requests
import json
import re
import datetime
import sys
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
from math import cos, sin, pi
# Get time and make string for title
utc = datetime.datetime.utcnow()
utc_string = utc.strftime("%Y-%m-%d %H:%M:%S")
# Define regular pool list
server_dict = {
'cryptonotepool.org.uk': 'http://80.71.13.55:8117/stats',
'extremehash.com': 'http://107.170.148.200:8117/stats',
'minexmr.com': 'http://pool.minexmr.com:8117/stats',
'monero.coolmining.club': 'http://xmr1.coolmining.club:8117/stats',
'monero.crypto-pool.fr': 'http://xmr.crypto-pool.fr:8090/stats',
'monero.graymines.net': 'http://monero.graymines.net:8117/stats',
'monero.kippo.eu': 'http://monero.kippo.eu:8117/stats',
'monero.xminingpool.com': 'http://xmr.xminingpool.com:2117/stats',
'moneropool.com': 'http://api.moneropool.com:8080/stats',
'moneropool.org': 'http://192.99.44.150:8117/stats',
'moneropool.net': 'http://moneropool.net:8118/stats',
'moneropool.ru': 'http://alxxxer.ru:8200/stats',
# 'mro.bitnonce.com': 'http://mro.bitnonce.com/api/stats', # for some reason hangs
'mro.extremepool.org': 'http://mro.extremepool.org:8117/stats',
'nomp.freeyy.me': 'http://nomp.freeyy.me:8117/stats',
'pool.cryptograben.com': 'http://xmr.cryptograben.com:8117/stats',
'www2.coinmine.pl': 'http://mine1.coinmine.pl:8117/stats',
# 'xmr.ext-pool.net': 'http://xmr.ext-pool.net:8417/stats', # for some reason hangs
'xmr.farm': 'http://xmr.farm:8117/stats',
'xmr.alimabi.cn': 'http://xmrapinew.alimabi.cn:80/stats',
'xmr.hashinvest.net': 'http://xmr.hashinvest.net:8117/stats',
'xmr.poolto.be': 'http://mro.poolto.be:8117/stats',
'xmr.prohash.net': 'http://xmr.prohash.net:8117/stats'
}
hashrate_list = [] #List of pool hashrates
name_list = [] #Ordered (to match hashrate) list of pool names
responded = 0
# Connect to each server and get pool hashrate
for key, val in server_dict.items():
print "Trying: " + key
try:
resp = requests.get(val, timeout=13)
output = json.loads(resp.text)
if float(output[u'pool'][u'hashrate']) != 0:
name_list.append(key)
hashrate_list.append(float(output[u'pool'][u'hashrate'])/1e6)
print key + " responded"
responded += 1
except:
print key + " did not respond"
# Use last pool connects data to calculate network hashrate from diff
network_hash = float(output[u'network'][u'difficulty'])/60e6
# Begin hack for dwarfpool
dwarf_url = 'http://dwarfpool.com/'
resp = requests.get(dwarf_url)
lines = resp.text.encode("utf-8").split('\n')
target_line = -1
# Find XMR pool data and then grab hashrate
try:
for line_number, line in enumerate(lines):
if "Code: XMR" in line:
target_line = line_number + 3
if line_number == target_line:
name_list.append('dwarfpool.com')
hashrate_list.append(float(re.sub("[^0-9.]", "", line))/1e3)
responded += 1
print "dwarfpool responded"
except:
print "dwarfpool did not respond"
print "Out of {0} pools, {1} responded.".format(len(server_dict), responded)
# Calculate unknown hash
known_hash = sum(hashrate_list)
unknown_hash = network_hash - known_hash
print "Unknown hash = {0}".format(unknown_hash)
if unknown_hash < 0:
unknown_hash = abs(unknown_hash)
print "WARNING - negative nethash"
name_list.append('Unknown/Minergate')
hashrate_list.append(unknown_hash)
# Calculate normalized hash rates
normalized_list = [x/network_hash for x in hashrate_list]
# Setup lists
smallpools_names = []
smallpools_hash = []
smallpools_normhash = []
majorpools_names = []
majorpools_hash = []
majorpools_normhash = []
smalllabellist = []
majorlabellist = []
# Print pools and separate to small or major
print "Total network hash = " + str(network_hash)
for idx, val in enumerate(hashrate_list):
print name_list[idx], val
if 0.0003 < normalized_list[idx] < 0.03:
smallpools_names.append(name_list[idx])
smallpools_hash.append(val)
smallpools_normhash.append(normalized_list[idx])
smalllabellist.append("{0} {1:.0f} kh/s".format(
name_list[idx], val*1e3))
elif normalized_list[idx] >= 0.03:
majorpools_names.append(name_list[idx])
majorpools_hash.append(val)
majorpools_normhash.append(normalized_list[idx])
majorlabellist.append("{0} {1:.2f} Mh/s".format(
name_list[idx], val))
# Make normalized small hash for plot
smallpool_hashtotal = sum(smallpools_hash)
smallpool_normtotal = smallpool_hashtotal/network_hash
smallpool_smallnorm = [x/smallpool_hashtotal for x in smallpools_hash]
# Add small pool total to major pools
majorpools_names.append('Small pools (<3.5%)')
majorpools_hash.append(smallpool_hashtotal)
majorpools_normhash.append(smallpool_normtotal)
majorlabellist.append("{0} {1:.2f} Mh/s".format(
'Small pools', smallpool_hashtotal))
# Make color list
colors = ('b', 'g', 'r', 'c', 'm', 'y', 'w', 'DeepPink', 'ForestGreen')
# Reorder slices to try and accomodate tiny pools
tmp_norm, tmp_names = (list(t) for t in zip(*sorted(zip(majorpools_normhash, majorlabellist))))
large_norm, large_names = tmp_norm[:len(tmp_norm) / 2], tmp_names[:len(tmp_names) / 2]
small_norm, small_names = tmp_norm[len(tmp_norm) / 2:], tmp_names[len(tmp_names) / 2:]
reordered_norm = large_norm[::2] + small_norm[::2] + large_norm[1::2] + small_norm[1::2]
reordered_names = large_names[::2] + small_names[::2] + large_names[1::2] + small_names[1::2]
#Plot and save major pools
plt.figure(1, figsize=(12,10))
ax1 = plt.axes([0.25, 0.2, 0.5, 0.5])
pie_wedge_collection = ax1.pie(reordered_norm,
# explode=[0.07]*len(majorlabellist),
explode=[0.026*(1/(z+0.001)**0.4) for z in reordered_norm],
labels=reordered_names,
labeldistance=1.07,
autopct='%1.0f%%',
shadow=True,
startangle=90,
colors=colors)
for pie_wedge in pie_wedge_collection[0]:
pie_wedge.set_edgecolor('0.3')
for i in pie_wedge_collection[1]:
i.set_fontsize('small')
plt.title('Monero network hashrate: {0:.1f} Mh/s\nTime recorded:{1}'.format(network_hash, utc_string))
plt.savefig('bigpools.png')
plt.close()
# Reorder slices to try and accomodate tiny pools
tmp_norm, tmp_names = (list(t) for t in zip(*sorted(zip(smallpool_smallnorm, smalllabellist))))
large_norm, large_names = tmp_norm[:len(tmp_norm) / 2], tmp_names[:len(tmp_names) / 2]
small_norm, small_names = tmp_norm[len(tmp_norm) / 2:], tmp_names[len(tmp_names) / 2:]
reordered_norm = large_norm[::2] + small_norm[::2] + large_norm[1::2] + small_norm[1::2]
reordered_names = large_names[::2] + small_names[::2] + large_names[1::2] + small_names[1::2]
# Plot and save minor pool figure
plt.figure(2, figsize=(12,10))
ax2 = plt.axes([0.25, 0.2, 0.5, 0.5])
p = ax2.pie(reordered_norm,
# explode=[0.08]*len(smalllabellist),
explode=[0.036*(1/(z+0.001)**0.4) for z in reordered_norm],
labels=reordered_names,
labeldistance=1.05,
autopct='%1.1f%%',
shadow=True,
# startangle=90,
colors=colors)
for i in p[1]:
i.set_fontsize('small')
plt.title('Monero smaller pools (<3%) hash rate: {0:.0f} kh/s'.format(smallpool_hashtotal*1e3))
plt.savefig('smallpools.png')
plt.close()
@Naxerate
Copy link

i think it's 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment