various small changes

This commit is contained in:
Jonathan Warren 2013-01-22 00:21:32 -05:00
parent f7f8545b97
commit dffbffca45
3 changed files with 55 additions and 64 deletions

View File

@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'about.ui' # Form implementation generated from reading ui file 'about.ui'
# #
# Created: Tue Dec 18 14:32:14 2012 # Created: Mon Jan 21 22:32:55 2013
# by: PyQt4 UI code generator 4.9.4 # by: PyQt4 UI code generator 4.9.5
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -17,9 +17,9 @@ except AttributeError:
class Ui_aboutDialog(object): class Ui_aboutDialog(object):
def setupUi(self, aboutDialog): def setupUi(self, aboutDialog):
aboutDialog.setObjectName(_fromUtf8("aboutDialog")) aboutDialog.setObjectName(_fromUtf8("aboutDialog"))
aboutDialog.resize(360, 402) aboutDialog.resize(360, 315)
self.buttonBox = QtGui.QDialogButtonBox(aboutDialog) self.buttonBox = QtGui.QDialogButtonBox(aboutDialog)
self.buttonBox.setGeometry(QtCore.QRect(20, 360, 311, 32)) self.buttonBox.setGeometry(QtCore.QRect(20, 280, 311, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
@ -42,10 +42,6 @@ class Ui_aboutDialog(object):
self.label_3.setGeometry(QtCore.QRect(20, 210, 331, 61)) self.label_3.setGeometry(QtCore.QRect(20, 210, 331, 61))
self.label_3.setWordWrap(True) self.label_3.setWordWrap(True)
self.label_3.setObjectName(_fromUtf8("label_3")) self.label_3.setObjectName(_fromUtf8("label_3"))
self.label_4 = QtGui.QLabel(aboutDialog)
self.label_4.setGeometry(QtCore.QRect(20, 280, 331, 81))
self.label_4.setWordWrap(True)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.label_5 = QtGui.QLabel(aboutDialog) self.label_5 = QtGui.QLabel(aboutDialog)
self.label_5.setGeometry(QtCore.QRect(10, 180, 341, 20)) self.label_5.setGeometry(QtCore.QRect(10, 180, 341, 20))
self.label_5.setAlignment(QtCore.Qt.AlignCenter) self.label_5.setAlignment(QtCore.Qt.AlignCenter)
@ -61,7 +57,6 @@ class Ui_aboutDialog(object):
self.label.setText(QtGui.QApplication.translate("aboutDialog", "PyBitmessage", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("aboutDialog", "PyBitmessage", None, QtGui.QApplication.UnicodeUTF8))
self.labelVersion.setText(QtGui.QApplication.translate("aboutDialog", "version ?", None, QtGui.QApplication.UnicodeUTF8)) self.labelVersion.setText(QtGui.QApplication.translate("aboutDialog", "version ?", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("aboutDialog", "Copyright © 2012 Jonathan Warren", None, QtGui.QApplication.UnicodeUTF8)) self.label_2.setText(QtGui.QApplication.translate("aboutDialog", "Copyright © 2012 Jonathan Warren", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("aboutDialog", "Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php", None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setText(QtGui.QApplication.translate("aboutDialog", "<html><head/><body><p>Distributed under the MIT/X11 software license, see the accompanying file license.txt or <a href=\"http://www.opensource.org/licenses/mit-license.php\"><span style=\" text-decoration: underline; color:#0000ff;\">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.label_4.setText(QtGui.QApplication.translate("aboutDialog", "This product includes Python-RSA (http://stuvel.eu/rsa) originally written by Sybren A. Stüvel <sybren@stuvel.eu>. It is licensed under the Apache 2.0 license: http://www.apache.org/licenses/LICENSE-2.0", None, QtGui.QApplication.UnicodeUTF8))
self.label_5.setText(QtGui.QApplication.translate("aboutDialog", "This is Beta software.", None, QtGui.QApplication.UnicodeUTF8)) self.label_5.setText(QtGui.QApplication.translate("aboutDialog", "This is Beta software.", None, QtGui.QApplication.UnicodeUTF8))

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>360</width> <width>360</width>
<height>402</height> <height>315</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -17,7 +17,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>20</x>
<y>360</y> <y>280</y>
<width>311</width> <width>311</width>
<height>32</height> <height>32</height>
</rect> </rect>
@ -90,23 +90,7 @@
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Distributed under the MIT/X11 software license, see the accompanying file license.txt or &lt;a href=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.opensource.org/licenses/mit-license.php&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>20</x>
<y>280</y>
<width>331</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string>This product includes Python-RSA (http://stuvel.eu/rsa) originally written by Sybren A. Stüvel &lt;sybren@stuvel.eu&gt;. It is licensed under the Apache 2.0 license: http://www.apache.org/licenses/LICENSE-2.0</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>

View File

@ -137,7 +137,9 @@ class outgoingSynSender(QThread):
sd.sendVersionMessage() sd.sendVersionMessage()
except socks.GeneralProxyError, err: except socks.GeneralProxyError, err:
printLock.acquire()
print 'Could NOT connect to', HOST, 'during outgoing attempt.', err print 'Could NOT connect to', HOST, 'during outgoing attempt.', err
printLock.release()
PORT, timeLastSeen = knownNodes[self.streamNumber][HOST] PORT, timeLastSeen = knownNodes[self.streamNumber][HOST]
if (int(time.time())-timeLastSeen) > 172800 and len(knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure. if (int(time.time())-timeLastSeen) > 172800 and len(knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure.
del knownNodes[self.streamNumber][HOST] del knownNodes[self.streamNumber][HOST]
@ -156,7 +158,9 @@ class outgoingSynSender(QThread):
print 'Bitmessage MIGHT be having trouble connecting to the SOCKS server. '+str(err) print 'Bitmessage MIGHT be having trouble connecting to the SOCKS server. '+str(err)
#self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"Problem: Bitmessage can not connect to the SOCKS server. "+str(err)) #self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),"Problem: Bitmessage can not connect to the SOCKS server. "+str(err))
else: else:
printLock.acquire()
print 'Could NOT connect to', HOST, 'during outgoing attempt.', err print 'Could NOT connect to', HOST, 'during outgoing attempt.', err
printLock.release()
PORT, timeLastSeen = knownNodes[self.streamNumber][HOST] PORT, timeLastSeen = knownNodes[self.streamNumber][HOST]
if (int(time.time())-timeLastSeen) > 172800 and len(knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure. if (int(time.time())-timeLastSeen) > 172800 and len(knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure.
del knownNodes[self.streamNumber][HOST] del knownNodes[self.streamNumber][HOST]
@ -188,11 +192,11 @@ class singleListener(QThread):
while True: while True:
#We don't want to accept incoming connections if the user is using a SOCKS proxy. If they eventually select proxy 'none' then this will start listening for connections. #We don't want to accept incoming connections if the user is using a SOCKS proxy. If the user eventually select proxy 'none' then this will start listening for connections.
while config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': while config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS':
time.sleep(10) time.sleep(10)
a,(HOST,PORT) = sock.accept() a,(HOST,PORT) = sock.accept()
#Users are finding that if they run more than one node in the same network (thus with the same public IP), they can not connect with the second node. This is because this section of code won't accept the connection from the same IP. This problem will go away when the Bitmessage network grows behond being tiny but in the mean time, I'll comment out this code section. #Users are finding that if they run more than one node in the same network (thus with the same public IP), they can not connect with the second node. This is because this section of code won't accept the connection from the same IP. This problem will go away when the Bitmessage network grows beyond being tiny but in the mean time I'll comment out this code section.
"""while HOST in connectedHostsList: """while HOST in connectedHostsList:
print 'incoming connection is from a host in connectedHostsList (we are already connected to it). Ignoring it.' print 'incoming connection is from a host in connectedHostsList (we are already connected to it). Ignoring it.'
a.close() a.close()
@ -226,10 +230,10 @@ class receiveDataThread(QThread):
self.streamNumber = streamNumber self.streamNumber = streamNumber
self.selfInitiatedConnectionList = selfInitiatedConnectionList self.selfInitiatedConnectionList = selfInitiatedConnectionList
self.selfInitiatedConnectionList.append(self) self.selfInitiatedConnectionList.append(self)
self.payloadLength = 0 self.payloadLength = 0 #This is the protocol payload length thus it doesn't include the 24 byte message header
self.receivedgetbiginv = False self.receivedgetbiginv = False #Gets set to true once we receive a getbiginv message from our peer. An abusive peer might request it too much so we use this variable to check whether they have already asked for a big inv message.
self.objectsThatWeHaveYetToGet = {} self.objectsThatWeHaveYetToGet = {}
connectedHostsList[self.HOST] = 0 connectedHostsList[self.HOST] = 0 #The very fact that this receiveData thread exists shows that we are connected to the remote host. Let's add it to this list so that the outgoingSynSender thread doesn't try to connect to it.
self.connectionIsOrWasFullyEstablished = False #set to true after the remote node and I accept each other's version messages. This is needed to allow the user interface to accurately reflect the current number of connections. self.connectionIsOrWasFullyEstablished = False #set to true after the remote node and I accept each other's version messages. This is needed to allow the user interface to accurately reflect the current number of connections.
if self.streamNumber == -1: #This was an incoming connection. Send out a version message if we accept the other node's version message. if self.streamNumber == -1: #This was an incoming connection. Send out a version message if we accept the other node's version message.
self.initiatedConnection = False self.initiatedConnection = False
@ -245,7 +249,7 @@ class receiveDataThread(QThread):
self.data = self.data + self.sock.recv(65536) self.data = self.data + self.sock.recv(65536)
except socket.timeout: except socket.timeout:
printLock.acquire() printLock.acquire()
print 'Timeout occurred waiting for data. Closing thread.' print 'Timeout occurred waiting for data. Closing receiveData thread.'
printLock.release() printLock.release()
break break
except Exception, err: except Exception, err:
@ -256,7 +260,7 @@ class receiveDataThread(QThread):
#print 'Received', repr(self.data) #print 'Received', repr(self.data)
if self.data == "": if self.data == "":
printLock.acquire() printLock.acquire()
print 'Connection closed.' print 'Connection closed. Closing receiveData thread.'
printLock.release() printLock.release()
break break
else: else:
@ -271,14 +275,19 @@ class receiveDataThread(QThread):
try: try:
self.selfInitiatedConnectionList.remove(self) self.selfInitiatedConnectionList.remove(self)
print 'removed self from ConnectionList' printLock.acquire()
print 'removed self (a receiveDataThread) from ConnectionList'
printLock.release()
except: except:
pass pass
broadcastToSendDataQueues((self.streamNumber, 'shutdown', self.HOST)) broadcastToSendDataQueues((0, 'shutdown', self.HOST))
if self.connectionIsOrWasFullyEstablished: #We don't want to decrement the number of connections and show the result if we never incremented it in the first place (which we only do if the connection is fully established- meaning that both nodes accepted each other's version packets.) if self.connectionIsOrWasFullyEstablished: #We don't want to decrement the number of connections and show the result if we never incremented it in the first place (which we only do if the connection is fully established- meaning that both nodes accepted each other's version packets.)
connectionsCountLock.acquire() connectionsCountLock.acquire()
connectionsCount[self.streamNumber] -= 1 connectionsCount[self.streamNumber] -= 1
self.emit(SIGNAL("updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject)"),self.streamNumber,connectionsCount[self.streamNumber]) self.emit(SIGNAL("updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject)"),self.streamNumber,connectionsCount[self.streamNumber])
printLock.acquire()
print 'Updating network status tab with current connections count:', connectionsCount[self.streamNumber]
printLock.release()
connectionsCountLock.release() connectionsCountLock.release()
try: try:
del connectedHostsList[self.HOST] del connectedHostsList[self.HOST]
@ -349,13 +358,17 @@ class receiveDataThread(QThread):
random.seed() random.seed()
objectHash, = random.sample(self.objectsThatWeHaveYetToGet, 1) objectHash, = random.sample(self.objectsThatWeHaveYetToGet, 1)
if objectHash in inventory: if objectHash in inventory:
printLock.acquire()
print 'Inventory (in memory) already has object listed in inv message.' print 'Inventory (in memory) already has object listed in inv message.'
printLock.release()
del self.objectsThatWeHaveYetToGet[objectHash] del self.objectsThatWeHaveYetToGet[objectHash]
elif isInSqlInventory(objectHash): elif isInSqlInventory(objectHash):
printLock.acquire()
print 'Inventory (SQL on disk) already has object listed in inv message.' print 'Inventory (SQL on disk) already has object listed in inv message.'
printLock.release()
del self.objectsThatWeHaveYetToGet[objectHash] del self.objectsThatWeHaveYetToGet[objectHash]
else: else:
print 'processData function making request for object:', objectHash.encode('hex') #print 'processData function making request for object:', objectHash.encode('hex')
self.sendgetdata(objectHash) self.sendgetdata(objectHash)
del self.objectsThatWeHaveYetToGet[objectHash] #It is possible that the remote node doesn't respond with the object. In that case, we'll very likely get it from someone else anyway. del self.objectsThatWeHaveYetToGet[objectHash] #It is possible that the remote node doesn't respond with the object. In that case, we'll very likely get it from someone else anyway.
break break
@ -402,9 +415,11 @@ class receiveDataThread(QThread):
print 'broadcasting addr from within connectionFullyEstablished function.' print 'broadcasting addr from within connectionFullyEstablished function.'
printLock.release() printLock.release()
self.broadcastaddr([(int(time.time()), self.streamNumber, 1, self.HOST, remoteNodeIncomingPort)]) #This lets all of our peers know about this new node. self.broadcastaddr([(int(time.time()), self.streamNumber, 1, self.HOST, remoteNodeIncomingPort)]) #This lets all of our peers know about this new node.
self.sendaddr() #This is one addr message to this one peer. self.sendaddr() #This is one large addr message to this one peer.
if connectionsCount[self.streamNumber] > 150: if connectionsCount[self.streamNumber] > 150:
printLock.acquire()
print 'We are connected to too many people. Closing connection.' print 'We are connected to too many people. Closing connection.'
printLock.release()
self.sock.close() self.sock.close()
return return
self.sendBigInv() self.sendBigInv()
@ -427,18 +442,19 @@ class receiveDataThread(QThread):
for row in queryreturn: for row in queryreturn:
hash, = row hash, = row
bigInvList[hash] = 0 bigInvList[hash] = 0
#print 'bigInvList:', bigInvList #We also have messages in our inventory in memory (which is a python dictionary). Let's fetch those too.
for hash, storedValue in inventory.items(): for hash, storedValue in inventory.items():
objectType, streamNumber, payload, receivedTime = storedValue objectType, streamNumber, payload, receivedTime = storedValue
if streamNumber == self.streamNumber and receivedTime > int(time.time())-maximumAgeOfObjectsThatIAdvertiseToOthers: if streamNumber == self.streamNumber and receivedTime > int(time.time())-maximumAgeOfObjectsThatIAdvertiseToOthers:
bigInvList[hash] = 0 bigInvList[hash] = 0
numberOfObjectsInInvMessage = 0 numberOfObjectsInInvMessage = 0
payload = '' payload = ''
#Now let us start appending all of these hashes together. They will be sent out in a big inv message to our new peer.
for hash, storedValue in bigInvList.items(): for hash, storedValue in bigInvList.items():
payload += hash payload += hash
numberOfObjectsInInvMessage += 1 numberOfObjectsInInvMessage += 1
if numberOfObjectsInInvMessage >= 50000: #We can only send a max of 50000 items per inv message but we may have more objects to advertise. They must be split up into multiple inv messages. if numberOfObjectsInInvMessage >= 50000: #We can only send a max of 50000 items per inv message but we may have more objects to advertise. They must be split up into multiple inv messages.
sendinvMessageToJustThisOnePeer(numberOfObjectsInInvMessage,payload) self.sendinvMessageToJustThisOnePeer(numberOfObjectsInInvMessage,payload)
payload = '' payload = ''
numberOfObjectsInInvMessage = 0 numberOfObjectsInInvMessage = 0
if numberOfObjectsInInvMessage > 0: if numberOfObjectsInInvMessage > 0:
@ -451,7 +467,7 @@ class receiveDataThread(QThread):
headerData = headerData + 'inv\x00\x00\x00\x00\x00\x00\x00\x00\x00' headerData = headerData + 'inv\x00\x00\x00\x00\x00\x00\x00\x00\x00'
headerData = headerData + pack('>L',len(payload)) headerData = headerData + pack('>L',len(payload))
headerData = headerData + hashlib.sha512(payload).digest()[:4] headerData = headerData + hashlib.sha512(payload).digest()[:4]
print 'Sending inv message to just this one peer' print 'Sending huge inv message to just this one peer'
self.sock.send(headerData + payload) self.sock.send(headerData + payload)
#We have received a broadcast message #We have received a broadcast message
@ -595,8 +611,6 @@ class receiveDataThread(QThread):
print 'The time in the msg message is too old. Ignoring it. Time:', embeddedTime print 'The time in the msg message is too old. Ignoring it. Time:', embeddedTime
return return
readPosition += 4 readPosition += 4
streamNumberAsClaimedByMsg, streamNumberAsClaimedByMsgLength = decodeVarint(self.data[readPosition:readPosition+9]) streamNumberAsClaimedByMsg, streamNumberAsClaimedByMsgLength = decodeVarint(self.data[readPosition:readPosition+9])
if streamNumberAsClaimedByMsg != self.streamNumber: if streamNumberAsClaimedByMsg != self.streamNumber:
print 'The stream number encoded in this msg (' + streamNumberAsClaimedByMsg + ') message does not match the stream number on which it was received. Ignoring it.' print 'The stream number encoded in this msg (' + streamNumberAsClaimedByMsg + ') message does not match the stream number on which it was received. Ignoring it.'
@ -632,7 +646,7 @@ class receiveDataThread(QThread):
sqlReturnQueue.get() sqlReturnQueue.get()
sqlLock.release() sqlLock.release()
self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),self.data[readPosition:24+self.payloadLength],'Acknowledgement of the message received just now.') self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),self.data[readPosition:24+self.payloadLength],'Acknowledgement of the message received just now.')
flushInventory() #so that we won't accidentially receive this message twice if the user restarts Bitmessage soon. flushInventory() #so that we won't accidentially receive this message twice if the user restarts Bitmessage both soon and un-cleanly.
return return
else: else:
printLock.acquire() printLock.acquire()
@ -806,18 +820,12 @@ class receiveDataThread(QThread):
sqlReturnQueue.get() sqlReturnQueue.get()
sqlLock.release() sqlLock.release()
self.emit(SIGNAL("displayNewMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),inventoryHash,toAddress,fromAddress,subject,body) self.emit(SIGNAL("displayNewMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),inventoryHash,toAddress,fromAddress,subject,body)
#Now let's send the acknowledgement #Now let's send the acknowledgement. We'll need to make sure that our client will properly process the ackData; if the packet is malformed, we could clear out self.data and an attacker could use that behavior to determine that we were capable of decoding this message.
#POW, = unpack('>Q',hashlib.sha512(hashlib.sha512(ackData[24:]).digest()).digest()[4:12])
#if POW <= 2**64 / ((len(ackData[24:])+payloadLengthExtraBytes) * averageProofOfWorkNonceTrialsPerByte):
#print 'The POW is strong enough that this ackdataPayload will be accepted by the Bitmessage network.'
#Currently PyBitmessage only supports sending a message with the acknowledgement in the form of a msg message. But future versions, and other clients, could send any object and this software will relay them. This can be used to relay identifying information, like your public key, through another Bitmessage host in case you believe that your Internet connection is being individually watched. You may pick a random address, hope its owner is online, and send a message with encoding type 0 so that they ignore the message but send your acknowledgement data over the network. If you send and receive many messages, it would also be clever to take someone else's acknowledgement data and use it for your own. Assuming that your message is delivered successfully, both will be acknowledged simultaneously (though if it is not delivered successfully, you will be in a pickle.)
#print 'self.data before:', repr(self.data)
#We'll need to make sure that our client will properly process the ackData; if the packet is malformed, we could clear out self.data and an attacker could use that behavior to determine that we were capable of decoding this message.
ackDataValidThusFar = True ackDataValidThusFar = True
if len(ackData) < 24: if len(ackData) < 24:
print 'The length of ackData is unreasonably short. Not sending ackData.' print 'The length of ackData is unreasonably short. Not sending ackData.'
ackDataValidThusFar = False ackDataValidThusFar = False
if ackData[0:4] != '\xe9\xbe\xb4\xd9': elif ackData[0:4] != '\xe9\xbe\xb4\xd9':
print 'Ackdata magic bytes were wrong. Not sending ackData.' print 'Ackdata magic bytes were wrong. Not sending ackData.'
ackDataValidThusFar = False ackDataValidThusFar = False
if ackDataValidThusFar: if ackDataValidThusFar:
@ -1234,7 +1242,7 @@ class receiveDataThread(QThread):
#print 'queryreturn', queryreturn #print 'queryreturn', queryreturn
if queryreturn == []: if queryreturn == []:
print 'pubkey request is for me but the pubkey is not in our database of pubkeys. Making it.' print 'pubkey request is for me but the pubkey is not in our database of pubkeys. Making it.'
payload = pack('>I',(int(time.time()))) #todo: fuzz this time payload = pack('>I',(int(time.time())+random.randrange(-300, 300))) #the current time plus or minus five minutes
payload += encodeVarint(2) #Address version number payload += encodeVarint(2) #Address version number
payload += encodeVarint(streamNumber) payload += encodeVarint(streamNumber)
payload += '\x00\x00\x00\x01' #bitfield of features supported by me (see the wiki). payload += '\x00\x00\x00\x01' #bitfield of features supported by me (see the wiki).
@ -1326,7 +1334,6 @@ class receiveDataThread(QThread):
while trialValue > target: while trialValue > target:
nonce += 1 nonce += 1
trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8]) trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8])
#trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + payload).digest()).digest()[4:12])
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
payload = pack('>Q',nonce) + payload payload = pack('>Q',nonce) + payload
@ -1360,6 +1367,9 @@ class receiveDataThread(QThread):
self.broadcastinv(inventoryHash) self.broadcastinv(inventoryHash)
else: else:
#This section hasn't been tested yet. Criteria for success: Alice sends Bob a message. Three days later, Charlie who is completely new to Bitmessage runs the client for the first time then sends a message to Bob and accomplishes this without Bob having to redo the POW for a pubkey message.
print 'Hash in getpubkey request is not for any of my keys.' print 'Hash in getpubkey request is not for any of my keys.'
#..but lets see if we have it stored from when it came in from someone else. #..but lets see if we have it stored from when it came in from someone else.
t = (self.data[36+addressVersionLength+streamNumberLength:56+addressVersionLength+streamNumberLength],) #this prevents SQL injection t = (self.data[36+addressVersionLength+streamNumberLength:56+addressVersionLength+streamNumberLength],) #this prevents SQL injection
@ -1370,7 +1380,7 @@ class receiveDataThread(QThread):
sqlLock.release() sqlLock.release()
print 'queryreturn', queryreturn print 'queryreturn', queryreturn
if queryreturn <> []: if queryreturn <> []:
print 'we have the public key. sending it.' print '...but we have the public key from when it came in from someone else. sending it.'
#We have it. Let's send it. #We have it. Let's send it.
for row in queryreturn: for row in queryreturn:
hash, transmitdata, timeLastRequested = row hash, transmitdata, timeLastRequested = row
@ -1405,7 +1415,7 @@ class receiveDataThread(QThread):
#Send a getdata message to our peer to request the object with the given hash #Send a getdata message to our peer to request the object with the given hash
def sendgetdata(self,hash): def sendgetdata(self,hash):
print 'sending getdata with hash', repr(hash) print 'sending getdata to retrieve object with hash:', hash.encode('hex')
payload = '\x01' + hash payload = '\x01' + hash
headerData = '\xe9\xbe\xb4\xd9' #magic bits, slighly different from Bitcoin's magic bits. headerData = '\xe9\xbe\xb4\xd9' #magic bits, slighly different from Bitcoin's magic bits.
headerData = headerData + 'getdata\x00\x00\x00\x00\x00' headerData = headerData + 'getdata\x00\x00\x00\x00\x00'
@ -1420,7 +1430,9 @@ class receiveDataThread(QThread):
try: try:
for i in range(value): for i in range(value):
hash = self.data[24+lengthOfVarint+(i*32):56+lengthOfVarint+(i*32)] hash = self.data[24+lengthOfVarint+(i*32):56+lengthOfVarint+(i*32)]
print 'getdata request for item:', hash.encode('hex'), 'length', len(hash) printLock.acquire()
print 'received getdata request for item:', hash.encode('hex')
printLock.release()
#print 'inventory is', inventory #print 'inventory is', inventory
if hash in inventory: if hash in inventory:
objectType, streamNumber, payload, receivedTime = inventory[hash] objectType, streamNumber, payload, receivedTime = inventory[hash]
@ -1484,8 +1496,6 @@ class receiveDataThread(QThread):
#Send an inv message with just one hash to all of our peers #Send an inv message with just one hash to all of our peers
def broadcastinv(self,hash): def broadcastinv(self,hash):
print 'sending inv'
#payload = '\x01' + pack('>H',objectType) + hash
payload = '\x01' + hash payload = '\x01' + hash
headerData = '\xe9\xbe\xb4\xd9' #magic bits, slighly different from Bitcoin's magic bits. headerData = '\xe9\xbe\xb4\xd9' #magic bits, slighly different from Bitcoin's magic bits.
headerData = headerData + 'inv\x00\x00\x00\x00\x00\x00\x00\x00\x00' headerData = headerData + 'inv\x00\x00\x00\x00\x00\x00\x00\x00\x00'
@ -1597,7 +1607,7 @@ class receiveDataThread(QThread):
if verbose >= 2: if verbose >= 2:
printLock.acquire() printLock.acquire()
print 'Broadcasting addr with # of entries:', numberOfAddressesInAddrMessage print 'Broadcasting addr with', numberOfAddressesInAddrMessage, 'entries.'
printLock.release() printLock.release()
broadcastToSendDataQueues((self.streamNumber, 'send', datatosend)) broadcastToSendDataQueues((self.streamNumber, 'send', datatosend))
@ -1665,7 +1675,7 @@ class receiveDataThread(QThread):
if verbose >= 2: if verbose >= 2:
printLock.acquire() printLock.acquire()
print 'Sending addr with # of entries:', numberOfAddressesInAddrMessage print 'Sending addr with', numberOfAddressesInAddrMessage, 'entries.'
printLock.release() printLock.release()
self.sock.send(datatosend) self.sock.send(datatosend)
@ -1689,7 +1699,9 @@ class receiveDataThread(QThread):
numberOfStreamsInVersionMessage, lengthOfNumberOfStreamsInVersionMessage = decodeVarint(self.data[readPosition:]) numberOfStreamsInVersionMessage, lengthOfNumberOfStreamsInVersionMessage = decodeVarint(self.data[readPosition:])
readPosition += lengthOfNumberOfStreamsInVersionMessage readPosition += lengthOfNumberOfStreamsInVersionMessage
self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint(self.data[readPosition:]) self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint(self.data[readPosition:])
printLock.acquire()
print 'Remote node stream number:', self.streamNumber print 'Remote node stream number:', self.streamNumber
printLock.release()
#If this was an incoming connection, then the sendData thread doesn't know the stream. We have to set it. #If this was an incoming connection, then the sendData thread doesn't know the stream. We have to set it.
if not self.initiatedConnection: if not self.initiatedConnection:
broadcastToSendDataQueues((0,'setStreamNumber',(self.HOST,self.streamNumber))) broadcastToSendDataQueues((0,'setStreamNumber',(self.HOST,self.streamNumber)))
@ -1785,7 +1797,7 @@ class sendDataThread(QThread):
self.streamNumber = streamNumber self.streamNumber = streamNumber
self.lastTimeISentData = int(time.time()) #If this value increases beyond five minutes ago, we'll send a pong message to keep the connection alive. self.lastTimeISentData = int(time.time()) #If this value increases beyond five minutes ago, we'll send a pong message to keep the connection alive.
printLock.acquire() printLock.acquire()
print 'The streamNumber of this sendDataThread at setup() is', self.streamNumber, self print 'The streamNumber of this sendDataThread (ID:', id(self),') at setup() is', self.streamNumber
printLock.release() printLock.release()
def sendVersionMessage(self): def sendVersionMessage(self):