Merge pull request #1365 from coffeedogs/final_code_quality_7

Changes based on style and lint checks. (final_code_quality_7)
This commit is contained in:
coffeedogs 2018-11-12 14:48:21 +00:00 committed by GitHub
commit a7a21e79ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 273 additions and 186 deletions

View File

@ -1,17 +1,22 @@
"""
src/bitmessageqt/messageview.py
===============================
"""
from PyQt4 import QtCore, QtGui
import multiprocessing
import Queue
from urlparse import urlparse
from safehtmlparser import *
from safehtmlparser import SafeHTMLParser
class MessageView(QtGui.QTextBrowser):
"""Message content viewer class, can switch between plaintext and HTML"""
MODE_PLAIN = 0
MODE_HTML = 1
def __init__(self, parent = 0):
def __init__(self, parent=0):
super(MessageView, self).__init__(parent)
self.mode = MessageView.MODE_PLAIN
self.mode = MessageView.MODE_PLAIN
self.html = None
self.setOpenExternalLinks(False)
self.setOpenLinks(False)
@ -25,12 +30,14 @@ class MessageView(QtGui.QTextBrowser):
self.setWrappingWidth()
def resizeEvent(self, event):
"""View resize event handler"""
super(MessageView, self).resizeEvent(event)
self.setWrappingWidth(event.size().width())
def mousePressEvent(self, event):
#text = textCursor.block().text()
if event.button() == QtCore.Qt.LeftButton and self.html and self.html.has_html and self.cursorForPosition(event.pos()).block().blockNumber() == 0:
"""Mouse press button event handler"""
if event.button() == QtCore.Qt.LeftButton and self.html and self.html.has_html and self.cursorForPosition(
event.pos()).block().blockNumber() == 0:
if self.mode == MessageView.MODE_PLAIN:
self.showHTML()
else:
@ -39,19 +46,24 @@ class MessageView(QtGui.QTextBrowser):
super(MessageView, self).mousePressEvent(event)
def wheelEvent(self, event):
"""Mouse wheel scroll event handler"""
# super will actually automatically take care of zooming
super(MessageView, self).wheelEvent(event)
if (QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical:
if (QtGui.QApplication.queryKeyboardModifiers() &
QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical:
zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize
QtGui.QApplication.activeWindow().statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg(str(zoom)))
QtGui.QApplication.activeWindow().statusBar().showMessage(
QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg(str(zoom)))
def setWrappingWidth(self, width=None):
"""Set word-wrapping width"""
self.setLineWrapMode(QtGui.QTextEdit.FixedPixelWidth)
if width is None:
width = self.width()
self.setLineWrapColumnOrWidth(width)
def confirmURL(self, link):
"""Show a dialog requesting URL opening confirmation"""
if link.scheme() == "mailto":
window = QtGui.QApplication.activeWindow()
window.ui.lineEditTo.setText(link.path())
@ -68,35 +80,39 @@ class MessageView(QtGui.QTextBrowser):
)
window.ui.textEditMessage.setFocus()
return
reply = QtGui.QMessageBox.warning(self,
QtGui.QApplication.translate("MessageView", "Follow external link"),
QtGui.QApplication.translate("MessageView", "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure?").arg(unicode(link.toString())),
QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
reply = QtGui.QMessageBox.warning(
self,
QtGui.QApplication.translate(
"MessageView",
"Follow external link"),
QtGui.QApplication.translate(
"MessageView",
"The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you"
" or download malicious data. Are you sure?").arg(unicode(link.toString())),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
QtGui.QDesktopServices.openUrl(link)
def loadResource (self, restype, name):
if restype == QtGui.QTextDocument.ImageResource and name.scheme() == "bmmsg":
pass
# QImage correctImage;
# lookup the correct QImage from a cache
# return QVariant::fromValue(correctImage);
# elif restype == QtGui.QTextDocument.HtmlResource:
# elif restype == QtGui.QTextDocument.ImageResource:
# elif restype == QtGui.QTextDocument.StyleSheetResource:
# elif restype == QtGui.QTextDocument.UserResource:
else:
pass
# by default, this will interpret it as a local file
# QtGui.QTextBrowser.loadResource(restype, name)
def loadResource(self, restype, name):
"""
Callback for loading referenced objects, such as an image. For security reasons at the moment doesn't do
anything)
"""
pass
def lazyRender(self):
"""
Partially render a message. This is to avoid UI freezing when loading huge messages. It continues loading as
you scroll down.
"""
if self.rendering:
return
self.rendering = True
position = self.verticalScrollBar().value()
cursor = QtGui.QTextCursor(self.document())
while self.outpos < len(self.out) and self.verticalScrollBar().value() >= self.document().size().height() - 2 * self.size().height():
while self.outpos < len(self.out) and self.verticalScrollBar().value(
) >= self.document().size().height() - 2 * self.size().height():
startpos = self.outpos
self.outpos += 10240
# find next end of tag
@ -108,27 +124,33 @@ class MessageView(QtGui.QTextBrowser):
cursor.insertHtml(QtCore.QString(self.out[startpos:self.outpos]))
self.verticalScrollBar().setValue(position)
self.rendering = False
def showPlain(self):
"""Render message as plain text."""
self.mode = MessageView.MODE_PLAIN
out = self.html.raw
if self.html.has_html:
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(QtGui.QApplication.translate("MessageView", "HTML detected, click here to display")) + "</b></div><br/>" + out
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(
QtGui.QApplication.translate(
"MessageView", "HTML detected, click here to display")) + "</b></div><br/>" + out
self.out = out
self.outpos = 0
self.setHtml("")
self.lazyRender()
def showHTML(self):
"""Render message as HTML"""
self.mode = MessageView.MODE_HTML
out = self.html.sanitised
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "</b></div><br/>" + out
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(
QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "</b></div><br/>" + out
self.out = out
self.outpos = 0
self.setHtml("")
self.lazyRender()
def setContent(self, data):
"""Set message content from argument"""
self.html = SafeHTMLParser()
self.html.reset()
self.html.reset_safe()

View File

@ -1,20 +1,27 @@
from PyQt4 import QtCore, QtGui
import time
import shared
"""
src/bitmessageqt/networkstatus.py
=================================
"""
import time
from PyQt4 import QtCore, QtGui
from tr import _translate
from inventory import Inventory
import knownnodes
import l10n
import network.stats
from retranslateui import RetranslateMixin
from uisignaler import UISignaler
import shared
import widgets
from inventory import Inventory
from network.connectionpool import BMConnectionPool
from retranslateui import RetranslateMixin
from tr import _translate
from uisignaler import UISignaler
class NetworkStatus(QtGui.QWidget, RetranslateMixin):
"""Network status tab"""
def __init__(self, parent=None):
super(NetworkStatus, self).__init__(parent)
widgets.load('networkstatus.ui', self)
@ -29,8 +36,9 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
self.startup = time.localtime()
self.labelStartupTime.setText(_translate("networkstatus", "Since startup on %1").arg(
l10n.formatTimestamp(self.startup)))
self.UISignalThread = UISignaler.get()
# pylint: disable=no-member
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
"updateNumberOfMessagesProcessed()"), self.updateNumberOfMessagesProcessed)
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
@ -42,57 +50,108 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
self.timer = QtCore.QTimer()
QtCore.QObject.connect(
self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds)
QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds)
# pylint: enable=no-member
def startUpdate(self):
"""Start a timer to update counters every 2 seconds"""
Inventory().numberOfInventoryLookupsPerformed = 0
self.runEveryTwoSeconds()
self.timer.start(2000) # milliseconds
def stopUpdate(self):
"""Stop counter update timer"""
self.timer.stop()
def formatBytes(self, num):
for x in [_translate("networkstatus", "byte(s)", None, QtCore.QCoreApplication.CodecForTr, num), "kB", "MB", "GB"]:
"""Format bytes nicely (SI prefixes)"""
# pylint: disable=no-self-use
for x in [
_translate(
"networkstatus",
"byte(s)",
None,
QtCore.QCoreApplication.CodecForTr,
num),
"kB",
"MB",
"GB",
]:
if num < 1000.0:
return "%3.0f %s" % (num, x)
num /= 1000.0
return "%3.0f %s" % (num, 'TB')
def formatByteRate(self, num):
"""Format transfer speed in kB/s"""
# pylint: disable=no-self-use
num /= 1000
return "%4.0f kB" % num
def updateNumberOfObjectsToBeSynced(self):
self.labelSyncStatus.setText(_translate("networkstatus", "Object(s) to be synced: %n", None, QtCore.QCoreApplication.CodecForTr, network.stats.pendingDownload() + network.stats.pendingUpload()))
"""Update the counter for number of objects to be synced"""
self.labelSyncStatus.setText(
_translate(
"networkstatus",
"Object(s) to be synced: %n",
None,
QtCore.QCoreApplication.CodecForTr,
network.stats.pendingDownload() +
network.stats.pendingUpload()))
def updateNumberOfMessagesProcessed(self):
"""Update the counter for number of processed messages"""
self.updateNumberOfObjectsToBeSynced()
self.labelMessageCount.setText(_translate(
"networkstatus", "Processed %n person-to-person message(s).", None, QtCore.QCoreApplication.CodecForTr, shared.numberOfMessagesProcessed))
self.labelMessageCount.setText(
_translate(
"networkstatus",
"Processed %n person-to-person message(s).",
None,
QtCore.QCoreApplication.CodecForTr,
shared.numberOfMessagesProcessed))
def updateNumberOfBroadcastsProcessed(self):
"""Update the counter for the number of processed broadcasts"""
self.updateNumberOfObjectsToBeSynced()
self.labelBroadcastCount.setText(_translate(
"networkstatus", "Processed %n broadcast message(s).", None, QtCore.QCoreApplication.CodecForTr, shared.numberOfBroadcastsProcessed))
self.labelBroadcastCount.setText(
_translate(
"networkstatus",
"Processed %n broadcast message(s).",
None,
QtCore.QCoreApplication.CodecForTr,
shared.numberOfBroadcastsProcessed))
def updateNumberOfPubkeysProcessed(self):
"""Update the counter for the number of processed pubkeys"""
self.updateNumberOfObjectsToBeSynced()
self.labelPubkeyCount.setText(_translate(
"networkstatus", "Processed %n public key(s).", None, QtCore.QCoreApplication.CodecForTr, shared.numberOfPubkeysProcessed))
self.labelPubkeyCount.setText(
_translate(
"networkstatus",
"Processed %n public key(s).",
None,
QtCore.QCoreApplication.CodecForTr,
shared.numberOfPubkeysProcessed))
def updateNumberOfBytes(self):
"""
This function is run every two seconds, so we divide the rate of bytes
sent and received by 2.
"""
self.labelBytesRecvCount.setText(_translate(
"networkstatus", "Down: %1/s Total: %2").arg(self.formatByteRate(network.stats.downloadSpeed()), self.formatBytes(network.stats.receivedBytes())))
self.labelBytesSentCount.setText(_translate(
"networkstatus", "Up: %1/s Total: %2").arg(self.formatByteRate(network.stats.uploadSpeed()), self.formatBytes(network.stats.sentBytes())))
self.labelBytesRecvCount.setText(
_translate(
"networkstatus",
"Down: %1/s Total: %2").arg(
self.formatByteRate(network.stats.downloadSpeed()),
self.formatBytes(network.stats.receivedBytes())))
self.labelBytesSentCount.setText(
_translate(
"networkstatus", "Up: %1/s Total: %2").arg(
self.formatByteRate(network.stats.uploadSpeed()),
self.formatBytes(network.stats.sentBytes())))
def updateNetworkStatusTab(self, outbound, add, destination):
"""Add or remove an entry to the list of connected peers"""
# pylint: disable=too-many-branches,undefined-variable
if outbound:
try:
c = BMConnectionPool().outboundConnections[destination]
@ -111,33 +170,39 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
self.tableWidgetConnectionCount.setUpdatesEnabled(False)
self.tableWidgetConnectionCount.setSortingEnabled(False)
if add:
self.tableWidgetConnectionCount.insertRow(0)
self.tableWidgetConnectionCount.setItem(0, 0,
self.tableWidgetConnectionCount.setItem(
0, 0,
QtGui.QTableWidgetItem("%s:%i" % (destination.host, destination.port))
)
self.tableWidgetConnectionCount.setItem(0, 2,
)
self.tableWidgetConnectionCount.setItem(
0, 2,
QtGui.QTableWidgetItem("%s" % (c.userAgent))
)
self.tableWidgetConnectionCount.setItem(0, 3,
)
self.tableWidgetConnectionCount.setItem(
0, 3,
QtGui.QTableWidgetItem("%s" % (c.tlsVersion))
)
self.tableWidgetConnectionCount.setItem(0, 4,
QtGui.QTableWidgetItem("%s" % (",".join(map(str,c.streams))))
)
)
self.tableWidgetConnectionCount.setItem(
0, 4,
QtGui.QTableWidgetItem("%s" % (",".join(map(str, c.streams))))
)
try:
# FIXME hard coded stream no
# .. todo:: FIXME: hard coded stream no
rating = "%.1f" % (knownnodes.knownNodes[1][destination]['rating'])
except KeyError:
rating = "-"
self.tableWidgetConnectionCount.setItem(0, 1,
self.tableWidgetConnectionCount.setItem(
0, 1,
QtGui.QTableWidgetItem("%s" % (rating))
)
)
if outbound:
brush = QtGui.QBrush(QtGui.QColor("yellow"), QtCore.Qt.SolidPattern)
else:
brush = QtGui.QBrush(QtGui.QColor("green"), QtCore.Qt.SolidPattern)
for j in (range(1)):
for j in range(1):
self.tableWidgetConnectionCount.item(0, j).setBackground(brush)
self.tableWidgetConnectionCount.item(0, 0).setData(QtCore.Qt.UserRole, destination)
self.tableWidgetConnectionCount.item(0, 1).setData(QtCore.Qt.UserRole, outbound)
@ -148,11 +213,16 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.UserRole).toPyObject() == outbound:
self.tableWidgetConnectionCount.removeRow(i)
break
self.tableWidgetConnectionCount.setUpdatesEnabled(True)
self.tableWidgetConnectionCount.setSortingEnabled(True)
self.labelTotalConnections.setText(_translate(
"networkstatus", "Total Connections: %1").arg(str(self.tableWidgetConnectionCount.rowCount())))
# FYI: The 'singlelistener' thread sets the icon color to green when it receives an incoming connection, meaning that the user's firewall is configured correctly.
self.labelTotalConnections.setText(
_translate(
"networkstatus", "Total Connections: %1").arg(
str(self.tableWidgetConnectionCount.rowCount())))
# FYI: The 'singlelistener' thread sets the icon color to green when it
# receives an incoming connection, meaning that the user's firewall is
# configured correctly.
if self.tableWidgetConnectionCount.rowCount() and shared.statusIconColor == 'red':
self.window().setStatusIcon('yellow')
elif self.tableWidgetConnectionCount.rowCount() == 0 and shared.statusIconColor != "red":
@ -160,8 +230,9 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
# timer driven
def runEveryTwoSeconds(self):
self.labelLookupsPerSecond.setText(_translate(
"networkstatus", "Inventory lookups per second: %1").arg(str(Inventory().numberOfInventoryLookupsPerformed/2)))
"""Updates counters, runs every 2 seconds if the timer is running"""
self.labelLookupsPerSecond.setText(_translate("networkstatus", "Inventory lookups per second: %1").arg(
str(Inventory().numberOfInventoryLookupsPerformed / 2)))
Inventory().numberOfInventoryLookupsPerformed = 0
self.updateNumberOfBytes()
self.updateNumberOfObjectsToBeSynced()

