Added estimated POW time tooltip
This commit is contained in:
parent
a27b5e9055
commit
2c7d677ccf
|
@ -54,6 +54,7 @@ from network.asyncore_pollchoose import set_rates
|
|||
import sound
|
||||
import re
|
||||
import bitmessage_icons_rc # Loads icon resources
|
||||
import workprover.utils
|
||||
|
||||
|
||||
try:
|
||||
|
@ -1876,11 +1877,17 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
if status.speed == 0:
|
||||
self.ui.workProverSpeed.setText("")
|
||||
self.ui.workProverSpeed.setToolTip("")
|
||||
else:
|
||||
self.ui.workProverSpeed.setText(
|
||||
_translate("MainWindow", "%1 kiH / s").arg("{:.1f}".format(status.speed / 1024))
|
||||
)
|
||||
|
||||
self.ui.workProverSpeed.setToolTip("Difficulty: {}, 80 % completion time: {:.1f} s".format(
|
||||
status.difficulty,
|
||||
workprover.utils.estimateMaximumIterationsCount(status.difficulty, .8) / status.speed
|
||||
))
|
||||
|
||||
def rerenderMessagelistFromLabels(self):
|
||||
for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions):
|
||||
for i in range(messagelist.rowCount()):
|
||||
|
|
|
@ -21,13 +21,14 @@ class Task(object):
|
|||
previous = None
|
||||
next = None
|
||||
|
||||
def __init__(self, headlessPayload, TTL, expiryTime, target):
|
||||
def __init__(self, headlessPayload, TTL, expiryTime, target, difficulty):
|
||||
self.headlessPayload = headlessPayload
|
||||
self.TTL = TTL
|
||||
self.expiryTime = expiryTime
|
||||
self.target = target
|
||||
self.difficulty = difficulty
|
||||
|
||||
Status = collections.namedtuple("Status", ["solverName", "solverStatus", "speed", "tasksCount"])
|
||||
Status = collections.namedtuple("Status", ["solverName", "solverStatus", "speed", "tasksCount", "difficulty"])
|
||||
|
||||
class WorkProver(threading.Thread):
|
||||
# Seed must be 32 bytes
|
||||
|
@ -81,6 +82,7 @@ class WorkProver(threading.Thread):
|
|||
self.lastTime = utils.getTimePoint()
|
||||
self.timedIntervals = collections.deque()
|
||||
self.speed = 0
|
||||
self.totalDifficulty = 0
|
||||
|
||||
self.tasks = {}
|
||||
self.currentTaskID = None
|
||||
|
@ -94,7 +96,7 @@ class WorkProver(threading.Thread):
|
|||
if self.solver is not None:
|
||||
status = self.solver.status
|
||||
|
||||
self.statusUpdated(Status(self.solverName, status, self.speed, len(self.tasks)))
|
||||
self.statusUpdated(Status(self.solverName, status, self.speed, len(self.tasks), self.totalDifficulty))
|
||||
|
||||
def setSolver(self, name, configuration):
|
||||
if name is None and self.solverName is None:
|
||||
|
@ -145,11 +147,12 @@ class WorkProver(threading.Thread):
|
|||
self.notifyStatus()
|
||||
|
||||
def addTask(self, ID, headlessPayload, TTL, expiryTime, byteDifficulty, lengthExtension):
|
||||
target = utils.calculateTarget(8 + 8 + len(headlessPayload), TTL, byteDifficulty, lengthExtension)
|
||||
target, difficulty = utils.calculateTarget(8 + 8 + len(headlessPayload), TTL, byteDifficulty, lengthExtension)
|
||||
|
||||
task = Task(headlessPayload, TTL, expiryTime, target)
|
||||
task = Task(headlessPayload, TTL, expiryTime, target, difficulty)
|
||||
|
||||
self.tasks[ID] = task
|
||||
self.totalDifficulty += difficulty
|
||||
|
||||
if self.currentTaskID is None:
|
||||
task.previous = ID
|
||||
|
@ -163,11 +166,14 @@ class WorkProver(threading.Thread):
|
|||
self.tasks[task.previous].next = ID
|
||||
self.tasks[task.next].previous = ID
|
||||
|
||||
self.notifyStatus()
|
||||
|
||||
def cancelTask(self, ID):
|
||||
if ID not in self.tasks:
|
||||
return
|
||||
|
||||
task = self.tasks.pop(ID)
|
||||
self.totalDifficulty -= task.difficulty
|
||||
|
||||
if len(self.tasks) == 0:
|
||||
self.currentTaskID = None
|
||||
|
@ -178,6 +184,8 @@ class WorkProver(threading.Thread):
|
|||
if self.currentTaskID == ID:
|
||||
self.currentTaskID = task.next
|
||||
|
||||
self.notifyStatus()
|
||||
|
||||
def nextTask(self):
|
||||
self.currentTaskID = self.tasks[self.currentTaskID].next
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ byteDifficulty = 1000
|
|||
lengthExtension = 1000
|
||||
|
||||
target = 0x00000f903320b7f6
|
||||
difficulty = 1078000
|
||||
|
||||
seed = binascii.unhexlify("3941c24a1256660a8f65d962954c406dab7bc449317fa087c4a3f1a3ca7d95fd")
|
||||
timeout = .5
|
||||
|
@ -56,8 +57,8 @@ class TestUtils(unittest.TestCase):
|
|||
self.assertEqual(utils.calculateDoubleHash(payload), doubleHash)
|
||||
|
||||
def testCalculateTarget(self):
|
||||
self.assertEqual(utils.calculateTarget(1000, 1015, 1000, 1000), 0x00000843bf57fed2)
|
||||
self.assertEqual(utils.calculateTarget(1000, 1016, 1000, 1000), 0x00000842b4a960c2)
|
||||
self.assertEqual(utils.calculateTarget(1000, 1015, 1000, 1000), (0x00000843bf57fed2, 2030000))
|
||||
self.assertEqual(utils.calculateTarget(1000, 1016, 1000, 1000), (0x00000842b4a960c2, 2031000))
|
||||
|
||||
def testCheckProof(self):
|
||||
self.assertFalse(utils.checkProof(nonce, initialHash, 0x000002fe91eba355))
|
||||
|
@ -75,8 +76,8 @@ class TestUtils(unittest.TestCase):
|
|||
utils.time.time = originalTime
|
||||
|
||||
def testEstimateMaximumIterationsCount(self):
|
||||
self.assertEqual(utils.estimateMaximumIterationsCount(0x000fffffffffffff, .1), 512)
|
||||
self.assertEqual(utils.estimateMaximumIterationsCount(target, .8), 1735168)
|
||||
self.assertEqual(utils.estimateMaximumIterationsCount(4096, .1), 512)
|
||||
self.assertEqual(utils.estimateMaximumIterationsCount(difficulty, .8), 1735168)
|
||||
|
||||
class TestSolver(unittest.TestCase):
|
||||
def setUp(self):
|
||||
|
@ -135,6 +136,8 @@ class TestWorkProver(unittest.TestCase):
|
|||
linkID = next(iter(IDs))
|
||||
|
||||
for i in xrange(len(IDs)):
|
||||
self.assertGreaterEqual(self.thread.totalDifficulty, 0)
|
||||
|
||||
self.assertIn(linkID, IDs)
|
||||
|
||||
IDs.remove(linkID)
|
||||
|
|
|
@ -19,7 +19,7 @@ def calculateTarget(length, TTL, byteDifficulty, lengthExtension):
|
|||
|
||||
difficulty = byteDifficulty * (adjustedLength + timeEquivalent)
|
||||
|
||||
return 2 ** 64 / difficulty
|
||||
return 2 ** 64 / difficulty, difficulty
|
||||
|
||||
def checkProof(nonce, initialHash, target):
|
||||
proof = nonce + initialHash
|
||||
|
@ -34,13 +34,12 @@ def checkWorkSufficient(payload, byteDifficulty, lengthExtension):
|
|||
nonce = payload[: 8]
|
||||
initialHash = calculateInitialHash(payload[8: ])
|
||||
|
||||
target = calculateTarget(len(payload), minimumTTL, byteDifficulty, lengthExtension)
|
||||
target, difficulty = calculateTarget(len(payload), minimumTTL, byteDifficulty, lengthExtension)
|
||||
|
||||
return checkProof(nonce, initialHash, target)
|
||||
|
||||
def estimateMaximumIterationsCount(target, probability):
|
||||
def estimateMaximumIterationsCount(difficulty, probability):
|
||||
coefficient = -math.log(1 - probability)
|
||||
difficulty = 2. ** 64 / target
|
||||
|
||||
return int(coefficient * difficulty + 255) / 256 * 256
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user