-
Notifications
You must be signed in to change notification settings - Fork 2
/
mining.py
115 lines (87 loc) · 3.37 KB
/
mining.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import threading
import time
import server
shares_of_current_block = 0
miners = {} # "account": number_of_shares
shares = {} # dict of pplns_shares objects, every account has an element + pool has one
#TODO miner object for every miner/account, collect every miner related function to that
#TODO future feature: collect shares worker-by-worker for detailed stat
hr_shares = {} # shares log for hashrate calculation for each account; example = {"1111":{"1":[timestamp1, timestamp2, timestamp3, ...], "32":[timestamp1, timestamp2, timestamp3, ..]}}
hr_avrg_shares = 30 # number of shares to calculated average hashrate
share_timeout = 240 # shares older than this will be deleted
class miner_conn():
def __init__(self, connection, address):
self.conn = connection
self.addr = address
self.timestamps = {}
def set_account(self, account):
self.account = account
def add_share(self, timestamp, difficulty):
self.timestamps[timestamp] = difficulty
miner_conns = []
def print_stat():
global shares_of_current_block, miner_conns
print("Number of connected miners: " + str(len(miner_conns)) + " Running threads: " + str(threading.active_count()))
threading.Timer(60, print_stat).start()
def add_share_for_hr_calc(account, difficulty):
global hr_shares
account = str(account)
difficulty = str(difficulty)
diffs = []
for diff in server.get_server_diffs():
diffs.append(str(diff))
if account in hr_shares:
for diff in diffs:
if len(hr_shares[account][diff]) == hr_avrg_shares:
del hr_shares[account][diff][0]
else:
hr_shares[account] = {}
for diff in diffs:
hr_shares[account][diff] = []
hr_shares[account][difficulty].append(time.time())
def get_hr(account):
"""
Get hashrate for an account.
Hashrate formula:
hashrate = difficulty * 2**32 / avrg_share_time
:param account:
:return:
"""
global hr_shares
account = str(account) # using account as str
if account not in hr_shares:
return 0
diffs = []
for diff in server.get_server_diffs(): # using diffs as str
diffs.append(str(diff))
hrs = [] # hashrate for every difficulty, then sum them for account hashrate
for diff in diffs:
if len(hr_shares[account][diff]) < 2: # can't calculate from 0 or 1 shares
continue
# delete old shares
new_timestamps = []
for i in range(len(hr_shares[account][diff])):
ts = hr_shares[account][diff][i]
if (time.time() - ts) <= share_timeout:
new_timestamps.append(ts)
hr_shares[account][diff] = new_timestamps
if len(hr_shares[account][diff]) < 2: # can't calculate from 0 or 1 shares
continue
# get average share time
last_share = hr_shares[account][diff][-1]
first_share = hr_shares[account][diff][0]
avrg_time = (last_share - first_share) / (len(hr_shares[account][diff]) - 1)
new_hr = float(diff) * 2**32 / avrg_time
hrs.append(new_hr)
sum_hr = 0
for hr in hrs:
sum_hr += hr
return sum_hr
def get_pool_hr():
global hr_shares
pool_hr = 0
for account in hr_shares:
pool_hr += get_hr(account)
return pool_hr
def No_miners():
return len(miner_conns)