2013-06-04 05:14:24 +02:00
|
|
|
#import shared
|
|
|
|
#import time
|
|
|
|
#from multiprocessing import Pool, cpu_count
|
2013-05-30 22:25:42 +02:00
|
|
|
import hashlib
|
|
|
|
from struct import unpack, pack
|
2013-06-05 23:20:34 +02:00
|
|
|
import sys
|
2013-08-23 19:20:07 +02:00
|
|
|
from shared import config, frozen
|
2014-08-27 09:14:32 +02:00
|
|
|
import shared
|
2015-06-20 09:54:15 +02:00
|
|
|
import openclpow
|
2015-11-05 20:41:41 +01:00
|
|
|
import os
|
|
|
|
import ctypes
|
|
|
|
|
2015-11-09 17:15:05 +01:00
|
|
|
if frozen == "macosx_app":
|
|
|
|
curdir = os.environ.get("RESOURCEPATH")
|
|
|
|
elif frozen: # windows
|
|
|
|
curdir = sys._MEIPASS
|
|
|
|
else:
|
|
|
|
curdir = os.path.dirname(__file__)
|
2015-11-05 20:41:41 +01:00
|
|
|
bitmsglib = 'bitmsghash.so'
|
|
|
|
if "win32" == sys.platform:
|
|
|
|
if ctypes.sizeof(ctypes.c_voidp) == 4:
|
|
|
|
bitmsglib = 'bitmsghash32.dll'
|
|
|
|
else:
|
|
|
|
bitmsglib = 'bitmsghash64.dll'
|
|
|
|
try:
|
2015-11-07 18:39:55 +01:00
|
|
|
bso = ctypes.WinDLL(os.path.join(curdir, "bitmsghash", bitmsglib))
|
2015-11-05 20:41:41 +01:00
|
|
|
except:
|
|
|
|
bso = None
|
|
|
|
else:
|
|
|
|
try:
|
2015-11-07 18:39:55 +01:00
|
|
|
bso = ctypes.CDLL(os.path.join(curdir, "bitmsghash", bitmsglib))
|
2015-11-05 20:41:41 +01:00
|
|
|
except:
|
|
|
|
bso = None
|
|
|
|
if bso:
|
|
|
|
try:
|
|
|
|
bmpow = bso.BitmessagePOW
|
|
|
|
bmpow.restype = ctypes.c_ulonglong
|
|
|
|
except:
|
|
|
|
bmpow = None
|
2015-11-08 11:44:19 +01:00
|
|
|
else:
|
|
|
|
bmpow = None
|
2013-06-03 07:04:22 +02:00
|
|
|
|
|
|
|
def _set_idle():
|
2013-06-05 23:20:34 +02:00
|
|
|
if 'linux' in sys.platform:
|
2013-06-18 18:56:03 +02:00
|
|
|
import os
|
2013-06-23 21:52:39 +02:00
|
|
|
os.nice(20) # @UndefinedVariable
|
2013-06-05 23:20:34 +02:00
|
|
|
else:
|
2013-06-18 18:56:03 +02:00
|
|
|
try:
|
|
|
|
sys.getwindowsversion()
|
2013-06-23 21:52:39 +02:00
|
|
|
import win32api,win32process,win32con # @UnresolvedImport
|
2013-06-18 18:56:03 +02:00
|
|
|
pid = win32api.GetCurrentProcessId()
|
|
|
|
handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
|
|
|
|
win32process.SetPriorityClass(handle, win32process.IDLE_PRIORITY_CLASS)
|
|
|
|
except:
|
|
|
|
#Windows 64-bit
|
|
|
|
pass
|
2013-05-30 22:25:42 +02:00
|
|
|
|
2013-05-29 22:01:12 +02:00
|
|
|
def _pool_worker(nonce, initialHash, target, pool_size):
|
2013-06-03 07:04:22 +02:00
|
|
|
_set_idle()
|
2013-08-20 10:43:30 +02:00
|
|
|
trialValue = float('inf')
|
2013-05-29 22:01:12 +02:00
|
|
|
while trialValue > target:
|
2013-05-30 22:25:42 +02:00
|
|
|
nonce += pool_size
|
|
|
|
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
|
2013-05-29 22:01:12 +02:00
|
|
|
return [trialValue, nonce]
|
|
|
|
|
2013-06-05 23:20:34 +02:00
|
|
|
def _doSafePoW(target, initialHash):
|
2015-06-20 09:54:15 +02:00
|
|
|
print "Safe POW\n"
|
2013-06-04 05:14:24 +02:00
|
|
|
nonce = 0
|
2013-08-20 10:43:30 +02:00
|
|
|
trialValue = float('inf')
|
2013-06-04 05:14:24 +02:00
|
|
|
while trialValue > target:
|
|
|
|
nonce += 1
|
|
|
|
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
|
|
|
|
return [trialValue, nonce]
|
2013-06-05 23:20:34 +02:00
|
|
|
|
|
|
|
def _doFastPoW(target, initialHash):
|
2015-06-20 09:54:15 +02:00
|
|
|
print "Fast POW\n"
|
2013-06-05 23:20:34 +02:00
|
|
|
import time
|
|
|
|
from multiprocessing import Pool, cpu_count
|
|
|
|
try:
|
2013-05-30 22:25:42 +02:00
|
|
|
pool_size = cpu_count()
|
2013-05-29 22:01:12 +02:00
|
|
|
except:
|
2013-05-30 22:25:42 +02:00
|
|
|
pool_size = 4
|
|
|
|
try:
|
|
|
|
maxCores = config.getint('bitmessagesettings', 'maxcores')
|
|
|
|
except:
|
|
|
|
maxCores = 99999
|
|
|
|
if pool_size > maxCores:
|
|
|
|
pool_size = maxCores
|
2013-05-29 22:01:12 +02:00
|
|
|
pool = Pool(processes=pool_size)
|
|
|
|
result = []
|
|
|
|
for i in range(pool_size):
|
2013-05-30 22:25:42 +02:00
|
|
|
result.append(pool.apply_async(_pool_worker, args = (i, initialHash, target, pool_size)))
|
2013-05-29 22:01:12 +02:00
|
|
|
while True:
|
2013-12-02 07:35:34 +01:00
|
|
|
if shared.shutdown >= 1:
|
2013-05-30 22:42:24 +02:00
|
|
|
pool.terminate()
|
2013-06-19 06:51:31 +02:00
|
|
|
while True:
|
|
|
|
time.sleep(10) # Don't let this thread return here; it will return nothing and cause an exception in bitmessagemain.py
|
2013-05-30 22:42:24 +02:00
|
|
|
return
|
2013-05-30 22:25:42 +02:00
|
|
|
for i in range(pool_size):
|
|
|
|
if result[i].ready():
|
|
|
|
result = result[i].get()
|
|
|
|
pool.terminate()
|
2013-06-06 19:30:57 +02:00
|
|
|
pool.join() #Wait for the workers to exit...
|
2013-05-30 22:25:42 +02:00
|
|
|
return result[0], result[1]
|
2013-06-05 23:20:34 +02:00
|
|
|
time.sleep(0.2)
|
2015-11-05 20:41:41 +01:00
|
|
|
def _doCPoW(target, initialHash):
|
|
|
|
h = initialHash
|
|
|
|
m = target
|
|
|
|
out_h = ctypes.pointer(ctypes.create_string_buffer(h, 64))
|
|
|
|
out_m = ctypes.c_ulonglong(m)
|
|
|
|
print "C PoW start"
|
|
|
|
nonce = bmpow(out_h, out_m)
|
|
|
|
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
|
|
|
|
print "C PoW done"
|
|
|
|
return [trialValue, nonce]
|
2013-05-29 22:01:12 +02:00
|
|
|
|
2015-10-02 15:04:16 +02:00
|
|
|
def _doGPUPoW(target, initialHash):
|
2015-11-05 20:41:41 +01:00
|
|
|
print "GPU PoW start"
|
2015-06-20 09:54:15 +02:00
|
|
|
nonce = openclpow.do_opencl_pow(initialHash.encode("hex"), target)
|
2015-01-19 18:39:02 +01:00
|
|
|
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
|
|
|
|
#print "{} - value {} < {}".format(nonce, trialValue, target)
|
2015-11-05 20:41:41 +01:00
|
|
|
print "GPU PoW done"
|
2015-01-19 18:39:02 +01:00
|
|
|
return [trialValue, nonce]
|
|
|
|
|
2013-06-05 23:20:34 +02:00
|
|
|
def run(target, initialHash):
|
2015-01-21 18:38:25 +01:00
|
|
|
target = int(target)
|
2015-09-30 10:22:41 +02:00
|
|
|
if shared.safeConfigGetBoolean('bitmessagesettings', 'opencl') and openclpow.has_opencl():
|
2015-10-02 15:04:16 +02:00
|
|
|
# trialvalue1, nonce1 = _doGPUPoW(target, initialHash)
|
|
|
|
# trialvalue, nonce = _doFastPoW(target, initialHash)
|
|
|
|
# print "GPU: %s, %s" % (trialvalue1, nonce1)
|
|
|
|
# print "Fast: %s, %s" % (trialvalue, nonce)
|
|
|
|
# return [trialvalue, nonce]
|
2015-11-05 20:41:41 +01:00
|
|
|
try:
|
|
|
|
return _doGPUPoW(target, initialHash)
|
|
|
|
except:
|
2015-11-09 17:15:05 +01:00
|
|
|
pass # fallback
|
|
|
|
if bmpow:
|
|
|
|
try:
|
|
|
|
return _doCPoW(target, initialHash)
|
|
|
|
except:
|
|
|
|
pass # fallback
|
2015-11-05 20:41:41 +01:00
|
|
|
if frozen == "macosx_app" or not frozen:
|
2015-11-09 17:15:05 +01:00
|
|
|
# on my (Peter Surda) Windows 10, Windows Defender
|
|
|
|
# does not like this and fights with PyBitmessage
|
|
|
|
# over CPU, resulting in very slow PoW
|
|
|
|
try:
|
|
|
|
return _doFastPoW(target, initialHash)
|
|
|
|
except:
|
|
|
|
pass #fallback
|
|
|
|
return _doSafePoW(target, initialHash)
|