#Notice that I have divided the averageProofOfWorkNonceTrialsPerByte 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.
#Notice that I have divided the networkDefaultAverageProofOfWorkNonceTrialsPerByte 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.
#Is it possible for a public key to be invalid such that trying to encrypt or sign with it will cause an error? If it is, we should probably test these keys here.
@ -1206,14 +1281,14 @@ class receiveDataThread(QThread):
#This getpubkey request is valid so far. Forward to peers.
self.broadcastinv(inventoryHash)
ifaddressVersionNumber ==0:
print'The addressVersionNumber of the pubkey request is zero. That doesn\'t make any sense. Ignoring it.'
ifrequestedAddressVersionNumber ==0:
print'The requestedAddressVersionNumber of the pubkey request is zero. That doesn\'t make any sense. Ignoring it.'
return
elifaddressVersionNumber ==1:
print'The addressVersionNumber of the pubkey request is 1 which isn\'t supported anymore. Ignoring it.'
elifrequestedAddressVersionNumber ==1:
print'The requestedAddressVersionNumber of the pubkey request is 1 which isn\'t supported anymore. Ignoring it.'
return
elifaddressVersionNumber >2:
print'The addressVersionNumber of the pubkey request is too high. Can\'t understand. Ignoring it.'
elifrequestedAddressVersionNumber >3:
print'The requestedAddressVersionNumber of the pubkey request is too high. Can\'t understand. Ignoring it.'
return
requestedHash=data[readPosition:readPosition+20]
@ -1240,16 +1315,27 @@ class receiveDataThread(QThread):
self.broadcastinv(inventoryHash)"""
#else: #the pubkey is not in our database of pubkeys. Let's check if the requested key is ours (which would mean we should do the POW, put it in the pubkey table, and broadcast out the pubkey.)
ifrequestedHashinmyAddressesByHash:#if this address hash is one of mine
sys.stderr.write('(Within the recgetpubkey function) Someone requested one of my pubkeys but the requestedAddressVersionNumber doesn\'t match my actual address version number. That shouldn\'t have happened. Ignoring.\n')
print'Found getpubkey-requested-hash in my list of EC hashes BUT we already sent it recently. Ignoring request. The lastPubkeySendTime is:',lastPubkeySendTime
printLock.release()
else:
printLock.acquire()
print'This getpubkey request is not for any of my keys.'
privEncryptionKey=decodeWalletImportFormat(config.get(addressInKeysFile,'privencryptionkey')).encode('hex')#returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error
iflen(privEncryptionKey)==64:#It is 32 bytes encoded as 64 hex characters
payload+=encodeVarint(networkDefaultAverageProofOfWorkNonceTrialsPerByte)#this is where we would multiply networkDefaultAverageProofOfWorkNonceTrialsPerByte by some difficulty set by the user.
payload+=encodeVarint(networkDefaultPayloadLengthExtraBytes)#this is where we would multiply networkDefaultPayloadLengthExtraBytes by some difficulty set by the user.
print'(For broadcast message) Doing proof of work...'
self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Doing work necessary to send broadcast...')
initialHash=hashlib.sha512(payload).digest()
@ -2525,44 +2686,47 @@ class singleWorker(QThread):
payload+=encodeVarint(len(signature))
payload+=signature
"""elif fromAddressVersionNumber == 1: #This code is for old version 1 (RSA) addresses. It will soon be removed.
payload='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'#this run of nulls allows the true message receiver to identify his message
payload+='\x01'#Message version.
payload+='\x00\x00\x00\x01'
iffromAddressVersionNumber==3:
payload='\x01'#Message version.
payload+=encodeVarint(fromAddressVersionNumber)
payload+=encodeVarint(fromStreamNumber)
payload+='\x00\x00\x00\x01'#Bitfield of features and behaviors that can be expected from me. (See https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features )
#We need to convert our private keys to public keys in order to include them.
print'Error: Could not find',fromaddress,'in our keys.dat file. You must have deleted it. Aborting the send.'
printLock.release()
return
payload+=encodeVarint(len(sendersN))
payload+=sendersN
self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
payload+=pubSigningKey[1:]#The \x04 on the beginning of the public keys are not sent. This way there is only one acceptable way to encode and send a public key.
payload+=pubEncryptionKey[1:]
payload+=encodeVarint(networkDefaultAverageProofOfWorkNonceTrialsPerByte)#this is where we would multiply networkDefaultAverageProofOfWorkNonceTrialsPerByte by some difficulty we demand others meet.
payload+=encodeVarint(networkDefaultPayloadLengthExtraBytes)#this is where we would multiply networkDefaultPayloadLengthExtraBytes by some difficulty set by some difficulty we demand others meet.
payload+='\x02'#Type 2 is simple UTF-8 message encoding.
payload+=toHash#This hash will be checked by the receiver of the message to verify that toHash belongs to them. This prevents a Surreptitious Forwarding Attack.
payload+='\x02'#Type 2 is simple UTF-8 message encoding as specified on the Protocol Specification on the Bitmessage Wiki.
#Later, if anyone impliments clients that don't send the ack_data, then we should probably check here to make sure that the receiver will make use of this ack_data and not attach it if not.
fullAckPayload=self.generateFullAckMessage(ackdata,toStreamNumber,embeddedTime)#The fullAckPayload is a normal msg protocol message with the proof of work already completed that the receiver of this message can easily send out.
ifrequiredAverageProofOfWorkNonceTrialsPerByte<networkDefaultAverageProofOfWorkNonceTrialsPerByte:#We still have to meet a minimum POW difficulty regardless of what they say is allowed in order to get our message to propagate through the network.
#We are now dropping the unencrypted data in payload since it has already been encrypted and replacing it with the encrypted payload that we will send out.
@ -2707,7 +2883,7 @@ class addressGenerator(QThread):
self.eighteenByteRipe=eighteenByteRipe
defrun(self):
ifself.addressVersionNumber==2:
ifself.addressVersionNumber==3:
ifself.deterministicPassphrase=="":
statusbar='Generating one new address'
@ -2738,7 +2914,7 @@ class addressGenerator(QThread):
break
print'Generated address with ripe digest:',ripe.digest().encode('hex')
print'Address generator calculated',numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix,'addresses at',numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix/(time.time()-startTime),'addresses per second before finding one with the correct ripe-prefix.'
QMessageBox.about(self,"Address version number","Concerning the address "+toAddress+", Bitmessage cannot understand address version numbers of "+str(addressVersionNumber)+". Perhaps upgrade Bitmessage to the latest version.")
continue
ifstreamNumber>1orstreamNumber==0:
@ -4638,7 +4814,7 @@ class MyForm(QtGui.QMainWindow):
alreadyAttemptedConnectionsListResetTime=int(time.time())#used to clear out the alreadyAttemptedConnectionsList periodically so that we will retry connecting to hosts to which we have already tried to connect.
#These constants are not at the top because if changed they will cause particularly unexpected behavior: You won't be able to either send or receive messages because the proof of work you do (or demand) won't match that done or demanded by others. Don't change them!
averageProofOfWorkNonceTrialsPerByte =320#The amount of work that should be performed (and demanded) per byte of the payload. Double this number to double the work.
payloadLengthExtraBytes =14000#To make sending short messages a little more difficult, this value is added to the payload length for use in calculating the proof of work target.
networkDefaultAverageProofOfWorkNonceTrialsPerByte =320#The amount of work that should be performed (and demanded) per byte of the payload. Double this number to double the work.
networkDefaultPayloadLengthExtraBytes =14000#To make sending short messages a little more difficult, this value is added to the payload length for use in calculating the proof of work target.