#Notice that I have divided the networkDefaultProofOfWorkNonceTrialsPerByte by two. This makes the POW requirement easier. This gives us wiggle-room: if we decide that we want to make the POW easier, the change won't obsolete old clients because they already expect a lower POW. If we decide that the current work done by clients feels approperate then we can remove this division by 2 and make the requirement match what is actually done by a sending node. If we want to raise the POW requirement then old nodes will HAVE to upgrade no matter what.
@ -533,6 +536,14 @@ class receiveDataThread(QThread):
iflen(data)<180:
print'The payload length of this broadcast packet is unreasonably low. Someone is probably trying funny business. Ignoring message.'
return
#Let us check to make sure the stream number is correct (thus preventing an individual from sending broadcasts out on the wrong streams or all streams).
print'The stream number encoded in this broadcast message ('+str(streamNumber)+') does not match the stream number on which it was received. Ignoring it.'
return
inventoryLock.acquire()
self.inventoryHash=calculateInventoryHash(data)
ifself.inventoryHashininventory:
@ -577,121 +588,249 @@ class receiveDataThread(QThread):
#A broadcast message has a valid time and POW and requires processing. The recbroadcast function calls this one.
#Cannot decode incoming broadcast versions higher than 1. Assuming the sender isn\' being silly, you should upgrade Bitmessage because this message shall be ignored.
return
readPosition+=broadcastVersionLength
beginningOfPubkeyPosition=readPosition#used when we add the pubkey to our pubkey table
#Cannot decode senderAddressVersion higher than 2. Assuming the sender isn\' being silly, you should upgrade Bitmessage because this message shall be ignored.
ifbroadcastVersion<1orbroadcastVersion>2:
#Cannot decode incoming broadcast versions higher than 2. Assuming the sender isn\' being silly, you should upgrade Bitmessage because this message shall be ignored.
#Cannot decode senderAddressVersion higher than 2. Assuming the sender isn\' being silly, you should upgrade Bitmessage because this message shall be ignored.
print'Time spent deciding that we are not interested in this broadcast:',time.time()-self.messageProcessingStartTime
printLock.release()
return
#At this point, this message claims to be from sendersHash and we are interested in it. We still have to hash the public key to make sure it is truly the key that matches the hash, and also check the signiture.
print'Time spent deciding that we are not interested in this broadcast:',time.time()-self.messageProcessingStartTime
printLock.release()
return
#At this point, this message claims to be from sendersHash and we are interested in it. We still have to hash the public key to make sure it is truly the key that matches the hash, and also check the signiture.
#Let's store the public key in case we want to reply to this person.
#We don't have the correct nonce or time (which would let us send out a pubkey message) so we'll just fill it with 1's. We won't be able to send this pubkey to others (without doing the proof of work ourselves, which this program is programmed to not do.)
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
sqlSubmitQueue.put(t)
sqlReturnQueue.get()
sqlSubmitQueue.put('commit')
sqlLock.release()
workerQueue.put(('newpubkey',(sendersAddressVersion,sendersStream,ripe.digest())))#This will check to see whether we happen to be awaiting this pubkey in order to send a message. If we are, it will do the POW and send it.
#Let's store the public key in case we want to reply to this person.
#We don't have the correct nonce or time (which would let us send out a pubkey message) so we'll just fill it with 1's. We won't be able to send this pubkey to others (without doing the proof of work ourselves, which this program is programmed to not do.)
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
sqlSubmitQueue.put(t)
sqlReturnQueue.get()
sqlSubmitQueue.put('commit')
sqlLock.release()
workerQueue.put(('newpubkey',(sendersAddressVersion,sendersStream,ripe.digest())))#This will check to see whether we happen to be awaiting this pubkey in order to send a message. If we are, it will do the POW and send it.
toRipe=key#This is the RIPE hash of the sender's pubkey. We need this below to compare to the RIPE hash of the sender's address to verify that it was encrypted by with their key rather than some other key.
initialDecryptionSuccessful=True
print'EC decryption successful using key associated with ripe hash:',key.encode('hex')
break
exceptException,err:
pass
#print 'cryptorObject.decrypt Exception:', err
ifnotinitialDecryptionSuccessful:
#This is not a message bound for me.
printLock.acquire()
print'Length of time program spent failing to decrypt this broadcast:',time.time()-self.messageProcessingStartTime,'seconds.'
printLock.release()
else:
body='Unknown encoding type.\n\n'+repr(message)
subject=''
#This is a broadcast I have decrypted and thus am interested in.
print'Cannot decode senderAddressVersion other than 2 or 3. Assuming the sender isn\' being silly, you should upgrade Bitmessage because this message shall be ignored.'
print'The stream number outside of the encryption on which the POW was completed doesn\'t match the stream number inside the encryption. Ignoring broadcast.'
workerQueue.put(('newpubkey',(sendersAddressVersion,sendersStream,ripe.digest())))#This will check to see whether we happen to be awaiting this pubkey in order to send a message. If we are, it will do the POW and send it.
#If we are behaving as an API then we might need to run an outside command to let some program know that a new message has arrived.
toRipe=key#This is the RIPE hash of my pubkeys. We need this below to compare to the destination_ripe included in the encrypted data.
initialDecryptionSuccessful=True
print'EC decryption successful using key associated with ripe hash:',key.encode('hex')
@ -806,13 +945,22 @@ class receiveDataThread(QThread):
printLock.release()
else:
#This is a message bound for me.
#If this message is bound for one of my version 3 addresses (or higher), then we must check to make sure it meets our demanded proof of work requirement.
toAddress=myAddressesByHash[toRipe]#Look up my address based on the RIPE hash.
ifdecodeAddress(toAddress)[1]>=3:#If the toAddress version number is 3 or higher:
@ -881,8 +1029,7 @@ class receiveDataThread(QThread):
ripe=hashlib.new('ripemd160')
ripe.update(sha.digest())
#Let's store the public key in case we want to reply to this person.
#We don't have the correct nonce or time (which would let us send out a pubkey message) so we'll just fill it with 1's. We won't be able to send this pubkey to others (without doing the proof of work ourselves, which this program is programmed to not do.)
@ -2629,6 +2801,76 @@ class singleWorker(QThread):
self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Broadcast sent on '+unicode(strftime(config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))),'utf-8'))
#Update the status of the message in the 'sent' table to have a 'broadcastsent' status
self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
pubSigningKey=highlevelcrypto.privToPub(privSigningKeyHex).decode('hex')#At this time these pubkeys are 65 bytes long because they include the encoding byte which we won't be sending in the broadcast message.
print'The string that we will hash to make the privEncryptionKey is',(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+ripe).encode('hex')
self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Broadcast sent on '+unicode(strftime(config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))),'utf-8'))
#Update the status of the message in the 'sent' table to have a 'broadcastsent' status
#Now, for all addresses, even version 2 addresses, we should create Cryptor objects in a dictionary which we will use to attempt to decrypt encrypted broadcast messages.
print'(Within reloadBroadcastSendersForWhichImWatching) The string that we will hash to make the privEncryptionKey is',(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+hash).encode('hex')
#In order for the time columns on the Inbox and Sent tabs to be sorted correctly (rather than alphabetically), we need to overload the < operator and use this class instead of QTableWidgetItem.
classmyTableWidgetItem(QTableWidgetItem):
@ -5339,6 +5564,7 @@ selfInitiatedConnections = {} #This is a list of current connections (the thread
alreadyAttemptedConnectionsList={}#This is a list of nodes to which we have already attempted a connection
sendDataQueues=[]#each sendData thread puts its queue in this list.
myECCryptorObjects={}
MyECSubscriptionCryptorObjects={}
myAddressesByHash={}#The key in this dictionary is the RIPE hash which is encoded in an address and value is the address itself.
inventory={}#of objects (like msg payloads and pubkey payloads) Does not include protocol headers (the first 24 bytes of each packet).
self.label_8.setText(QtGui.QApplication.translate("settingsDialog","When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exeption: if you add a friend or aquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. ",None,QtGui.QApplication.UnicodeUTF8))
self.label_8.setText(QtGui.QApplication.translate("settingsDialog","When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or aquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. ",None,QtGui.QApplication.UnicodeUTF8))
self.label_12.setText(QtGui.QApplication.translate("settingsDialog","The \'Small message difficulty\' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really affect large messages.",None,QtGui.QApplication.UnicodeUTF8))
<string>When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exeption: if you add a friend or aquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. </string>
<string>When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or aquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. </string>