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