View File

@ -1,40 +1,41 @@
"""
src/class_singleWorker.py
=========================
"""
# pylint: disable=protected-access,too-many-branches,too-many-statements,no-self-use,too-many-lines,too-many-locals
from __future__ import division
import time
import threading
import hashlib
from struct import pack
# used when the API must execute an outside program
from subprocess import call # nosec
import threading
import time
from binascii import hexlify, unhexlify
from struct import pack
from subprocess import call # nosec
import tr
import defaults
import helper_inbox
import helper_msgcoding
import helper_random
import highlevelcrypto
import l10n
import proofofwork
import protocol
import queues
import state
import shared
import defaults
import highlevelcrypto
import proofofwork
import helper_inbox
import helper_random
import helper_msgcoding
import state
import tr
from addresses import calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint
from bmconfigparser import BMConfigParser
from debug import logger
from inventory import Inventory
from addresses import (
decodeAddress, encodeVarint, decodeVarint, calculateInventoryHash
)
# from helper_generic import addDataPadding
from helper_sql import sqlExecute, sqlQuery
from helper_threading import StoppableThread
from helper_sql import sqlQuery, sqlExecute
from inventory import Inventory
# This thread, of which there is only one, does the heavy lifting:
# calculating POWs.
def sizeof_fmt(num, suffix='h/s'):
"""Format hashes per seconds nicely (SI prefix)"""
for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']:
if abs(num) < 1000.0:
return "%3.1f%s%s" % (num, unit, suffix)
@ -43,14 +44,16 @@ def sizeof_fmt(num, suffix='h/s'):
class singleWorker(threading.Thread, StoppableThread):
"""Thread for performing PoW"""
def __init__(self):
# QThread.__init__(self, parent)
threading.Thread.__init__(self, name="singleWorker")
self.initStop()
proofofwork.init()
def stopThread(self):
"""Signal through the queue that the thread should be stopped"""
try:
queues.workerQueue.put(("stopThread", "data"))
except:
@ -58,6 +61,7 @@ class singleWorker(threading.Thread, StoppableThread):
super(singleWorker, self).stopThread()
def run(self):
# pylint: disable=attribute-defined-outside-init
while not state.sqlReady and state.shutdown == 0:
self.stop.wait(2)
@ -96,12 +100,12 @@ class singleWorker(threading.Thread, StoppableThread):
'''SELECT ackdata FROM sent WHERE status = 'msgsent' ''')
for row in queryreturn:
ackdata, = row
logger.info('Watching for ackdata ' + hexlify(ackdata))
logger.info('Watching for ackdata %s', hexlify(ackdata))
shared.ackdataForWhichImWatching[ackdata] = 0
# Fix legacy (headerless) watched ackdata to include header
for oldack in shared.ackdataForWhichImWatching.keys():
if (len(oldack) == 32):
for oldack in shared.ackdataForWhichImWatching:
if len(oldack) == 32:
# attach legacy header, always constant (msg/1/1)
newack = '\x00\x00\x00\x02\x01\x01' + oldack
shared.ackdataForWhichImWatching[newack] = 0
@ -226,19 +230,9 @@ class singleWorker(threading.Thread, StoppableThread):
# inventoryHash = calculateInventoryHash(payload)
return payload
# This function also broadcasts out the pubkey message
# once it is done with the POW
def doPOWForMyV2Pubkey(self, adressHash):
""" This function also broadcasts out the pubkey message once it is done with the POW"""
# Look up my stream number based on my address hash
"""configSections = shared.config.addresses()
for addressInKeysFile in configSections:
if addressInKeysFile != 'bitmessagesettings':
status, addressVersionNumber, streamNumber, \
hashFromThisParticularAddress = \
decodeAddress(addressInKeysFile)
if hash == hashFromThisParticularAddress:
myAddress = addressInKeysFile
break"""
myAddress = shared.myAddressesByHash[adressHash]
# status
_, addressVersionNumber, streamNumber, adressHash = decodeAddress(myAddress)
@ -289,11 +283,12 @@ class singleWorker(threading.Thread, StoppableThread):
# before this finished.
pass
# If this isn't a chan address, this function assembles the pubkey data,
# does the necessary POW and sends it out. If it *is* a chan then it
# assembles the pubkey and stores is in the pubkey table so that we can
# send messages to "ourselves".
def sendOutOrStoreMyV3Pubkey(self, adressHash):
"""
If this isn't a chan address, this function assembles the pubkey data, does the necessary POW and sends it out.
If it *is* a chan then it assembles the pubkey and stores is in the pubkey table so that we can send messages
to "ourselves".
"""
try:
myAddress = shared.myAddressesByHash[adressHash]
except:
@ -357,7 +352,7 @@ class singleWorker(threading.Thread, StoppableThread):
Inventory()[inventoryHash] = (
objectType, streamNumber, payload, embeddedTime, '')
logger.info('broadcasting inv with hash: ' + hexlify(inventoryHash))
logger.info('broadcasting inv with hash: %s', hexlify(inventoryHash))
queues.invQueue.put((streamNumber, inventoryHash))
queues.UISignalQueue.put(('updateStatusBar', ''))
@ -370,9 +365,12 @@ class singleWorker(threading.Thread, StoppableThread):
# before this finished.
pass
# If this isn't a chan address, this function assembles
# the pubkey data, does the necessary POW and sends it out.
def sendOutOrStoreMyV4Pubkey(self, myAddress):
"""
It doesn't send directly anymore. It put is to a queue for another thread to send at an appropriate time,
whereas in the past it directly appended it to the outgoing buffer, I think. Same with all the other methods in
this class.
"""
if not BMConfigParser().has_section(myAddress):
# The address has been deleted.
return
@ -444,7 +442,7 @@ class singleWorker(threading.Thread, StoppableThread):
doubleHashOfAddressData[32:]
)
logger.info('broadcasting inv with hash: ' + hexlify(inventoryHash))
logger.info('broadcasting inv with hash: %s', hexlify(inventoryHash))
queues.invQueue.put((streamNumber, inventoryHash))
queues.UISignalQueue.put(('updateStatusBar', ''))
@ -459,6 +457,7 @@ class singleWorker(threading.Thread, StoppableThread):
)
def sendBroadcast(self):
"""Send a broadcast-type object (assemble the object, perform PoW and put it to the inv announcement queue)"""
# Reset just in case
sqlExecute(
'''UPDATE sent SET status='broadcastqueued' '''
@ -627,6 +626,8 @@ class singleWorker(threading.Thread, StoppableThread):
)
def sendMsg(self):
"""Send a message-type object (assemble the object, perform PoW and put it to the inv announcement queue)"""
# pylint: disable=too-many-nested-blocks
# Reset just in case
sqlExecute(
'''UPDATE sent SET status='msgqueued' '''
@ -740,10 +741,8 @@ class singleWorker(threading.Thread, StoppableThread):
# object associated with the tag for this toAddress.
if toAddressVersionNumber >= 4:
doubleHashOfToAddressData = hashlib.sha512(
hashlib.sha512(encodeVarint(
toAddressVersionNumber) +
encodeVarint(toStreamNumber) +
toRipe
hashlib.sha512(
encodeVarint(toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe
).digest()
).digest()
# The first half of the sha512 hash.
@ -834,7 +833,7 @@ class singleWorker(threading.Thread, StoppableThread):
queryreturn = sqlQuery(
'SELECT transmitdata FROM pubkeys WHERE address=?',
toaddress)
for row in queryreturn:
for row in queryreturn: # pylint: disable=redefined-outer-name
pubkeyPayload, = row
# The pubkey message is stored with the following items
@ -939,40 +938,43 @@ class singleWorker(threading.Thread, StoppableThread):
requiredAverageProofOfWorkNonceTrialsPerByte,
requiredPayloadLengthExtraBytes
)
queues.UISignalQueue.put((
'updateSentItemStatusByAckdata', (
ackdata,
tr._translate(
"MainWindow",
"Doing work necessary to send message.\n"
"Receiver\'s required difficulty: %1"
" and %2"
).arg(str(float(
requiredAverageProofOfWorkNonceTrialsPerByte) /
defaults.networkDefaultProofOfWorkNonceTrialsPerByte
)).arg(str(float(
requiredPayloadLengthExtraBytes) /
defaults.networkDefaultPayloadLengthExtraBytes
)))))
queues.UISignalQueue.put(
(
'updateSentItemStatusByAckdata',
(
ackdata,
tr._translate(
"MainWindow",
"Doing work necessary to send message.\n"
"Receiver\'s required difficulty: %1"
" and %2"
).arg(
str(
float(requiredAverageProofOfWorkNonceTrialsPerByte) /
defaults.networkDefaultProofOfWorkNonceTrialsPerByte
)
).arg(
str(
float(requiredPayloadLengthExtraBytes) /
defaults.networkDefaultPayloadLengthExtraBytes
)
)
)
)
)
if status != 'forcepow':
if (requiredAverageProofOfWorkNonceTrialsPerByte
> BMConfigParser().getint(
'bitmessagesettings',
'maxacceptablenoncetrialsperbyte'
) and
BMConfigParser().getint(
'bitmessagesettings',
'maxacceptablenoncetrialsperbyte'
) != 0) or (
requiredPayloadLengthExtraBytes
> BMConfigParser().getint(
'bitmessagesettings',
'maxacceptablepayloadlengthextrabytes'
) and
BMConfigParser().getint(
'bitmessagesettings',
'maxacceptablepayloadlengthextrabytes'
) != 0):
maxacceptablenoncetrialsperbyte = BMConfigParser().getint(
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte')
maxacceptablepayloadlengthextrabytes = BMConfigParser().getint(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')
cond1 = maxacceptablenoncetrialsperbyte and \
requiredAverageProofOfWorkNonceTrialsPerByte > maxacceptablenoncetrialsperbyte
cond2 = maxacceptablepayloadlengthextrabytes and \
requiredPayloadLengthExtraBytes > maxacceptablepayloadlengthextrabytes
if cond1 or cond2:
# The demanded difficulty is more than
# we are willing to do.
sqlExecute(
@ -988,19 +990,15 @@ class singleWorker(threading.Thread, StoppableThread):
" the recipient (%1 and %2) is"
" more difficult than you are"
" willing to do. %3"
).arg(str(float(
requiredAverageProofOfWorkNonceTrialsPerByte)
/ defaults.networkDefaultProofOfWorkNonceTrialsPerByte
)).arg(str(float(
requiredPayloadLengthExtraBytes)
/ defaults.networkDefaultPayloadLengthExtraBytes
)).arg(l10n.formatTimestamp()))
))
).arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) /
defaults.networkDefaultProofOfWorkNonceTrialsPerByte)).arg(
str(float(requiredPayloadLengthExtraBytes) /
defaults.networkDefaultPayloadLengthExtraBytes)).arg(
l10n.formatTimestamp()))))
continue
else: # if we are sending a message to ourselves or a chan..
logger.info('Sending a message.')
logger.debug(
'First 150 characters of message: %r', message[:150])
logger.debug('First 150 characters of message: %r', message[:150])
behaviorBitfield = protocol.getBitfield(fromaddress)
try:
@ -1199,16 +1197,14 @@ class singleWorker(threading.Thread, StoppableThread):
Inventory()[inventoryHash] = (
objectType, toStreamNumber, encryptedPayload, embeddedTime, '')
if BMConfigParser().has_section(toaddress) or \
not protocol.checkBitfield(
behaviorBitfield, protocol.BITFIELD_DOESACK):
not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK):
queues.UISignalQueue.put((
'updateSentItemStatusByAckdata', (
ackdata,
tr._translate(
"MainWindow",
"Message sent. Sent at %1"
).arg(l10n.formatTimestamp()))
))
).arg(l10n.formatTimestamp()))))
else:
# not sending to a chan or one of my addresses
queues.UISignalQueue.put((
@ -1229,8 +1225,7 @@ class singleWorker(threading.Thread, StoppableThread):
# Update the sent message in the sent table with the
# necessary information.
if BMConfigParser().has_section(toaddress) or \
not protocol.checkBitfield(
behaviorBitfield, protocol.BITFIELD_DOESACK):
not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK):
newStatus = 'msgsentnoackexpected'
else:
newStatus = 'msgsent'
@ -1270,6 +1265,7 @@ class singleWorker(threading.Thread, StoppableThread):
call([apiNotifyPath, "newMessage"])
def requestPubKey(self, toAddress):
"""Send a getpubkey object"""
toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress(
toAddress)
if toStatus != 'success':
@ -1286,7 +1282,7 @@ class singleWorker(threading.Thread, StoppableThread):
''' LIMIT 1''',
toAddress
)
if len(queryReturn) == 0:
if not queryReturn:
logger.critical(
'BUG: Why are we requesting the pubkey for %s'
' if there are no messages in the sent folder'
@ -1389,16 +1385,14 @@ class singleWorker(threading.Thread, StoppableThread):
).arg(l10n.formatTimestamp()))
))
def generateFullAckMessage(self, ackdata, toStreamNumber, TTL):
# It might be perfectly fine to just use the same TTL for
# the ackdata that we use for the message. But I would rather
# it be more difficult for attackers to associate ackData with
# the associated msg object. However, users would want the TTL
# of the acknowledgement to be about the same as they set
# for the message itself. So let's set the TTL of the
# acknowledgement to be in one of three 'buckets': 1 hour, 7
# days, or 28 days, whichever is relatively close to what the
# user specified.
def generateFullAckMessage(self, ackdata, _, TTL):
"""
It might be perfectly fine to just use the same TTL for the ackdata that we use for the message. But I would
rather it be more difficult for attackers to associate ackData with the associated msg object. However, users
would want the TTL of the acknowledgement to be about the same as they set for the message itself. So let's set
the TTL of the acknowledgement to be in one of three 'buckets': 1 hour, 7 days, or 28 days, whichever is
relatively close to what the user specified.
"""
if TTL < 24 * 60 * 60: # 1 day
TTL = 24 * 60 * 60 # 1 day
elif TTL < 7 * 24 * 60 * 60: # 1 week