Notify if C PoW missing

- Linux users often don't know that the C PoW is available and complain
  it's slow. This will try to build it, and adds availability
  notification in the status bar
- also, the updateStatusBar signal now allows emphasised notifications,
  which will remain visible for a longer period of time and also
  reappear if a status change happened in the meantime
This commit is contained in:
Peter Šurda 2016-12-15 16:11:29 +01:00
parent 9d9052dda2
commit fefb959338
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
4 changed files with 125 additions and 37 deletions

View File

@ -76,6 +76,7 @@ from class_objectHashHolder import objectHashHolder
from class_singleWorker import singleWorker from class_singleWorker import singleWorker
from helper_generic import powQueueSize, invQueueSize from helper_generic import powQueueSize, invQueueSize
from proofofwork import getPowType from proofofwork import getPowType
from statusbar import BMStatusBar
def _translate(context, text, disambiguation = None, encoding = None, number = None): def _translate(context, text, disambiguation = None, encoding = None, number = None):
if number is None: if number is None:
@ -703,6 +704,7 @@ class MyForm(settingsmixin.SMainWindow):
# Put the colored icon on the status bar # Put the colored icon on the status bar
# self.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/yellowicon.png")) # self.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/yellowicon.png"))
self.setStatusBar(BMStatusBar())
self.statusbar = self.statusBar() self.statusbar = self.statusBar()
self.pushButtonStatusIcon = QtGui.QPushButton(self) self.pushButtonStatusIcon = QtGui.QPushButton(self)
@ -3927,10 +3929,19 @@ class MyForm(settingsmixin.SMainWindow):
self.rerenderComboBoxSendFromBroadcast() self.rerenderComboBoxSendFromBroadcast()
def updateStatusBar(self, data): def updateStatusBar(self, data):
if data != "": if type(data) is tuple or type(data) is list:
logger.info('Status bar: ' + data) option = data[1]
message = data[0]
else:
option = 0
message = data
if message != "":
logger.info('Status bar: ' + message)
self.statusBar().showMessage(data, 10000) if option == 1:
self.statusBar().addImportant(message)
else:
self.statusBar().showMessage(message, 10000)
def initSettings(self): def initSettings(self):
QtCore.QCoreApplication.setOrganizationName("PyBitmessage") QtCore.QCoreApplication.setOrganizationName("PyBitmessage")

View File

@ -0,0 +1,38 @@
from PyQt4 import QtCore, QtGui
from Queue import Queue
from time import time
class BMStatusBar(QtGui.QStatusBar):
duration = 10000
deleteAfter = 60
def __init__(self, parent=None):
super(BMStatusBar, self).__init__(parent)
self.important = []
self.timer = self.startTimer(BMStatusBar.duration)
self.iterator = 0
def timerEvent(self, event):
while len(self.important) > 0:
self.iterator += 1
try:
if time() > self.important[self.iterator][1] + BMStatusBar.deleteAfter:
del self.important[self.iterator]
self.iterator -= 1
continue
except IndexError:
self.iterator = -1
continue
super(BMStatusBar, self).showMessage(self.important[self.iterator][0], 0)
break
def addImportant(self, message):
self.important.append([message, time()])
self.iterator = len(self.important) - 2
self.timerEvent(None)
def showMessage(self, message, timeout=0):
super(BMStatusBar, self).showMessage(message, timeout)
def clearMessage(self):
super(BMStatusBar, self).clearMessage()

View File

