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))
else:
ifverbose>=1:
shared.printLock.acquire()
@ -178,7 +174,7 @@ class outgoingSynSender(threading.Thread):
shared.printLock.release()
exceptException,err:
sys.stderr.write('An exception has occurred in the outgoingSynSender thread that was not caught by other exception types: %s\n'%err)
time.sleep(0.1)
time.sleep(0.1)
#Only one singleListener thread will ever exist. It creates the receiveDataThread and sendDataThread for each incoming connection. Note that it cannot set the stream number because it is not known yet- the other node will have to tell us its stream number in a version message. If we don't care about their stream, we will close the connection (within the recversion function of the recieveData thread)
classsingleListener(threading.Thread):
@ -449,7 +445,6 @@ class receiveDataThread(threading.Thread):
self.sock.settimeout(600)#We'll send out a pong every 5 minutes to make sure the connection stays alive if there has been no other traffic to send lately.
print'a sendData thread is not sending an addr message to this particular peer ('+self.HOST+') because their protocol version is 1.'
shared.printLock.release()
else:
try:
#To prevent some network analysis, 'leak' the data out to our peer after waiting a random amount of time unless we have a long list of messages in our queue to send.
random.seed()
time.sleep(random.randrange(0,10))
self.sock.sendall(data)
self.lastTimeISentData=int(time.time())
except:
print'self.sock.sendall failed'
try:
#To prevent some network analysis, 'leak' the data out to our peer after waiting a random amount of time unless we have a long list of messages in our queue to send.
random.seed()
time.sleep(random.randrange(0,10))
self.sock.sendall(data)
self.lastTimeISentData=int(time.time())
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
except:
print'self.sock.sendall failed'
try:
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
except:
pass
shared.sendDataQueues.remove(self.mailbox)
print'sendDataThread thread (ID:',str(id(self))+') ending now. Was connected to',self.HOST
break
pass
shared.sendDataQueues.remove(self.mailbox)
print'sendDataThread thread (ID:',str(id(self))+') ending now. Was connected to',self.HOST
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue
@ -2840,7 +2819,7 @@ class singleWorker(threading.Thread):
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.
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Broadcast sent on '+unicode(strftime(shared.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
@ -2889,7 +2866,6 @@ class singleWorker(threading.Thread):
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue
@ -2899,7 +2875,7 @@ class singleWorker(threading.Thread):
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.
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Broadcast sent on '+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Broadcast sent on '+unicode(strftime(shared.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
@ -3000,12 +2974,12 @@ class singleWorker(threading.Thread):
shared.UISignalQueue.put(('updateSentItemStatusByHash',(toripe,'Sending a request for the recipient\'s encryption key.')))
self.requestPubKey(toaddress)
shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('''SELECT toaddress, toripe, fromaddress, subject, message, ackdata FROM sent WHERE status='doingmsgpow' and folder='sent'''')
shared.sqlSubmitQueue.put('')
shared.sqlSubmitQueue.put('''SELECT toaddress, toripe, fromaddress, subject, message, ackdata, status FROM sent WHERE (status='doingmsgpow' or status='forcepow' or (status='toodifficult' and lastactiontime>?)) and folder='sent'''')
#Evidently there is a remote possibility that we may no longer have the recipient's pubkey. Let us make sure we still have it or else the sendMsg function will appear to freeze.
shared.sqlLock.acquire()
@ -3036,7 +3010,72 @@ class singleWorker(threading.Thread):
print'Found a message in our database that needs to be sent with this pubkey.'
print'First 150 characters of message:',repr(message[:150])
shared.printLock.release()
embeddedTime=pack('>I',(int(time.time())+random.randrange(-300,300)))#the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message.
#Now let us fetch the recipient's public key out of our database. If the required proof of work difficulty is too hard then we'll abort.
shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('SELECT transmitdata FROM pubkeys WHERE hash=?')
shared.sqlSubmitQueue.put((toripe,))
queryreturn=shared.sqlReturnQueue.get()
#also mark the pubkey as 'usedpersonally' so that we don't delete it.
t=(toripe,)
shared.sqlSubmitQueue.put('''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=?''')
shared.sqlSubmitQueue.put(t)
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release()
ifqueryreturn==[]:
shared.printLock.acquire()
sys.stderr.write('(within sendMsg) The needed pubkey was not found. This should never happen. Aborting send.\n')
shared.printLock.release()
return
forrowinqueryreturn:
pubkeyPayload,=row
#The pubkey is stored the way we originally received it which means that we need to read beyond things like the nonce and time to get to the public keys.
ifrequiredAverageProofOfWorkNonceTrialsPerByte<shared.networkDefaultProofOfWorkNonceTrialsPerByte:#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.
#The demanded difficulty is more than we are willing to do.
shared.sqlLock.acquire()
t=(ackdata,)
shared.sqlSubmitQueue.put('''UPDATE sent SET status='toodifficult' WHERE ackdata=? AND status='doingmsgpow'''')
shared.sqlSubmitQueue.put(t)
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release()
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Problem: The work demanded by the recipient ('+str(float(requiredAverageProofOfWorkNonceTrialsPerByte)/shared.networkDefaultProofOfWorkNonceTrialsPerByte)+' and '+str(float(requiredPayloadLengthExtraBytes)/shared.networkDefaultPayloadLengthExtraBytes)+') is more difficult than you are willing to do. '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))),'utf-8'))))
continue
embeddedTime=pack('>Q',(int(time.time())+random.randrange(-300,300)))#the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message.
iffromAddressVersionNumber==2:
payload='\x01'#Message version.
payload+=encodeVarint(fromAddressVersionNumber)
@ -3048,7 +3087,6 @@ class singleWorker(threading.Thread):
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue
@ -3084,7 +3122,6 @@ class singleWorker(threading.Thread):
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Error! Could not find sender address (your address) in the keys.dat file.')))
continue
@ -3116,71 +3153,9 @@ class singleWorker(threading.Thread):
payload+=encodeVarint(len(signature))
payload+=signature
#We have assembled the data that will be encrypted. Now let us fetch the recipient's public key out of our database and do the encryption.
shared.sqlSubmitQueue.put('SELECT transmitdata FROM pubkeys WHERE hash=?')
shared.sqlSubmitQueue.put((toripe,))
queryreturn=shared.sqlReturnQueue.get()
shared.sqlLock.release()
ifqueryreturn==[]:
shared.printLock.acquire()
sys.stderr.write('(within sendMsg) The needed pubkey was not found. This should never happen. Aborting send.\n')
shared.printLock.release()
return
forrowinqueryreturn:
pubkeyPayload,=row
#The pubkey is stored the way we originally received it which means that we need to read beyond things like the nonce and time to get to the public keys.
ifrequiredAverageProofOfWorkNonceTrialsPerByte<shared.networkDefaultProofOfWorkNonceTrialsPerByte:#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.
#The demanded difficulty is more than we are willing to do.
shared.sqlLock.acquire()
t=(ackdata,)
shared.sqlSubmitQueue.put('''UPDATE sent SET status='toodifficult' WHERE ackdata=? AND status='doingmsgpow'''')
shared.sqlSubmitQueue.put(t)
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release()
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Problem: The work demanded by the recipient ('+str(requiredAverageProofOfWorkNonceTrialsPerByte/shared.networkDefaultProofOfWorkNonceTrialsPerByte)+' and '+str(requiredPayloadLengthExtraBytes/shared.networkDefaultPayloadLengthExtraBytes)+') is more difficult than you are willing to do. '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))),'utf-8'))))
#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.
#We have assembled the data that will be encrypted.
#self.emit(SIGNAL("updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"),ackdata,'Message sent. Waiting on acknowledgement. Sent on ' + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,'Message sent. Waiting on acknowledgement. Sent on '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))),'utf-8'))))
print'Broadcasting inv for my msg(within sendmsg function):',inventoryHash.encode('hex')
shared.sqlSubmitQueue.put('UPDATE sent SET status=? WHERE toaddress=? AND fromaddress=? AND subject=? AND message=? AND status=?')
shared.sqlSubmitQueue.put(t)
queryreturn=shared.sqlReturnQueue.get()
t=(toripe,)
shared.sqlSubmitQueue.put('''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=?''')
t=(toaddress,fromaddress,subject,message)
shared.sqlSubmitQueue.put('''UPDATE sent SET status='msgsent' WHERE toaddress=? AND fromaddress=? AND subject=? AND message=? AND status='doingmsgpow' or status='forcepow'''')
shared.sqlSubmitQueue.put(t)
queryreturn=shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
@ -3227,7 +3196,7 @@ class singleWorker(threading.Thread):
shared.printLock.release()
return
neededPubkeys[ripe]=0
payload=pack('>I',(int(time.time())+random.randrange(-300,300)))#the current time plus or minus five minutes.
payload=pack('>Q',(int(time.time())+random.randrange(-300,300)))#the current time plus or minus five minutes.
payload+=encodeVarint(addressVersionNumber)
payload+=encodeVarint(streamNumber)
payload+=ripe
@ -3238,7 +3207,6 @@ class singleWorker(threading.Thread):
statusbar='Doing the computations necessary to request the recipient\'s public key.'
shared.reloadMyAddressHashes()#This is necessary here (rather than just at the end) because otherwise if the human generates a large number of new addresses and uses one before they are done generating, the program will receive a getpubkey message and will ignore it.
#if eighteenByteRipe:
# shared.reloadMyAddressHashes()#This is necessary here (rather than just at the end) because otherwise if the human generates a large number of new addresses and uses one before they are done generating, the program will receive a getpubkey message and will ignore it.
shared.sqlSubmitQueue.put('''SELECT msgid, toaddress, fromaddress, subject, received, message, read FROM inbox where folder='inbox' ORDER BY received''')
shared.sqlSubmitQueue.put('')
@ -231,7 +231,8 @@ class MyForm(QtGui.QMainWindow):
shared.sqlSubmitQueue.put('''SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime FROM sent where folder = 'sent' ORDER BY lastactiontime''')
@ -309,6 +315,8 @@ class MyForm(QtGui.QMainWindow):
newItem =myTableWidgetItem('Message sent. Waiting on acknowledgement. Sent at '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(lastactiontime)),'utf-8'))
statusText ='Message sent. Waiting on acknowledgement. Sent at '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(lastactiontime)),'utf-8')
elifstatus=='doingmsgpow':
newItem =myTableWidgetItem('Need to do work to send message. Work is queued.')
statusText ='Need to do work to send message. Work is queued.'
elifstatus=='ackreceived':
newItem =myTableWidgetItem('Acknowledgement of the message received '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(lastactiontime))),'utf-8'))
statusText ='Acknowledgement of the message received '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(lastactiontime))),'utf-8')
elifstatus=='broadcastqueued':
newItem =myTableWidgetItem('Broadcast queued.')
statusText ='Broadcast queued.'
elifstatus=='broadcastsent':
newItem =myTableWidgetItem('Broadcast on '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(lastactiontime))),'utf-8'))
statusText ='Broadcast on '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(lastactiontime))),'utf-8')
elifstatus=='toodifficult':
newItem=myTableWidgetItem('Problem: The work demanded by the recipient is more difficult than you are willing to do. '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(lastactiontime))),'utf-8'))
statusText='Problem: The work demanded by the recipient is more difficult than you are willing to do. '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(lastactiontime))),'utf-8')
elifstatus=='forcepow':
statusText='Forced difficulty override. Send should start soon.'
@ -766,19 +784,8 @@ class MyForm(QtGui.QMainWindow):
defclick_actionDeleteAllTrashedMessages(self):
ifQtGui.QMessageBox.question(self,'Delete trash?',"Are you sure you want to delete all trashed messages?",QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)==QtGui.QMessageBox.No:
return
self.statusBar().showMessage('Deleting messages and freeing empty space...')
shared.sqlLock.acquire()
shared.sqlSubmitQueue.put('''delete from inbox where folder='trash'''')
shared.sqlSubmitQueue.put('')
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('''delete from sent where folder='trash'''')
shared.sqlSubmitQueue.put('')
shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')#Commit takes no parameters and returns nothing
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:
@ -1210,6 +1218,8 @@ class MyForm(QtGui.QMainWindow):
#This function is called by the processmsg function when that function receives a message to an address that is acting as a pseudo-mailing-list. The message will be broadcast out. This function puts the message on the 'Sent' tab.
#newItem = QtGui.QTableWidgetItem('Doing work necessary to send broadcast...'+ unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8'))
newItem=myTableWidgetItem('Work is queued. '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))),'utf-8'))
newItem.setToolTip('Work is queued. '+unicode(strftime(shared.config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))),'utf-8'))
newItem.setData(Qt.UserRole,QByteArray(ackdata))
newItem.setData(33,int(time.time()))
self.ui.tableWidgetSent.setItem(0,3,newItem)
@ -1243,6 +1259,8 @@ class MyForm(QtGui.QMainWindow):
@ -222,4 +265,8 @@ class Ui_settingsDialog(object):
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))
self.label_10.setText(QtGui.QApplication.translate("settingsDialog","The \'Total difficulty\' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work.",None,QtGui.QApplication.UnicodeUTF8))
self.label_15.setText(QtGui.QApplication.translate("settingsDialog","Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.",None,QtGui.QApplication.UnicodeUTF8))
self.label_13.setText(QtGui.QApplication.translate("settingsDialog","Maximum acceptable total difficulty:",None,QtGui.QApplication.UnicodeUTF8))
self.label_14.setText(QtGui.QApplication.translate("settingsDialog","Maximum acceptable small message difficulty:",None,QtGui.QApplication.UnicodeUTF8))