Seperated out class_singleWorker (POW thread)
parent
d2d2d8c380
commit
c7d9b316ef
@ -0,0 +1,858 @@
|
||||
import threading
|
||||
import shared
|
||||
import time
|
||||
from time import strftime, localtime, gmtime
|
||||
import random
|
||||
from addresses import *
|
||||
import bitmessagemain
|
||||
import highlevelcrypto
|
||||
import proofofwork
|
||||
|
||||
# This thread, of which there is only one, does the heavy lifting:
|
||||
# calculating POWs.
|
||||
|
||||
|
||||
class singleWorker(threading.Thread):
|
||||
|
||||
def __init__(self):
|
||||
# QThread.__init__(self, parent)
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''SELECT toripe FROM sent WHERE ((status='awaitingpubkey' OR status='doingpubkeypow') AND folder='sent')''')
|
||||
shared.sqlSubmitQueue.put('')
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
for row in queryreturn:
|
||||
toripe, = row
|
||||
neededPubkeys[toripe] = 0
|
||||
|
||||
# Initialize the bitmessagemain.ackdataForWhichImWatching data structure using data
|
||||
# from the sql database.
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''SELECT ackdata FROM sent where (status='msgsent' OR status='doingmsgpow')''')
|
||||
shared.sqlSubmitQueue.put('')
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
for row in queryreturn:
|
||||
ackdata, = row
|
||||
print 'Watching for ackdata', ackdata.encode('hex')
|
||||
bitmessagemain.ackdataForWhichImWatching[ackdata] = 0
|
||||
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''SELECT DISTINCT toaddress FROM sent WHERE (status='doingpubkeypow' AND folder='sent')''')
|
||||
shared.sqlSubmitQueue.put('')
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
for row in queryreturn:
|
||||
toaddress, = row
|
||||
self.requestPubKey(toaddress)
|
||||
|
||||
time.sleep(
|
||||
10) # give some time for the GUI to start before we start on existing POW tasks.
|
||||
|
||||
self.sendMsg()
|
||||
# just in case there are any pending tasks for msg
|
||||
# messages that have yet to be sent.
|
||||
self.sendBroadcast()
|
||||
# just in case there are any tasks for Broadcasts
|
||||
# that have yet to be sent.
|
||||
|
||||
while True:
|
||||
command, data = shared.workerQueue.get()
|
||||
if command == 'sendmessage':
|
||||
self.sendMsg()
|
||||
elif command == 'sendbroadcast':
|
||||
self.sendBroadcast()
|
||||
elif command == 'doPOWForMyV2Pubkey':
|
||||
self.doPOWForMyV2Pubkey(data)
|
||||
elif command == 'doPOWForMyV3Pubkey':
|
||||
self.doPOWForMyV3Pubkey(data)
|
||||
"""elif command == 'newpubkey':
|
||||
toAddressVersion,toStreamNumber,toRipe = data
|
||||
if toRipe in neededPubkeys:
|
||||
print 'We have been awaiting the arrival of this pubkey.'
|
||||
del neededPubkeys[toRipe]
|
||||
t = (toRipe,)
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put('''UPDATE sent SET status='doingmsgpow' WHERE toripe=? AND status='awaitingpubkey' and folder='sent' ''')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()
|
||||
self.sendMsg()
|
||||
else:
|
||||
shared.printLock.acquire()
|
||||
print 'We don\'t need this pub key. We didn\'t ask for it. Pubkey hash:', toRipe.encode('hex')
|
||||
shared.printLock.release()"""
|
||||
else:
|
||||
shared.printLock.acquire()
|
||||
sys.stderr.write(
|
||||
'Probable programming error: The command sent to the workerThread is weird. It is: %s\n' % command)
|
||||
shared.printLock.release()
|
||||
shared.workerQueue.task_done()
|
||||
|
||||
def doPOWForMyV2Pubkey(self, hash): # This function also broadcasts out the pubkey message once it is done with the POW
|
||||
# Look up my stream number based on my address hash
|
||||
"""configSections = shared.config.sections()
|
||||
for addressInKeysFile in configSections:
|
||||
if addressInKeysFile <> 'bitmessagesettings':
|
||||
status,addressVersionNumber,streamNumber,hashFromThisParticularAddress = decodeAddress(addressInKeysFile)
|
||||
if hash == hashFromThisParticularAddress:
|
||||
myAddress = addressInKeysFile
|
||||
break"""
|
||||
myAddress = shared.myAddressesByHash[hash]
|
||||
status, addressVersionNumber, streamNumber, hash = decodeAddress(
|
||||
myAddress)
|
||||
embeddedTime = int(time.time() + random.randrange(
|
||||
-300, 300)) # the current time plus or minus five minutes
|
||||
payload = pack('>I', (embeddedTime))
|
||||
payload += encodeVarint(addressVersionNumber) # Address version number
|
||||
payload += encodeVarint(streamNumber)
|
||||
payload += '\x00\x00\x00\x01' # bitfield of features supported by me (see the wiki).
|
||||
|
||||
try:
|
||||
privSigningKeyBase58 = shared.config.get(
|
||||
myAddress, 'privsigningkey')
|
||||
privEncryptionKeyBase58 = shared.config.get(
|
||||
myAddress, 'privencryptionkey')
|
||||
except Exception as err:
|
||||
shared.printLock.acquire()
|
||||
sys.stderr.write(
|
||||
'Error within doPOWForMyV2Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err)
|
||||
shared.printLock.release()
|
||||
return
|
||||
|
||||
privSigningKeyHex = shared.decodeWalletImportFormat(
|
||||
privSigningKeyBase58).encode('hex')
|
||||
privEncryptionKeyHex = shared.decodeWalletImportFormat(
|
||||
privEncryptionKeyBase58).encode('hex')
|
||||
pubSigningKey = highlevelcrypto.privToPub(
|
||||
privSigningKeyHex).decode('hex')
|
||||
pubEncryptionKey = highlevelcrypto.privToPub(
|
||||
privEncryptionKeyHex).decode('hex')
|
||||
|
||||
payload += pubSigningKey[1:]
|
||||
payload += pubEncryptionKey[1:]
|
||||
|
||||
# Do the POW for this pubkey message
|
||||
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
|
||||
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||
print '(For pubkey message) Doing proof of work...'
|
||||
initialHash = hashlib.sha512(payload).digest()
|
||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
||||
payload = pack('>Q', nonce) + payload
|
||||
"""t = (hash,payload,embeddedTime,'no')
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()"""
|
||||
|
||||
inventoryHash = calculateInventoryHash(payload)
|
||||
objectType = 'pubkey'
|
||||
shared.inventory[inventoryHash] = (
|
||||
objectType, streamNumber, payload, embeddedTime)
|
||||
|
||||
shared.printLock.acquire()
|
||||
print 'broadcasting inv with hash:', inventoryHash.encode('hex')
|
||||
shared.printLock.release()
|
||||
shared.broadcastToSendDataQueues((
|
||||
streamNumber, 'sendinv', inventoryHash))
|
||||
shared.UISignalQueue.put(('updateStatusBar', ''))
|
||||
shared.config.set(
|
||||
myAddress, 'lastpubkeysendtime', str(int(time.time())))
|
||||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||
shared.config.write(configfile)
|
||||
|
||||
def doPOWForMyV3Pubkey(self, hash): # This function also broadcasts out the pubkey message once it is done with the POW
|
||||
myAddress = shared.myAddressesByHash[hash]
|
||||
status, addressVersionNumber, streamNumber, hash = decodeAddress(
|
||||
myAddress)
|
||||
embeddedTime = int(time.time() + random.randrange(
|
||||
-300, 300)) # the current time plus or minus five minutes
|
||||
payload = pack('>I', (embeddedTime))
|
||||
payload += encodeVarint(addressVersionNumber) # Address version number
|
||||
payload += encodeVarint(streamNumber)
|
||||
payload += '\x00\x00\x00\x01' # bitfield of features supported by me (see the wiki).
|
||||
|
||||
try:
|
||||
privSigningKeyBase58 = shared.config.get(
|
||||
myAddress, 'privsigningkey')
|
||||
privEncryptionKeyBase58 = shared.config.get(
|
||||
myAddress, 'privencryptionkey')
|
||||
except Exception as err:
|
||||
shared.printLock.acquire()
|
||||
sys.stderr.write(
|
||||
'Error within doPOWForMyV3Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err)
|
||||
shared.printLock.release()
|
||||
return
|
||||
|
||||
privSigningKeyHex = shared.decodeWalletImportFormat(
|
||||
privSigningKeyBase58).encode('hex')
|
||||
privEncryptionKeyHex = shared.decodeWalletImportFormat(
|
||||
privEncryptionKeyBase58).encode('hex')
|
||||
pubSigningKey = highlevelcrypto.privToPub(
|
||||
privSigningKeyHex).decode('hex')
|
||||
pubEncryptionKey = highlevelcrypto.privToPub(
|
||||
privEncryptionKeyHex).decode('hex')
|
||||
|
||||
payload += pubSigningKey[1:]
|
||||
payload += pubEncryptionKey[1:]
|
||||
|
||||
payload += encodeVarint(shared.config.getint(
|
||||
myAddress, 'noncetrialsperbyte'))
|
||||
payload += encodeVarint(shared.config.getint(
|
||||
myAddress, 'payloadlengthextrabytes'))
|
||||
signature = highlevelcrypto.sign(payload, privSigningKeyHex)
|
||||
payload += encodeVarint(len(signature))
|
||||
payload += signature
|
||||
|
||||
# Do the POW for this pubkey message
|
||||
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
|
||||
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||
print '(For pubkey message) Doing proof of work...'
|
||||
initialHash = hashlib.sha512(payload).digest()
|
||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
||||
|
||||
payload = pack('>Q', nonce) + payload
|
||||
"""t = (hash,payload,embeddedTime,'no')
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()"""
|
||||
|
||||
inventoryHash = calculateInventoryHash(payload)
|
||||
objectType = 'pubkey'
|
||||
shared.inventory[inventoryHash] = (
|
||||
objectType, streamNumber, payload, embeddedTime)
|
||||
|
||||
shared.printLock.acquire()
|
||||
print 'broadcasting inv with hash:', inventoryHash.encode('hex')
|
||||
shared.printLock.release()
|
||||
shared.broadcastToSendDataQueues((
|
||||
streamNumber, 'sendinv', inventoryHash))
|
||||
shared.UISignalQueue.put(('updateStatusBar', ''))
|
||||
shared.config.set(
|
||||
myAddress, 'lastpubkeysendtime', str(int(time.time())))
|
||||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||
shared.config.write(configfile)
|
||||
|
||||
def sendBroadcast(self):
|
||||
shared.sqlLock.acquire()
|
||||
t = ('broadcastqueued',)
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''SELECT fromaddress, subject, message, ackdata FROM sent WHERE status=? and folder='sent' ''')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
for row in queryreturn:
|
||||
fromaddress, subject, body, ackdata = row
|
||||
status, addressVersionNumber, streamNumber, ripe = decodeAddress(
|
||||
fromaddress)
|
||||
if addressVersionNumber == 2 and int(time.time()) < encryptedBroadcastSwitchoverTime:
|
||||
# We need to convert our private keys to public keys in order
|
||||
# to include them.
|
||||
try:
|
||||
privSigningKeyBase58 = shared.config.get(
|
||||
fromaddress, 'privsigningkey')
|
||||
privEncryptionKeyBase58 = shared.config.get(
|
||||
fromaddress, 'privencryptionkey')
|
||||
except:
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||
ackdata, bitmessagemain.translateText("MainWindow", "Error! Could not find sender address (your address) in the keys.dat file."))))
|
||||
continue
|
||||
|
||||
privSigningKeyHex = shared.decodeWalletImportFormat(
|
||||
privSigningKeyBase58).encode('hex')
|
||||
privEncryptionKeyHex = shared.decodeWalletImportFormat(
|
||||
privEncryptionKeyBase58).encode('hex')
|
||||
|
||||
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.
|
||||
pubEncryptionKey = highlevelcrypto.privToPub(
|
||||
privEncryptionKeyHex).decode('hex')
|
||||
|
||||
payload = pack('>Q', (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)
|
||||
payload += '\x00\x00\x00\x01' # behavior bitfield
|
||||
payload += pubSigningKey[1:]
|
||||
payload += pubEncryptionKey[1:]
|
||||
payload += ripe
|
||||
payload += '\x02' # message encoding type
|
||||
payload += encodeVarint(len(
|
||||
'Subject:' + subject + '\n' + 'Body:' + body)) # Type 2 is simple UTF-8 message encoding.
|
||||
payload += 'Subject:' + subject + '\n' + 'Body:' + body
|
||||
|
||||
signature = highlevelcrypto.sign(payload, privSigningKeyHex)
|
||||
payload += encodeVarint(len(signature))
|
||||
payload += signature
|
||||
|
||||
target = 2 ** 64 / ((len(
|
||||
payload) + shared.networkDefaultPayloadLengthExtraBytes + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||
print '(For broadcast message) Doing proof of work...'
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||
ackdata, bitmessagemain.translateText("MainWindow", "Doing work necessary to send broadcast..."))))
|
||||
initialHash = hashlib.sha512(payload).digest()
|
||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||
print '(For broadcast message) Found proof of work', trialValue, 'Nonce:', nonce
|
||||
|
||||
payload = pack('>Q', nonce) + payload
|
||||
|
||||
inventoryHash = calculateInventoryHash(payload)
|
||||
objectType = 'broadcast'
|
||||
shared.inventory[inventoryHash] = (
|
||||
objectType, streamNumber, payload, int(time.time()))
|
||||
print 'Broadcasting inv for my broadcast (within sendBroadcast function):', inventoryHash.encode('hex')
|
||||
shared.broadcastToSendDataQueues((
|
||||
streamNumber, 'sendinv', inventoryHash))
|
||||
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, bitmessagemain.translateText("MainWindow", "Broadcast sent on %1").arg(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
|
||||
shared.sqlLock.acquire()
|
||||
t = ('broadcastsent', int(
|
||||
time.time()), fromaddress, subject, body, 'broadcastqueued')
|
||||
shared.sqlSubmitQueue.put(
|
||||
'UPDATE sent SET status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()
|
||||
elif addressVersionNumber == 3 or int(time.time()) > encryptedBroadcastSwitchoverTime:
|
||||
# We need to convert our private keys to public keys in order
|
||||
# to include them.
|
||||
try:
|
||||
privSigningKeyBase58 = shared.config.get(
|
||||
fromaddress, 'privsigningkey')
|
||||
privEncryptionKeyBase58 = shared.config.get(
|
||||
fromaddress, 'privencryptionkey')
|
||||
except:
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||
ackdata, bitmessagemain.translateText("MainWindow", "Error! Could not find sender address (your address) in the keys.dat file."))))
|
||||
continue
|
||||
|
||||
privSigningKeyHex = shared.decodeWalletImportFormat(
|
||||
privSigningKeyBase58).encode('hex')
|
||||
privEncryptionKeyHex = shared.decodeWalletImportFormat(
|
||||
privEncryptionKeyBase58).encode('hex')
|
||||
|
||||
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.
|
||||
pubEncryptionKey = highlevelcrypto.privToPub(
|
||||
privEncryptionKeyHex).decode('hex')
|
||||
|
||||
payload = pack('>Q', (int(time.time()) + random.randrange(
|
||||
-300, 300))) # the current time plus or minus five minutes
|
||||
payload += encodeVarint(2) # broadcast version
|
||||
payload += encodeVarint(streamNumber)
|
||||
|
||||
dataToEncrypt = encodeVarint(2) # broadcast version
|
||||
dataToEncrypt += encodeVarint(addressVersionNumber)
|
||||
dataToEncrypt += encodeVarint(streamNumber)
|
||||
dataToEncrypt += '\x00\x00\x00\x01' # behavior bitfield
|
||||
dataToEncrypt += pubSigningKey[1:]
|
||||
dataToEncrypt += pubEncryptionKey[1:]
|
||||
if addressVersionNumber >= 3:
|
||||
dataToEncrypt += encodeVarint(shared.config.getint(fromaddress,'noncetrialsperbyte'))
|
||||
dataToEncrypt += encodeVarint(shared.config.getint(fromaddress,'payloadlengthextrabytes'))
|
||||
dataToEncrypt += '\x02' # message encoding type
|
||||
dataToEncrypt += encodeVarint(len('Subject:' + subject + '\n' + 'Body:' + body)) #Type 2 is simple UTF-8 message encoding per the documentation on the wiki.
|
||||
dataToEncrypt += 'Subject:' + subject + '\n' + 'Body:' + body
|
||||
signature = highlevelcrypto.sign(
|
||||
dataToEncrypt, privSigningKeyHex)
|
||||
dataToEncrypt += encodeVarint(len(signature))
|
||||
dataToEncrypt += signature
|
||||
|
||||
# Encrypt the broadcast with the information contained in the broadcaster's address. Anyone who knows the address can generate
|
||||
# the private encryption key to decrypt the broadcast. This provides virtually no privacy; its purpose is to keep questionable
|
||||
# and illegal content from flowing through the Internet connections and being stored on the disk of 3rd parties.
|
||||
privEncryptionKey = hashlib.sha512(encodeVarint(
|
||||
addressVersionNumber) + encodeVarint(streamNumber) + ripe).digest()[:32]
|
||||
pubEncryptionKey = pointMult(privEncryptionKey)
|
||||
payload += highlevelcrypto.encrypt(
|
||||
dataToEncrypt, pubEncryptionKey.encode('hex'))
|
||||
|
||||
target = 2 ** 64 / ((len(
|
||||
payload) + shared.networkDefaultPayloadLengthExtraBytes + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||
print '(For broadcast message) Doing proof of work...'
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||
ackdata, bitmessagemain.translateText("MainWindow", "Doing work necessary to send broadcast..."))))
|
||||
initialHash = hashlib.sha512(payload).digest()
|
||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||
print '(For broadcast message) Found proof of work', trialValue, 'Nonce:', nonce
|
||||
|
||||
payload = pack('>Q', nonce) + payload
|
||||
|
||||
inventoryHash = calculateInventoryHash(payload)
|
||||
objectType = 'broadcast'
|
||||
shared.inventory[inventoryHash] = (
|
||||
objectType, streamNumber, payload, int(time.time()))
|
||||
print 'sending inv (within sendBroadcast function)'
|
||||
shared.broadcastToSendDataQueues((
|
||||
streamNumber, 'sendinv', inventoryHash))
|
||||
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, bitmessagemain.translateText("MainWindow", "Broadcast sent on %1").arg(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
|
||||
shared.sqlLock.acquire()
|
||||
t = ('broadcastsent', int(
|
||||
time.time()), fromaddress, subject, body, 'broadcastqueued')
|
||||
shared.sqlSubmitQueue.put(
|
||||
'UPDATE sent SET status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()
|
||||
else:
|
||||
shared.printLock.acquire()
|
||||
sys.stderr.write(
|
||||
'Error: In the singleWorker thread, the sendBroadcast function doesn\'t understand the address version.\n')
|
||||
shared.printLock.release()
|
||||
|
||||
def sendMsg(self):
|
||||
# Check to see if there are any messages queued to be sent
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''SELECT DISTINCT toaddress FROM sent WHERE (status='msgqueued' AND folder='sent')''')
|
||||
shared.sqlSubmitQueue.put('')
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
for row in queryreturn: # For each address to which we need to send a message, check to see if we have its pubkey already.
|
||||
toaddress, = row
|
||||
toripe = decodeAddress(toaddress)[3]
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''SELECT hash FROM pubkeys WHERE hash=? ''')
|
||||
shared.sqlSubmitQueue.put((toripe,))
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
if queryreturn != []: # If we have the needed pubkey, set the status to doingmsgpow (we'll do it further down)
|
||||
t = (toaddress,)
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''UPDATE sent SET status='doingmsgpow' WHERE toaddress=? AND status='msgqueued' ''')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()
|
||||
else: # We don't have the needed pubkey. Set the status to 'awaitingpubkey' and request it if we haven't already
|
||||
if toripe in neededPubkeys:
|
||||
# We already sent a request for the pubkey
|
||||
t = (toaddress,)
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''UPDATE sent SET status='awaitingpubkey' WHERE toaddress=? AND status='msgqueued' ''')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByHash', (
|
||||
toripe, bitmessagemain.translateText("MainWindow",'Encryption key was requested earlier.'))))
|
||||
else:
|
||||
# We have not yet sent a request for the pubkey
|
||||
t = (toaddress,)
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put(
|
||||
'''UPDATE sent SET status='doingpubkeypow' WHERE toaddress=? AND status='msgqueued' ''')
|
||||
shared.sqlSubmitQueue.put(t)
|
||||
shared.sqlReturnQueue.get()
|
||||
shared.sqlSubmitQueue.put('commit')
|
||||
shared.sqlLock.release()
|
||||
shared.UISignalQueue.put(('updateSentItemStatusByHash', (
|
||||
toripe, bitmessagemain.translateText("MainWindow",'Sending a request for the recipient\'s encryption key.'))))
|
||||
self.requestPubKey(toaddress)
|
||||
shared.sqlLock.acquire()
|
||||
# Get all messages that are ready to be sent, and also all messages
|
||||
# which we have sent in the last 28 days which were previously marked
|
||||
# as 'toodifficult'. If the user as raised the maximum acceptable
|
||||
# difficulty then those messages may now be sendable.
|
||||
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' ''')
|
||||
shared.sqlSubmitQueue |