@ -3,6 +3,7 @@
#from multiprocessing import Pool, cpu_count #from multiprocessing import Pool, cpu_count
import hashlib import hashlib
from struct import unpack, pack from struct import unpack, pack
from subprocess import call
import sys import sys
import time import time
from debug import logger from debug import logger
@ -12,6 +13,8 @@ import tr
import os import os
import ctypes import ctypes
bitmsglib = 'bitmsghash.so'
def _set_idle(): def _set_idle():
if 'linux' in sys.platform: if 'linux' in sys.platform:
import os import os
@ -109,7 +112,7 @@ def _doGPUPoW(target, initialHash):
#print "{} - value {} < {}".format(nonce, trialValue, target) #print "{} - value {} < {}".format(nonce, trialValue, target)
if trialValue > target: if trialValue > target:
deviceNames = ", ".join(gpu.name for gpu in openclpow.enabledGpus) deviceNames = ", ".join(gpu.name for gpu in openclpow.enabledGpus)
shared.UISignalQueue.put(('updateStatusBar', tr._translate("MainWindow",'Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers.'))) shared.UISignalQueue.put(('updateStatusBar', (tr._translate("MainWindow",'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) logger.error("Your GPUs (%s) did not calculate correctly, disabling OpenCL. Please report to the developers.", deviceNames)
openclpow.enabledGpus = [] openclpow.enabledGpus = []
raise Exception("GPU did not calculate correctly.") raise Exception("GPU did not calculate correctly.")
@ -150,6 +153,37 @@ def getPowType():
return "C" return "C"
return "python" return "python"
def notifyBuild(tried=False):
global bmpow
if bmpow:
shared.UISignalQueue.put(('updateStatusBar', (tr._translate("proofofwork", "C PoW module built successfully."), 1)))
elif tried:
shared.UISignalQueue.put(('updateStatusBar', (tr._translate("proofofwork", "Failed to build C PoW module. Please build it manually."), 1)))
else:
shared.UISignalQueue.put(('updateStatusBar', (tr._translate("proofofwork", "C PoW module unavailable. Please build it."), 1)))
def buildCPoW():
global bmpow
if bmpow is not None:
return
if shared.frozen is not None:
notifyBuild(False)
return
if sys.platform in ["win32", "win64"]:
notifyBuild(False)
return
try:
call(["make", "-C", os.path.join(shared.codePath(), "bitmsghash")])
if os.path.exists(os.path.join(shared.codePath(), "bitmsghash", "bitmsghash.so")):
init()
notifyBuild(True)
else:
notifyBuild(True)
except:
notifyBuild(True)
def run(target, initialHash): def run(target, initialHash):
if shared.shutdown != 0: if shared.shutdown != 0:
raise raise
@ -194,8 +228,9 @@ def run(target, initialHash):
pass #fallback pass #fallback
# init # init
bitmsglib = 'bitmsghash.so' def init():
if "win32" == sys.platform: global bitmsglib, bso, bmpow
if "win32" == sys.platform:
if ctypes.sizeof(ctypes.c_voidp) == 4: if ctypes.sizeof(ctypes.c_voidp) == 4:
bitmsglib = 'bitmsghash32.dll' bitmsglib = 'bitmsghash32.dll'
else: else:
@ -221,18 +256,21 @@ if "win32" == sys.platform:
except: except:
logger.error("C PoW test fail.", exc_info=True) logger.error("C PoW test fail.", exc_info=True)
bso = None bso = None
else: else:
try: try:
bso = ctypes.CDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib)) bso = ctypes.CDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib))
logger.info("Loaded C PoW DLL %s", bitmsglib) logger.info("Loaded C PoW DLL %s", bitmsglib)
except: except:
bso = None bso = None
if bso: if bso:
try: try:
bmpow = bso.BitmessagePOW bmpow = bso.BitmessagePOW
bmpow.restype = ctypes.c_ulonglong bmpow.restype = ctypes.c_ulonglong
except: except:
bmpow = None bmpow = None
else: else:
bmpow = None bmpow = None
init()
if bmpow is None:
buildCPoW()

View File

@ -16,6 +16,7 @@ SOURCES = ../addresses.py\
../helper_msgcoding.py\ ../helper_msgcoding.py\
../helper_sent.py\ ../helper_sent.py\
../helper_startup.py\ ../helper_startup.py\
../proofofwork.py\
../shared.py\ ../shared.py\
../upnp.py\ ../upnp.py\
../bitmessageqt/__init__.py\ ../bitmessageqt/__init__.py\