Format proofofwork once again

This commit is contained in:
Lee Miller 2023-10-02 02:11:06 +03:00
parent 3b6db99152
commit a84168f273
Signed by untrusted user: lee.miller
GPG Key ID: 4F97A5EA88F4AB63

View File

@ -1,9 +1,10 @@
# pylint: disable=too-many-branches,too-many-statements,protected-access
""" """
Proof of work calculation Proof of work calculation
""" """
# pylint: disable=import-outside-toplevel
import ctypes import ctypes
import hashlib
import os import os
import subprocess # nosec B404 import subprocess # nosec B404
import sys import sys
@ -16,12 +17,12 @@ import openclpow
import paths import paths
import queues import queues
import state import state
import tr
from bmconfigparser import config from bmconfigparser import config
from debug import logger from debug import logger
from defaults import ( from defaults import (
networkDefaultProofOfWorkNonceTrialsPerByte, networkDefaultProofOfWorkNonceTrialsPerByte,
networkDefaultPayloadLengthExtraBytes) networkDefaultPayloadLengthExtraBytes)
from tr import _translate
bitmsglib = 'bitmsghash.so' bitmsglib = 'bitmsghash.so'
@ -83,10 +84,13 @@ def _set_idle():
import win32api import win32api
import win32process import win32process
import win32con import win32con
pid = win32api.GetCurrentProcessId()
handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid) handle = win32api.OpenProcess(
win32process.SetPriorityClass(handle, win32process.IDLE_PRIORITY_CLASS) win32con.PROCESS_ALL_ACCESS, True,
except: # nosec B110 # noqa:E722 # pylint:disable=bare-except win32api.GetCurrentProcessId())
win32process.SetPriorityClass(
handle, win32process.IDLE_PRIORITY_CLASS)
except: # nosec B110 # noqa:E722 pylint:disable=bare-except
# Windows 64-bit # Windows 64-bit
pass pass
@ -105,11 +109,11 @@ def _pool_worker(nonce, initialHash, target, pool_size):
while trialValue > target: while trialValue > target:
nonce += pool_size nonce += pool_size
trialValue = trial_value(nonce, initialHash) trialValue = trial_value(nonce, initialHash)
return [trialValue, nonce] return trialValue, nonce
def _doSafePoW(target, initialHash): def _doSafePoW(target, initialHash):
logger.debug("Safe PoW start") logger.debug('Safe PoW start')
nonce = 0 nonce = 0
trialValue = float('inf') trialValue = float('inf')
while trialValue > target and state.shutdown == 0: while trialValue > target and state.shutdown == 0:
@ -117,35 +121,33 @@ def _doSafePoW(target, initialHash):
trialValue = trial_value(nonce, initialHash) trialValue = trial_value(nonce, initialHash)
if state.shutdown != 0: if state.shutdown != 0:
raise StopIteration("Interrupted") raise StopIteration("Interrupted")
logger.debug("Safe PoW done") logger.debug('Safe PoW done')
return [trialValue, nonce] return trialValue, nonce
def _doFastPoW(target, initialHash): def _doFastPoW(target, initialHash):
logger.debug("Fast PoW start") # pylint:disable=bare-except
logger.debug('Fast PoW start')
from multiprocessing import Pool, cpu_count from multiprocessing import Pool, cpu_count
try: try:
pool_size = cpu_count() pool_size = cpu_count()
except: # noqa:E722 except: # noqa:E722
pool_size = 4 pool_size = 4
try: maxCores = config.safeGetInt('bitmessagesettings', 'maxcores', 99999)
maxCores = config.getint('bitmessagesettings', 'maxcores') pool_size = min(pool_size, maxCores)
except: # noqa:E722
maxCores = 99999
if pool_size > maxCores:
pool_size = maxCores
pool = Pool(processes=pool_size) pool = Pool(processes=pool_size)
result = [] result = []
for i in range(pool_size): for i in range(pool_size):
result.append(pool.apply_async(_pool_worker, args=(i, initialHash, target, pool_size))) result.append(pool.apply_async(
_pool_worker, args=(i, initialHash, target, pool_size)))
while True: while True:
if state.shutdown > 0: if state.shutdown != 0:
try: try:
pool.terminate() pool.terminate()
pool.join() pool.join()
except: # nosec B110 # noqa:E722 # pylint:disable=bare-except except: # nosec B110 # noqa:E722
pass pass
raise StopIteration("Interrupted") raise StopIteration("Interrupted")
for i in range(pool_size): for i in range(pool_size):
@ -159,7 +161,7 @@ def _doFastPoW(target, initialHash):
result = result[i].get() result = result[i].get()
pool.terminate() pool.terminate()
pool.join() pool.join()
logger.debug("Fast PoW done") logger.debug('Fast PoW done')
return result[0], result[1] return result[0], result[1]
time.sleep(0.2) time.sleep(0.2)
@ -170,70 +172,67 @@ def _doCPoW(target, initialHash):
m = target m = target
out_h = ctypes.pointer(ctypes.create_string_buffer(h, 64)) out_h = ctypes.pointer(ctypes.create_string_buffer(h, 64))
out_m = ctypes.c_ulonglong(m) out_m = ctypes.c_ulonglong(m)
logger.debug("C PoW start") logger.debug('C PoW start')
nonce = bmpow(out_h, out_m) nonce = bmpow(out_h, out_m)
trialValue = trial_value(nonce, initialHash) trialValue = trial_value(nonce, initialHash)
if state.shutdown != 0: if state.shutdown != 0:
raise StopIteration("Interrupted") raise StopIteration("Interrupted")
logger.debug("C PoW done") logger.debug('C PoW done')
return [trialValue, nonce] return trialValue, nonce
def _doGPUPoW(target, initialHash): def _doGPUPoW(target, initialHash):
logger.debug("GPU PoW start") logger.debug('GPU PoW start')
nonce = openclpow.do_opencl_pow(initialHash.encode("hex"), target) nonce = openclpow.do_opencl_pow(initialHash.encode("hex"), target)
trialValue = trial_value(nonce, initialHash) trialValue = trial_value(nonce, initialHash)
if trialValue > target: if trialValue > target:
deviceNames = ", ".join(gpu.name for gpu in openclpow.enabledGpus) deviceNames = ", ".join(gpu.name for gpu in openclpow.enabledGpus)
queues.UISignalQueue.put(( queues.UISignalQueue.put((
'updateStatusBar', ( 'updateStatusBar', (
tr._translate( _translate(
"MainWindow", "MainWindow",
'Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers.' "Your GPU(s) did not calculate correctly,"
), " disabling OpenCL. Please report to the developers."
1))) ), 1)
))
logger.error( logger.error(
"Your GPUs (%s) did not calculate correctly, disabling OpenCL. Please report to the developers.", 'Your GPUs (%s) did not calculate correctly, disabling OpenCL.'
deviceNames) ' Please report to the developers.', deviceNames)
openclpow.enabledGpus = [] openclpow.enabledGpus = []
raise Exception("GPU did not calculate correctly.") raise Exception("GPU did not calculate correctly.")
if state.shutdown != 0: if state.shutdown != 0:
raise StopIteration("Interrupted") raise StopIteration("Interrupted")
logger.debug("GPU PoW done") logger.debug('GPU PoW done')
return [trialValue, nonce] return trialValue, nonce
def estimate(difficulty, format=False): # pylint: disable=redefined-builtin # def estimate(difficulty, fmt=False):
""" # ret = difficulty / 10
.. todo: fix unused variable # if ret < 1:
""" # ret = 1
ret = difficulty / 10 #
if ret < 1: # if fmt:
ret = 1 # out = str(int(ret)) + " seconds"
# if ret > 60:
if format: # ret /= 60
# pylint: disable=unused-variable # out = str(int(ret)) + " minutes"
out = str(int(ret)) + " seconds" # if ret > 60:
if ret > 60: # ret /= 60
ret /= 60 # out = str(int(ret)) + " hours"
out = str(int(ret)) + " minutes" # if ret > 24:
if ret > 60: # ret /= 24
ret /= 60 # out = str(int(ret)) + " days"
out = str(int(ret)) + " hours" # if ret > 7:
if ret > 24: # out = str(int(ret)) + " weeks"
ret /= 24 # if ret > 31:
out = str(int(ret)) + " days" # out = str(int(ret)) + " months"
if ret > 7: # if ret > 366:
out = str(int(ret)) + " weeks" # ret /= 366
if ret > 31: # out = str(int(ret)) + " years"
out = str(int(ret)) + " months" # ret = None # Ensure legacy behaviour
if ret > 366: #
ret /= 366 # return ret
out = str(int(ret)) + " years"
ret = None # Ensure legacy behaviour
return ret
def getPowType(): def getPowType():
@ -247,25 +246,19 @@ def getPowType():
def notifyBuild(tried=False): def notifyBuild(tried=False):
"""Notify the user of the success or otherwise of building the PoW C module""" """
Notify the user of the success or otherwise of building the PoW C module
"""
if bmpow: if bmpow:
queues.UISignalQueue.put(('updateStatusBar', (tr._translate( queues.UISignalQueue.put(('updateStatusBar', (_translate(
"proofofwork", "C PoW module built successfully."), 1))) "proofofwork", "C PoW module built successfully."), 1)))
elif tried: elif tried:
queues.UISignalQueue.put( queues.UISignalQueue.put(('updateStatusBar', (_translate(
( "proofofwork",
'updateStatusBar', ( "Failed to build C PoW module. Please build it manually."), 1)))
tr._translate(
"proofofwork",
"Failed to build C PoW module. Please build it manually."
),
1
)
)
)
else: else:
queues.UISignalQueue.put(('updateStatusBar', (tr._translate( queues.UISignalQueue.put(('updateStatusBar', (_translate(
"proofofwork", "C PoW module unavailable. Please build it."), 1))) "proofofwork", "C PoW module unavailable. Please build it."), 1)))
@ -273,76 +266,49 @@ def buildCPoW():
"""Attempt to build the PoW C module""" """Attempt to build the PoW C module"""
if bmpow is not None: if bmpow is not None:
return return
if paths.frozen is not None: if paths.frozen or sys.platform.startswith('win'):
notifyBuild(False)
return
if sys.platform in ["win32", "win64"]:
notifyBuild(False) notifyBuild(False)
return return
try: try:
# GNU make
make_cmd = ['make', '-C', os.path.join(paths.codePath(), 'bitmsghash')]
if "bsd" in sys.platform: if "bsd" in sys.platform:
# BSD make # BSD make
subprocess.check_call([ # nosec B607, B603 make_cmd += ['-f', 'Makefile.bsd']
"make", "-C", os.path.join(paths.codePath(), "bitmsghash"),
'-f', 'Makefile.bsd']) subprocess.check_call(make_cmd) # nosec B603
else:
# GNU make
subprocess.check_call([ # nosec B607, B603
"make", "-C", os.path.join(paths.codePath(), "bitmsghash")])
if os.path.exists( if os.path.exists(
os.path.join(paths.codePath(), "bitmsghash", "bitmsghash.so") os.path.join(paths.codePath(), 'bitmsghash', 'bitmsghash.so')
): ):
init() init()
notifyBuild(True)
else:
notifyBuild(True)
except (OSError, subprocess.CalledProcessError): except (OSError, subprocess.CalledProcessError):
notifyBuild(True) pass
except: # noqa:E722 except: # noqa:E722
logger.warning( logger.warning(
'Unexpected exception rised when tried to build bitmsghash lib', 'Unexpected exception rised when tried to build bitmsghash lib',
exc_info=True) exc_info=True)
notifyBuild(True) notifyBuild(True)
def run(target, initialHash): def run(target, initialHash):
"""Run the proof of work thread""" """Run the proof of work calculation"""
if state.shutdown != 0: if state.shutdown != 0:
raise # pylint: disable=misplaced-bare-raise raise StopIteration("Interrupted")
target = int(target) target = int(target)
if openclpow.openclEnabled(): if openclpow.openclEnabled():
try: return _doGPUPoW(target, initialHash)
return _doGPUPoW(target, initialHash)
except StopIteration:
raise
except: # nosec B110 # noqa:E722 # pylint:disable=bare-except
pass # fallback
if bmpow: if bmpow:
try: return _doCPoW(target, initialHash)
return _doCPoW(target, initialHash)
except StopIteration:
raise
except: # nosec B110 # noqa:E722 # pylint:disable=bare-except
pass # fallback
if paths.frozen == "macosx_app" or not paths.frozen: if paths.frozen == "macosx_app" or not paths.frozen:
# on my (Peter Surda) Windows 10, Windows Defender # on my (Peter Surda) Windows 10, Windows Defender
# does not like this and fights with PyBitmessage # does not like this and fights with PyBitmessage
# over CPU, resulting in very slow PoW # over CPU, resulting in very slow PoW
# added on 2015-11-29: multiprocesing.freeze_support() doesn't help # added on 2015-11-29: multiprocesing.freeze_support() doesn't help
try: return _doFastPoW(target, initialHash)
return _doFastPoW(target, initialHash)
except StopIteration: return _doSafePoW(target, initialHash)
logger.error("Fast PoW got StopIteration")
raise
except: # noqa:E722 # pylint:disable=bare-except
logger.error("Fast PoW got exception:", exc_info=True)
try:
return _doSafePoW(target, initialHash)
except StopIteration:
raise
except: # nosec B110 # noqa:E722 # pylint:disable=bare-except
pass # fallback
def getTarget(payloadLength, ttl, nonceTrialsPerByte, payloadLengthExtraBytes): def getTarget(payloadLength, ttl, nonceTrialsPerByte, payloadLengthExtraBytes):
@ -377,60 +343,63 @@ def resetPoW():
def init(): def init():
"""Initialise PoW""" """Initialise PoW"""
# pylint: disable=global-statement # pylint: disable=broad-exception-caught,disable=global-statement
global bitmsglib, bmpow global bitmsglib, bmpow
openclpow.initCL() openclpow.initCL()
if sys.platform == "win32": if sys.platform.startswith('win'):
if ctypes.sizeof(ctypes.c_voidp) == 4: bitmsglib = (
bitmsglib = 'bitmsghash32.dll' 'bitmsghash32.dll' if ctypes.sizeof(ctypes.c_voidp) == 4 else
else: 'bitmsghash64.dll')
bitmsglib = 'bitmsghash64.dll' libfile = os.path.join(paths.codePath(), 'bitmsghash', bitmsglib)
try: try:
# MSVS # MSVS
bso = ctypes.WinDLL(os.path.join(paths.codePath(), "bitmsghash", bitmsglib)) bso = ctypes.WinDLL(
logger.info("Loaded C PoW DLL (stdcall) %s", bitmsglib) os.path.join(paths.codePath(), 'bitmsghash', bitmsglib))
logger.info('Loaded C PoW DLL (stdcall) %s', bitmsglib)
bmpow = bso.BitmessagePOW bmpow = bso.BitmessagePOW
bmpow.restype = ctypes.c_ulonglong bmpow.restype = ctypes.c_ulonglong
_doCPoW(2**63, "") _doCPoW(2**63, "")
logger.info("Successfully tested C PoW DLL (stdcall) %s", bitmsglib) logger.info(
'Successfully tested C PoW DLL (stdcall) %s', bitmsglib)
except ValueError: except ValueError:
try: try:
# MinGW # MinGW
bso = ctypes.CDLL(os.path.join(paths.codePath(), "bitmsghash", bitmsglib)) bso = ctypes.CDLL(libfile)
logger.info("Loaded C PoW DLL (cdecl) %s", bitmsglib) logger.info('Loaded C PoW DLL (cdecl) %s', bitmsglib)
bmpow = bso.BitmessagePOW bmpow = bso.BitmessagePOW
bmpow.restype = ctypes.c_ulonglong bmpow.restype = ctypes.c_ulonglong
_doCPoW(2**63, "") _doCPoW(2**63, "")
logger.info("Successfully tested C PoW DLL (cdecl) %s", bitmsglib) logger.info(
'Successfully tested C PoW DLL (cdecl) %s', bitmsglib)
except Exception as e: except Exception as e:
logger.error("Error: %s", e, exc_info=True) logger.error('Error: %s', e, exc_info=True)
bso = None
except Exception as e: except Exception as e:
logger.error("Error: %s", e, exc_info=True) logger.error('Error: %s', e, exc_info=True)
bso = None
else: else:
try: try:
bso = ctypes.CDLL(os.path.join(paths.codePath(), "bitmsghash", bitmsglib)) bso = ctypes.CDLL(
os.path.join(paths.codePath(), 'bitmsghash', bitmsglib))
except OSError: except OSError:
import glob import glob
try: try:
bso = ctypes.CDLL(glob.glob(os.path.join( bso = ctypes.CDLL(glob.glob(os.path.join(
paths.codePath(), "bitmsghash", "bitmsghash*.so" paths.codePath(), 'bitmsghash', 'bitmsghash*.so'
))[0]) ))[0])
except (OSError, IndexError): except (OSError, IndexError):
bso = None bso = None
except: # noqa:E722 except Exception:
bso = None bso = None
else: else:
logger.info("Loaded C PoW DLL %s", bitmsglib) logger.info('Loaded C PoW DLL %s', bitmsglib)
if bso: if bso:
try: try:
bmpow = bso.BitmessagePOW bmpow = bso.BitmessagePOW
bmpow.restype = ctypes.c_ulonglong bmpow.restype = ctypes.c_ulonglong
except: # noqa:E722 except Exception:
bmpow = None logger.warning(
else: 'Failed to setup bmpow lib %s', bso, exc_info=True)
bmpow = None return
if bmpow is None: if bmpow is None:
buildCPoW() buildCPoW()