refactor 3/4

This commit is contained in:
william 2015-01-30 17:47:24 -05:00
parent a85cf6a49c
commit a5b3338df0

View File

@ -8,7 +8,6 @@ from debug import logger
# Helper Functions # Helper Functions
import proofofwork import proofofwork
from addresses import decodeAddress,addBMIfNotPresent,decodeVarint,calculateInventoryHash,varintDecodeError from addresses import decodeAddress,addBMIfNotPresent,decodeVarint,calculateInventoryHash,varintDecodeError
import helper_inbox import helper_inbox
import helper_sent import helper_sent
@ -16,33 +15,6 @@ from pyelliptic.openssl import OpenSSL
str_chan = '[chan]' str_chan = '[chan]'
# class messages( array ):
# def base( self ):
# msgid, toAddress, fromAddress, subject, message, encodingtype, received, read= query
# subject = shared.fixPotentiallyInvalidUTF8Data(subject)
# message = shared.fixPotentiallyInvalidUTF8Data(message)
# data.append({
# 'msgid':msgid.encode('hex'),
# 'toAddress':toAddress,
# 'fromAddress':fromAddress,
# 'subject':subject.encode('base64'),
# 'message':message.encode('base64'),
# 'encodingType':encodingtype,
# })
# def sent( sefl, query ):
# lastactiontime, status, ackdata = row[6:8]
# 'lastactiontime':lastactiontime,
# 'status':status,
# 'ackdata': ackdata
# def ( self, query ):
# received, read = row[6:7]
# 'receivedTime':received
# 'read': read
class _handle_request( object ): class _handle_request( object ):
def ping( self, *args ): def ping( self, *args ):
data = { 'pong': args } data = { 'pong': args }
@ -467,7 +439,7 @@ class _handle_request( object ):
return 200, {} return 200, {}
def getAllInboxMessages( self, *args ): def getAllInboxMessages( self, *args ):
queryreturn = sqlQuery('''SELECT msgid, toaddress, fromaddress, subject, received, message, encodingtype, read FROM inbox where folder='inbox' ORDER BY received''') queryreturn = sqlQuery('''SELECT msgid, toAddress, fromAddress, subject, message, encodingtype, received, read FROM inbox where folder='inbox' ORDER BY received''')
# data = rowMessage( queryreturn ) # data = rowMessage( queryreturn )
print queryreturn print queryreturn
return 200, queryreturn return 200, queryreturn
@ -507,25 +479,26 @@ class _handle_request( object ):
# return 200, data # return 200, data
# def getAllSentMessages( self, *args ): def getAllSentMessages( self, *args ):
# queryreturn = sqlQuery('''SELECT msgid, toaddress, fromaddress, subject, lastactiontime, message, encodingtype, status, ackdata FROM sent where folder='sent' ORDER BY lastactiontime''') queryreturn = sqlQuery('''SELECT msgid, toAddress, fromAddress, subject, message, encodingtype, lastactiontime, status, ackdata FROM sent where folder='sent' ORDER BY lastactiontime''')
# data = [] print queryreturn
# for row in queryreturn: data = []
# msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row # for row in queryreturn:
# subject = shared.fixPotentiallyInvalidUTF8Data(subject) # msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row
# message = shared.fixPotentiallyInvalidUTF8Data(message) # subject = shared.fixPotentiallyInvalidUTF8Data(subject)
# data.append({ # message = shared.fixPotentiallyInvalidUTF8Data(message)
# 'msgid':msgid.encode('hex'), # data.append({
# 'toAddress':toAddress, # 'msgid':msgid.encode('hex'),
# 'fromAddress':fromAddress, # 'toAddress':toAddress,
# 'subject':subject.encode('base64'), # 'fromAddress':fromAddress,
# 'message':message.encode('base64'), # 'subject':subject.encode('base64'),
# 'encodingType':encodingtype, # 'message':message.encode('base64'),
# 'lastActionTime':lastactiontime, # 'encodingType':encodingtype,
# 'status':status, # 'lastActionTime':lastactiontime,
# 'ackData':ackdata.encode('hex') # 'status':status,
# }) # 'ackData':ackdata.encode('hex')
# return 200, data # })
return 200, queryreturn
# def getAllSentMessageIDs( self, *args ): # undocumented # def getAllSentMessageIDs( self, *args ): # undocumented
# queryreturn = sqlQuery('''SELECT msgid FROM sent where folder='sent' ORDER BY lastactiontime''') # queryreturn = sqlQuery('''SELECT msgid FROM sent where folder='sent' ORDER BY lastactiontime''')
@ -844,3 +817,174 @@ class _handle_request( object ):
# shared.UISignalQueue.put(('rerenderInboxFromLabels', '')) # shared.UISignalQueue.put(('rerenderInboxFromLabels', ''))
# shared.UISignalQueue.put(('rerenderSubscriptions', '')) # shared.UISignalQueue.put(('rerenderSubscriptions', ''))
# return 200, 'Deleted subscription if it existed.' # return 200, 'Deleted subscription if it existed.'
def listSubscriptions( self, *args ):
queryreturn = sqlQuery('''SELECT label, address, enabled FROM subscriptions''')
data = []
for row in queryreturn:
label, address, enabled = row
label = shared.fixPotentiallyInvalidUTF8Data(label)
data.append({
'label':label.encode('base64'),
'address': address,
'enabled': enabled == 1
})
return 200, data
def disseminatePreEncryptedMsg( self, *args ):
# The device issuing this command to PyBitmessage supplies a msg object that has
# already been encrypted but which still needs the POW to be done. PyBitmessage
# accepts this msg object and sends it out to the rest of the Bitmessage network
# as if it had generated the message itself. Please do not yet add this to the
# api doc.
if len( args ) != 3:
return 0, 'I need 3 parameter!'
encryptedPayload, requiredAverageProofOfWorkNonceTrialsPerByte, requiredPayloadLengthExtraBytes = args
encryptedPayload = self._decode(encryptedPayload, "hex")
# Let us do the POW and attach it to the front
target = 2**64 / ((len(encryptedPayload)+requiredPayloadLengthExtraBytes+8) * requiredAverageProofOfWorkNonceTrialsPerByte)
with shared.printLock:
print '(For msg message via API) Doing proof of work. Total required difficulty:', float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte, 'Required small message difficulty:', float(requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes
powStartTime = time.time()
initialHash = hashlib.sha512(encryptedPayload).digest()
trialValue, nonce = proofofwork.run(target, initialHash)
with shared.printLock:
print '(For msg message via API) Found proof of work', trialValue, 'Nonce:', nonce
try:
print 'POW took', int(time.time() - powStartTime), 'seconds.', nonce / (time.time() - powStartTime), 'nonce trials per second.'
except:
pass
encryptedPayload = pack('>Q', nonce) + encryptedPayload
toStreamNumber = decodeVarint(encryptedPayload[16:26])[0]
inventoryHash = calculateInventoryHash(encryptedPayload)
objectType = 2
TTL = 2.5 * 24 * 60 * 60
shared.inventory[inventoryHash] = (
objectType, toStreamNumber, encryptedPayload, int(time.time()) + TTL,'')
shared.inventorySets[toStreamNumber].add(inventoryHash)
with shared.printLock:
print 'Broadcasting inv for msg(API disseminatePreEncryptedMsg command):', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues((
toStreamNumber, 'advertiseobject', inventoryHash))
def disseminatePubkey':
# The device issuing this command to PyBitmessage supplies a pubkey object to be
# disseminated to the rest of the Bitmessage network. PyBitmessage accepts this
# pubkey object and sends it out to the rest of the Bitmessage network as if it
# had generated the pubkey object itself. Please do not yet add this to the api
# doc.
if len( args ) != 1:
return 0, 'I need 1 parameter!'
payload, = args
payload = self._decode(payload, "hex")
# Let us do the POW
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
print '(For pubkey message via API) Doing proof of work...'
initialHash = hashlib.sha512(payload).digest()
trialValue, nonce = proofofwork.run(target, initialHash)
print '(For pubkey message via API) Found proof of work', trialValue, 'Nonce:', nonce
payload = pack('>Q', nonce) + payload
pubkeyReadPosition = 8 # bypass the nonce
if payload[pubkeyReadPosition:pubkeyReadPosition+4] == '\x00\x00\x00\x00': # if this pubkey uses 8 byte time
pubkeyReadPosition += 8
else:
pubkeyReadPosition += 4
addressVersion, addressVersionLength = decodeVarint(payload[pubkeyReadPosition:pubkeyReadPosition+10])
pubkeyReadPosition += addressVersionLength
pubkeyStreamNumber = decodeVarint(payload[pubkeyReadPosition:pubkeyReadPosition+10])[0]
inventoryHash = calculateInventoryHash(payload)
objectType = 1
#todo: support v4 pubkeys
TTL = 28 * 24 * 60 * 60
shared.inventory[inventoryHash] = (
objectType, pubkeyStreamNumber, payload, int(time.time()) + TTL,'')
shared.inventorySets[pubkeyStreamNumber].add(inventoryHash)
with shared.printLock:
print 'broadcasting inv within API command disseminatePubkey with hash:', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues((
streamNumber, 'advertiseobject', inventoryHash))
def getMessageDataByDestinationTag( self, *args ):
# Method will eventually be used by a particular Android app to
# select relevant messages. Do not yet add this to the api
# doc.
if len( args ) != 1:
0, 'I need 1 parameter!'
requestedHash, = args
if len(requestedHash) != 32:
return 19, 'The length of hash should be 32 bytes (encoded in hex thus 64 characters).'
requestedHash = self._decode(requestedHash, "hex")
# This is not a particularly commonly used API function. Before we
# use it we'll need to fill out a field in our inventory database
# which is blank by default (first20bytesofencryptedmessage).
queryreturn = sqlQuery(
'''SELECT hash, payload FROM inventory WHERE tag = '' and objecttype = 2 ; ''')
with SqlBulkExecute() as sql:
for row in queryreturn:
hash01, payload = row
readPosition = 16 # Nonce length + time length
readPosition += decodeVarint(payload[readPosition:readPosition+10])[1] # Stream Number length
t = (payload[readPosition:readPosition+32],hash01)
sql.execute('''UPDATE inventory SET tag=? WHERE hash=?; ''', *t)
queryreturn = sqlQuery('''SELECT payload FROM inventory WHERE tag = ?''',
requestedHash)
data = []
for row in queryreturn:
payload, = row
data.append({'data':payload.encode('hex')})
return 200, data
def getPubkeyByHash( self, *args ):
# Method will eventually be used by a particular Android app to
# retrieve pubkeys. Please do not yet add this to the api docs.
if len( args ) != 1:
return 0, 'I need 1 parameter!'
requestedHash, = args
if len(requestedHash) != 40:
return 19, 'The length of hash should be 20 bytes (encoded in hex thus 40 characters).'
requestedHash = self._decode(requestedHash, "hex")
queryreturn = sqlQuery('''SELECT transmitdata FROM pubkeys WHERE hash = ? ; ''', requestedHash)
data = []
for row in queryreturn:
transmitdata, = row
data.append({'data':transmitdata.encode('hex')})
return 200, data
def clientStatus( self, *args ):
if len(shared.connectedHostsList) == 0:
networkStatus = 'notConnected'
elif len(shared.connectedHostsList) > 0 and not shared.clientHasReceivedIncomingConnections:
networkStatus = 'connectedButHaveNotReceivedIncomingConnections'
else:
networkStatus = 'connectedAndReceivingIncomingConnections'
data = {
'networkConnections':len(shared.connectedHostsList),
'numberOfMessagesProcessed':shared.numberOfMessagesProcessed,
'numberOfBroadcastsProcessed':shared.numberOfBroadcastsProcessed,
'numberOfPubkeysProcessed':shared.numberOfPubkeysProcessed,
'networkStatus':networkStatus,
'softwareName':'PyBitmessage',
'softwareVersion':shared.softwareVersion
}
return 200, data
def decodeAddress( self, *args ):
# Return a meaningful decoding of an address.
if len( args ) != 1:
return 0, 'I need 1 parameter!'
address, = params
status, addressVersion, streamNumber, ripe = decodeAddress(address)
data = {
'status':status,
'addressVersion':addressVersion,
'streamNumber':streamNumber,
'ripe':ripe.encode('base64')
}
return 200, data