107 lines
3.2 KiB
Python
107 lines
3.2 KiB
Python
import os
|
|
import pickle
|
|
# import sys
|
|
import threading
|
|
import time
|
|
|
|
import state
|
|
from bmconfigparser import BMConfigParser
|
|
from debug import logger
|
|
|
|
knownNodesLock = threading.Lock()
|
|
knownNodes = {stream: {} for stream in range(1, 4)}
|
|
|
|
knownNodesTrimAmount = 2000
|
|
|
|
# forget a node after rating is this low
|
|
knownNodesForgetRating = -0.5
|
|
|
|
|
|
def saveKnownNodes(dirName=None):
|
|
if dirName is None:
|
|
dirName = state.appdata
|
|
with knownNodesLock:
|
|
with open(os.path.join(dirName, 'knownnodes.dat'), 'wb') as output:
|
|
pickle.dump(knownNodes, output)
|
|
|
|
|
|
def addKnownNode(stream, peer, lastseen=None, is_self=False):
|
|
if lastseen is None:
|
|
lastseen = time.time()
|
|
knownNodes[stream][peer] = {
|
|
"lastseen": lastseen,
|
|
"rating": 0,
|
|
"self": is_self,
|
|
}
|
|
|
|
|
|
def readKnownNodes():
|
|
try:
|
|
with open(state.appdata + 'knownnodes.dat', 'rb') as source:
|
|
with knownNodesLock:
|
|
knownNodes = pickle.load(source)
|
|
except (IOError, OSError):
|
|
logger.warning(
|
|
'Failed to read nodes from knownnodes.dat', exc_info=True)
|
|
else:
|
|
# the old format was {Peer:lastseen, ...}
|
|
# the new format is {Peer:{"lastseen":i, "rating":f}}
|
|
for stream in knownNodes.keys():
|
|
for node, params in knownNodes[stream].items():
|
|
if isinstance(params, (float, int)):
|
|
addKnownNode(stream, node, params)
|
|
|
|
config = BMConfigParser()
|
|
# if config.safeGetInt('bitmessagesettings', 'settingsversion') > 10:
|
|
# sys.exit(
|
|
# 'Bitmessage cannot read future versions of the keys file'
|
|
# ' (keys.dat). Run the newer version of Bitmessage.')
|
|
|
|
# your own onion address, if setup
|
|
onionhostname = config.safeGet('bitmessagesettings', 'onionhostname')
|
|
if onionhostname and ".onion" in onionhostname:
|
|
onionport = config.safeGetInt('bitmessagesettings', 'onionport')
|
|
if onionport:
|
|
addKnownNode(1, state.Peer(onionhostname, onionport), is_self=True)
|
|
|
|
|
|
def increaseRating(peer):
|
|
increaseAmount = 0.1
|
|
maxRating = 1
|
|
with knownNodesLock:
|
|
for stream in knownNodes.keys():
|
|
try:
|
|
knownNodes[stream][peer]["rating"] = min(
|
|
knownNodes[stream][peer]["rating"] + increaseAmount,
|
|
maxRating
|
|
)
|
|
except KeyError:
|
|
pass
|
|
|
|
|
|
def decreaseRating(peer):
|
|
decreaseAmount = 0.1
|
|
minRating = -1
|
|
with knownNodesLock:
|
|
for stream in knownNodes.keys():
|
|
try:
|
|
knownNodes[stream][peer]["rating"] = max(
|
|
knownNodes[stream][peer]["rating"] - decreaseAmount,
|
|
minRating
|
|
)
|
|
except KeyError:
|
|
pass
|
|
|
|
|
|
def trimKnownNodes(recAddrStream=1):
|
|
if len(knownNodes[recAddrStream]) < \
|
|
BMConfigParser().safeGetInt("knownnodes", "maxnodes"):
|
|
return
|
|
with knownNodesLock:
|
|
oldestList = sorted(
|
|
knownNodes[recAddrStream],
|
|
key=lambda x: x['lastseen']
|
|
)[:knownNodesTrimAmount]
|
|
for oldest in oldestList:
|
|
del knownNodes[recAddrStream][oldest]
|