#Right now, PyBitmessage only support connecting to stream 1. It doesn't yet contain logic to expand into further streams.
softwareVersion='0.2.2'
softwareVersion='0.2.3'
verbose=2
maximumAgeOfAnObjectThatIAmWillingToAccept=216000#Equals two days and 12 hours.
lengthOfTimeToLeaveObjectsInInventory=237600#Equals two days and 18 hours. This should be longer than maximumAgeOfAnObjectThatIAmWillingToAccept so that we don't process messages twice.
lengthOfTimeToHoldOnToAllPubkeys=2419200#Equals 4 weeks. You could make this longer if you want but making it shorter would not be advisable because there is a very small possibility that it could keep you from obtaining a needed pubkey for a period of time.
maximumAgeOfObjectsThatIAdvertiseToOthers=216000#Equals two days and 12 hours
maximumAgeOfNodesThatIAdvertiseToOthers=10800#Equals three hours
storeConfigFilesInSameDirectoryAsProgram=False
@ -863,9 +864,9 @@ class receiveDataThread(QThread):
#Let's store the public key in case we want to reply to this person.
#We don't have the correct nonce in order to 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.)
t=(ripe.digest(),False,'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'+data[20+messageVersionLength:endOfThePublicKeyPosition],int(time.time())+2419200)#after one month we may remove this pub key from our database. (2419200 = a month)
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''')
sqlSubmitQueue.put(t)
sqlReturnQueue.get()
sqlLock.release()
@ -1085,9 +1086,9 @@ class receiveDataThread(QThread):
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.)
t=(ripe.digest(),False,'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'+'\xFF\xFF\xFF\xFF'+data[messageVersionLength:endOfThePublicKeyPosition],int(time.time())+2419200)#after one month we may remove this pub key from our database. (2419200 = a month)
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''')
sqlSubmitQueue.put(t)
sqlReturnQueue.get()
sqlLock.release()
@ -1192,6 +1193,7 @@ class receiveDataThread(QThread):
#We have received a pubkey
defrecpubkey(self):
self.pubkeyProcessingStartTime=time.time()
ifself.payloadLength<32:#sanity check
return
#We must check to make sure the proof of work is sufficient.
@ -1199,9 +1201,20 @@ class receiveDataThread(QThread):
print'Proof of work in pubkey message insufficient.'
return
readPosition=24#for the message header
readPosition+=8#for the nonce
embeddedTime,=unpack('>I',self.data[readPosition:readPosition+4])#We currently are not checking the embeddedTime for any sort of validity in pubkey messages.
ifembeddedTime<int(time.time())-lengthOfTimeToHoldOnToAllPubkeys-86400:#If the pubkey is more than a month old then reject it. (the 86400 is included to give an extra day of wiggle-room. If the wiggle-room is actually of any use, everyone on the network will delete this pubkey from their database the next time the cleanerThread cleans anyway- except for the node that actually wants the pubkey.)
printLock.acquire()
print'The embedded time in this pubkey message is too old. Ignoring.'
printLock.release()
return
ifembeddedTime>int(time.time())+10800:
printLock.acquire()
print'The embedded time in this pubkey message more than several hours in the future. This is irrational. Ignoring message.'
#embeddedTime, = unpack('>I',self.data[readPosition:readPosition+4]) #We don't need the time in this processpubkey function. It was checked earlier in the recpubkey function.
@ -1349,38 +1426,31 @@ class receiveDataThread(QThread):
print'the hash requested in this getpubkey request is:',self.data[36+addressVersionLength+streamNumberLength:56+addressVersionLength+streamNumberLength].encode('hex')
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.
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.)
ifself.data[36+addressVersionLength+streamNumberLength:56+addressVersionLength+streamNumberLength]inmyECAddressHashes:#if this address hash is one of mine
printLock.acquire()
print'Found getpubkey-requested-hash in my list of EC hashes. Telling Worker thread to do the POW for a pubkey message and send it out.'
@ -1405,6 +1475,7 @@ class receiveDataThread(QThread):
payload=pack('>Q',nonce)+payload
t=(self.data[36+addressVersionLength+streamNumberLength:56+addressVersionLength+streamNumberLength],True,payload,int(time.time())+1209600)#after two weeks (1,209,600 seconds), we may remove our own pub key from our database. It will be regenerated and put back in the database if it is requested.
sqlLock.acquire()
#** pubkeys insert query not yet fixed! **
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
sqlSubmitQueue.put(t)
queryreturn=sqlReturnQueue.get()
@ -1412,7 +1483,7 @@ class receiveDataThread(QThread):
self.cur.execute('''CREATE TABLE pubkeys (hash blob, havecorrectnonce bool, transmitdata blob, time blob, UNIQUE(hash, havecorrectnonce, transmitdata) ON CONFLICT REPLACE)''')
#Explanation of what is in the pubkeys table:
# The hash is the RIPEMD160 hash that is encoded in the Bitmessage address.
# If you or someone else did the POW for this pubkey, then havecorrectnonce will be true. If you received the pubkey in a msg message then havecorrectnonce will be false. You won't have the correct nonce and won't be able to send the message to peers if they request the pubkey.
# transmitdata is literally the data that was included in the Bitmessage pubkey message when it arrived, except for the 24 byte protocol header- ie, it starts with the POW nonce.
# time is the time that the pubkey was broadcast on the network same as with every other type of Bitmessage object.
# usedpersonally is set to "yes" if we have used the key personally. This keeps us from deleting it because we may want to reply to a message in the future. This field is not a bool because we may need more flexability in the future and it doesn't take up much more space anyway.
self.cur.execute('''CREATE TABLE pubkeys (hash blob, havecorrectnonce bool, transmitdata blob, time blob, usedpersonally text, UNIQUE(hash, havecorrectnonce, transmitdata) ON CONFLICT REPLACE)''')
self.cur.execute('''CREATE TABLE knownnodes (timelastseen int, stream int, services blob, host blob, port blob, UNIQUE(host, stream, port) ON CONFLICT REPLACE)''')#This table isn't used in the program yet but I have a feeling that we'll need it.
@ -2088,11 +2167,21 @@ class sqlThread(QThread):
else:
sys.stderr.write('ERROR trying to create database file (message.dat). Error message: %s\n'%str(err))
@ -2162,9 +2251,9 @@ class singleCleaner(QThread):
sqlSubmitQueue.put(t)
sqlReturnQueue.get()
#pubkeys (clears data older than the date specified in the table. This is because we won't want to hold pubkeys that show up randomly as long as those that we have actually have used (unless someone can come up with a decent attack based on this behavior.))
t=(int(time.time()),)
sqlSubmitQueue.put('''DELETE FROM pubkeys WHERE time<?''')
payload=pack('>I',(int(time.time())+random.randrange(-300,300)))#the current time plus or minus five minutes
embeddedTime=int(time.time())+random.randrange(-300,300)#the current time plus or minus five minutes
payload=pack('>I',(embeddedTime))
payload+=encodeVarint(2)#Address version number
payload+=encodeVarint(streamNumber)
payload+='\x00\x00\x00\x01'#bitfield of features supported by me (see the wiki).
@ -2302,16 +2392,16 @@ class singleWorker(QThread):
print'(For pubkey message) Found proof of work',trialValue,'Nonce:',nonce
payload=pack('>Q',nonce)+payload
t=(hash,True,payload,int(time.time())+1209600)#after two weeks (1,209,600 seconds), we may remove our own pub key from our database. It will be regenerated and put back in the database if it is requested.
t=(hash,True,payload,embeddedTime,'no')
sqlLock.acquire()
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''')
print'broadcasting inv with hash:',inventoryHash.encode('hex')
@ -2341,7 +2431,7 @@ class singleWorker(QThread):
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.
payload=pack('>I',(int(time.time())+random.randrange(-300,300)))#the current time plus or minus five minutes
payload+=encodeVarint(1)#broadcast version
payload+=encodeVarint(addressVersionNumber)
payload+=encodeVarint(streamNumber)
@ -2473,7 +2563,7 @@ class singleWorker(QThread):
print'Found a message in our database that needs to be sent with this pubkey.'
print'First 150 characters of message:',message[:150]
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.
fullAckPayload=self.generateFullAckMessage(ackdata,toStreamNumber)#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.
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.
#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.
#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.
readPosition=8#to bypass the nonce
@ -2568,13 +2658,13 @@ class singleWorker(QThread):
eliftoAddressVersionNumber==1:
sqlLock.acquire()
sqlSubmitQueue.put('SELECT * FROM pubkeys WHERE hash=?')
sqlSubmitQueue.put('SELECT transmitdata FROM pubkeys WHERE hash=?')
#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.
#Update the time in the pubkey sql database so that we'll hold the foreign pubkey for quite a while longer
t=(int(time.time())+31449600,toRipe)#Hold the pubkey for an entire year from today
sqlSubmitQueue.put('UPDATE pubkeys SET time=? WHERE hash=?')
t=(toRipe,)
sqlSubmitQueue.put('''UPDATE pubkeys SET usedpersonally='yes' WHERE hash=?''')
sqlSubmitQueue.put(t)
queryreturn=sqlReturnQueue.get()
@ -2676,10 +2766,9 @@ class singleWorker(QThread):
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Broacasting the public key request. The recipient''s software must be on. This program will auto-retry if they are offline.')
self.emit(SIGNAL("updateSentItemStatusByHash(PyQt_PyObject,PyQt_PyObject)"),ripe,'Sending public key request. Waiting for reply. Requested at '+strftime(config.get('bitmessagesettings','timeformat'),localtime(int(time.time()))))
config.set('bitmessagesettings','settingsversion','3')#If the settings version is equal to 2 then the sqlThread will modify the pubkeys table and change the settings version to 3.
#This program can be used to print out everything in your Inbox or Sent folders and also take things out of the trash.
#Scroll down to the bottom to see the functions that you can uncomment. Save then run this file.
#The functions only read the database file seem to function just fine even if you have Bitmessage running but you should definitly close it before running the functions to take items out of the trash.
print'Hash:',hash.encode('hex'),'\tHave correct nonce:',havecorrectnonce,'\tTime first broadcast:',strftime('%a, %d%b %Y %I:%M %p',localtime(time)),'\tUsed by me personally:',usedpersonally,'\tFull pubkey message:',transmitdata.encode('hex')
deftakeInboxMessagesOutOfTrash():
item='''update inbox set folder='inbox' where folder='trash''''
parameters=''
cur.execute(item,parameters)
output=cur.fetchall()
conn.commit()
print'done'
deftakeSentMessagesOutOfTrash():
item='''update sent set folder='sent' where folder='trash''''