From e417b6257f1078151ae247fc0abd307c85bd184f Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 3 Oct 2018 16:07:06 +0300 Subject: [PATCH] Fixes #1335: - moved knownnodes cleanup to knownnodes module, - added a check for last node in stream initiating DNS based bootstrap. --- src/class_singleCleaner.py | 82 +++++++++++++------------------------- src/knownnodes.py | 41 +++++++++++++++++++ 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index 1ba342b6..82d6b491 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -55,7 +55,7 @@ class singleCleaner(threading.Thread, StoppableThread): ) + ( float(BMConfigParser().get( 'bitmessagesettings', 'stopresendingafterxmonths')) * - (60 * 60 * 24 * 365)/12) + (60 * 60 * 24 * 365) / 12) except: # Either the user hasn't set stopresendingafterxdays and # stopresendingafterxmonths yet or the options are missing @@ -96,9 +96,8 @@ class singleCleaner(threading.Thread, StoppableThread): "SELECT toaddress, ackdata, status FROM sent" " WHERE ((status='awaitingpubkey' OR status='msgsent')" " AND folder='sent' AND sleeptill?)", - int(time.time()), - int(time.time()) - - shared.maximumLengthOfTimeToBotherResendingMessages + int(time.time()), int(time.time()) - + shared.maximumLengthOfTimeToBotherResendingMessages ) for row in queryreturn: if len(row) < 2: @@ -115,54 +114,28 @@ class singleCleaner(threading.Thread, StoppableThread): elif status == 'msgsent': resendMsg(ackData) - # cleanup old nodes - now = int(time.time()) - - with knownnodes.knownNodesLock: - for stream in knownnodes.knownNodes: - keys = knownnodes.knownNodes[stream].keys() - for node in keys: - try: - # scrap old nodes - if now - knownnodes.knownNodes[stream][node]["lastseen"] > 2419200: # 28 days - shared.needToWriteKnownNodesToDisk = True - del knownnodes.knownNodes[stream][node] - continue - # scrap old nodes with low rating - if now - knownnodes.knownNodes[stream][node]["lastseen"] > 10800 and knownnodes.knownNodes[stream][node]["rating"] <= knownnodes.knownNodesForgetRating: - shared.needToWriteKnownNodesToDisk = True - del knownnodes.knownNodes[stream][node] - continue - except TypeError: - print "Error in %s" % node - keys = [] - - # Let us write out the knowNodes to disk - # if there is anything new to write out. - if shared.needToWriteKnownNodesToDisk: - try: - knownnodes.saveKnownNodes() - except Exception as err: - if "Errno 28" in str(err): - logger.fatal( - '(while receiveDataThread' - ' knownnodes.needToWriteKnownNodesToDisk)' - ' Alert: Your disk or data storage volume' - ' is full. ' - ) - queues.UISignalQueue.put(( - 'alert', - (tr._translate("MainWindow", "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume' - ' is full. Bitmessage will now exit.'), - True) - )) - # FIXME redundant? - if shared.daemon or not state.enableGUI: - os._exit(0) - shared.needToWriteKnownNodesToDisk = False + try: + # Cleanup knownnodes and handle possible severe exception + # while writing it to disk + knownnodes.cleanupKnownNodes() + except Exception as err: + if "Errno 28" in str(err): + logger.fatal( + '(while writing knownnodes to disk)' + ' Alert: Your disk or data storage volume is full.' + ) + queues.UISignalQueue.put(( + 'alert', + (tr._translate("MainWindow", "Disk full"), + tr._translate( + "MainWindow", + 'Alert: Your disk or data storage volume' + ' is full. Bitmessage will now exit.'), + True) + )) + # FIXME redundant? + if shared.daemon or not state.enableGUI: + os._exit(1) # # clear download queues # for thread in threading.enumerate(): @@ -206,8 +179,9 @@ def resendPubkeyRequest(address): pass queues.UISignalQueue.put(( - 'updateStatusBar', - 'Doing work necessary to again attempt to request a public key...')) + 'updateStatusBar', + 'Doing work necessary to again attempt to request a public key...' + )) sqlExecute( '''UPDATE sent SET status='msgqueued' WHERE toaddress=?''', address) diff --git a/src/knownnodes.py b/src/knownnodes.py index b1a78334..1fed7509 100644 --- a/src/knownnodes.py +++ b/src/knownnodes.py @@ -8,6 +8,7 @@ import time import state from bmconfigparser import BMConfigParser from debug import logger +from helper_bootstrap import dns knownNodesLock = threading.Lock() knownNodes = {stream: {} for stream in range(1, 4)} @@ -157,3 +158,43 @@ def trimKnownNodes(recAddrStream=1): )[:knownNodesTrimAmount] for oldest in oldestList: del knownNodes[recAddrStream][oldest] + + +def cleanupKnownNodes(): + """ + Cleanup knownnodes: remove old nodes and nodes with low rating + """ + now = int(time.time()) + needToWriteKnownNodesToDisk = False + dns_done = False + + with knownNodesLock: + for stream in knownNodes: + keys = knownNodes[stream].keys() + if len(keys) <= 1 and not dns_done: # leave at least one node + dns() + dns_done = True + continue + for node in keys: + try: + # scrap old nodes + if (now - knownNodes[stream][node]["lastseen"] > + 2419200): # 28 days + needToWriteKnownNodesToDisk = True + del knownNodes[stream][node] + continue + # scrap old nodes with low rating + if (now - knownNodes[stream][node]["lastseen"] > 10800 and + knownNodes[stream][node]["rating"] <= + knownNodesForgetRating): + needToWriteKnownNodesToDisk = True + del knownNodes[stream][node] + continue + except TypeError: + logger.warning('Error in %s', node) + keys = [] + + # Let us write out the knowNodes to disk + # if there is anything new to write out. + if needToWriteKnownNodesToDisk: + saveKnownNodes()