Added API for raw objects
This commit is contained in:
parent
c9a2240b44
commit
1fd021760a
81
src/api.py
81
src/api.py
|
@ -22,10 +22,12 @@ import shared
|
||||||
import time
|
import time
|
||||||
from addresses import (decodeAddress, addBMIfNotPresent, decodeVarint,
|
from addresses import (decodeAddress, addBMIfNotPresent, decodeVarint,
|
||||||
calculateInventoryHash, varintDecodeError)
|
calculateInventoryHash, varintDecodeError)
|
||||||
|
import protocol
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
import defaults
|
import defaults
|
||||||
import helper_inbox
|
import helper_inbox
|
||||||
import helper_sent
|
import helper_sent
|
||||||
|
import helper_random
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
import state
|
import state
|
||||||
|
@ -63,6 +65,7 @@ class StoppableXMLRPCServer(SimpleXMLRPCServer):
|
||||||
while state.shutdown == 0:
|
while state.shutdown == 0:
|
||||||
self.handle_request()
|
self.handle_request()
|
||||||
|
|
||||||
|
queuedRawObjects = {}
|
||||||
|
|
||||||
# This is one of several classes that constitute the API
|
# This is one of several classes that constitute the API
|
||||||
# This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros).
|
# This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros).
|
||||||
|
@ -951,6 +954,79 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
data += ']}'
|
data += ']}'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def HandleDisseminateRawObject(self, params):
|
||||||
|
if len(params) != 1:
|
||||||
|
raise APIError(0, 'I need 1 parameter!')
|
||||||
|
payload = self._decode(params[0], "hex")
|
||||||
|
|
||||||
|
if protocol.checkAndShareObjectWithPeers(payload) == 0:
|
||||||
|
raise APIError(30, 'Invalid object or insufficient POW')
|
||||||
|
else:
|
||||||
|
return hexlify(calculateInventoryHash(payload))
|
||||||
|
|
||||||
|
def HandleQueueRawObject(self, params):
|
||||||
|
if len(params) != 1:
|
||||||
|
raise APIError(0, 'I need 1 parameter!')
|
||||||
|
payload = self._decode(params[0], "hex")
|
||||||
|
queueItemID = helper_random.randomBytes(32)
|
||||||
|
queues.workerQueue.put(('sendrawobject', (queueItemID, payload)))
|
||||||
|
queuedRawObjects[queueItemID] = "queued"
|
||||||
|
return hexlify(queueItemID)
|
||||||
|
|
||||||
|
def HandleCheckQueuedRawObject(self, params):
|
||||||
|
if len(params) != 1:
|
||||||
|
raise APIError(0, 'I need 1 parameter!')
|
||||||
|
queueItemID, = params
|
||||||
|
if len(queueItemID) != 64:
|
||||||
|
raise APIError(19, 'The length of queue item ID should be 32 bytes (encoded in hex thus 64 characters).')
|
||||||
|
queueItemID = self._decode(queueItemID, "hex")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
ID, result = queues.processedRawObjectsQueue.get_nowait()
|
||||||
|
queuedRawObjects[ID] = result
|
||||||
|
except:
|
||||||
|
break
|
||||||
|
|
||||||
|
result = queuedRawObjects.get(queueItemID, "notfound")
|
||||||
|
if result == "failed" or len(result) == 64:
|
||||||
|
del queuedRawObjects[queueItemID]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def HandleGetRawObject(self, params):
|
||||||
|
if len(params) != 1:
|
||||||
|
raise APIError(0, 'I need 1 parameter!')
|
||||||
|
inventoryHash, = params
|
||||||
|
if len(inventoryHash) != 64:
|
||||||
|
raise APIError(19, 'The length of hash should be 32 bytes (encoded in hex thus 64 characters).')
|
||||||
|
inventoryHash = self._decode(inventoryHash, "hex")
|
||||||
|
|
||||||
|
try:
|
||||||
|
inventoryItem = Inventory()[inventoryHash]
|
||||||
|
except:
|
||||||
|
raise APIError(31, 'Object not found.')
|
||||||
|
else:
|
||||||
|
return json.dumps({'hash':hexlify(inventoryHash),'objectType':inventoryItem.type,'streamNumber':inventoryItem.stream,'payload':hexlify(inventoryItem.payload),'expiresTime':inventoryItem.expires,'tag':hexlify(inventoryItem.tag)}, indent=4, separators=(',', ': '))
|
||||||
|
|
||||||
|
def HandleListRawObjects(self, params):
|
||||||
|
if len(params) != 4:
|
||||||
|
raise APIError(0, 'I need 4 parameters!')
|
||||||
|
objectType, streamNumber, sliceStart, sliceEnd = params
|
||||||
|
if type(sliceStart) is not int or type(sliceEnd) is not int:
|
||||||
|
raise APIError(32, 'Invalid slice boundaries')
|
||||||
|
|
||||||
|
result = []
|
||||||
|
inventory = Inventory()
|
||||||
|
for i in inventory:
|
||||||
|
inventoryItem = inventory[str(i)]
|
||||||
|
if objectType != -1 and inventoryItem.type != objectType:
|
||||||
|
continue
|
||||||
|
if streamNumber != 0 and inventoryItem.stream != streamNumber:
|
||||||
|
continue
|
||||||
|
result.append({'hash':hexlify(i),'slice':hexlify(inventoryItem.payload[sliceStart:sliceEnd])})
|
||||||
|
|
||||||
|
return json.dumps(result, indent=4, separators=(',', ': '))
|
||||||
|
|
||||||
def HandleClientStatus(self, params):
|
def HandleClientStatus(self, params):
|
||||||
if len(network.stats.connectedHostsList()) == 0:
|
if len(network.stats.connectedHostsList()) == 0:
|
||||||
networkStatus = 'notConnected'
|
networkStatus = 'notConnected'
|
||||||
|
@ -1039,6 +1115,11 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
handlers['disseminatePubkey'] = HandleDissimatePubKey
|
handlers['disseminatePubkey'] = HandleDissimatePubKey
|
||||||
handlers['getMessageDataByDestinationHash'] = HandleGetMessageDataByDestinationHash
|
handlers['getMessageDataByDestinationHash'] = HandleGetMessageDataByDestinationHash
|
||||||
handlers['getMessageDataByDestinationTag'] = HandleGetMessageDataByDestinationHash
|
handlers['getMessageDataByDestinationTag'] = HandleGetMessageDataByDestinationHash
|
||||||
|
handlers['disseminateRawObject'] = HandleDisseminateRawObject
|
||||||
|
handlers['queueRawObject'] = HandleQueueRawObject
|
||||||
|
handlers['checkQueuedRawObject'] = HandleCheckQueuedRawObject
|
||||||
|
handlers['getRawObject'] = HandleGetRawObject
|
||||||
|
handlers['listRawObjects'] = HandleListRawObjects
|
||||||
handlers['clientStatus'] = HandleClientStatus
|
handlers['clientStatus'] = HandleClientStatus
|
||||||
handlers['decodeAddress'] = HandleDecodeAddress
|
handlers['decodeAddress'] = HandleDecodeAddress
|
||||||
handlers['deleteAndVacuum'] = HandleDeleteAndVacuum
|
handlers['deleteAndVacuum'] = HandleDeleteAndVacuum
|
||||||
|
|
|
@ -3,7 +3,7 @@ from __future__ import division
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import hashlib
|
import hashlib
|
||||||
from struct import pack
|
from struct import pack, unpack
|
||||||
# used when the API must execute an outside program
|
# used when the API must execute an outside program
|
||||||
from subprocess import call
|
from subprocess import call
|
||||||
from binascii import hexlify, unhexlify
|
from binascii import hexlify, unhexlify
|
||||||
|
@ -137,6 +137,11 @@ class singleWorker(threading.Thread, StoppableThread):
|
||||||
self.sendBroadcast()
|
self.sendBroadcast()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
elif command == 'sendrawobject':
|
||||||
|
try:
|
||||||
|
self.sendRawObject(data)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
elif command == 'doPOWForMyV2Pubkey':
|
elif command == 'doPOWForMyV2Pubkey':
|
||||||
try:
|
try:
|
||||||
self.doPOWForMyV2Pubkey(data)
|
self.doPOWForMyV2Pubkey(data)
|
||||||
|
@ -226,6 +231,18 @@ class singleWorker(threading.Thread, StoppableThread):
|
||||||
# inventoryHash = calculateInventoryHash(payload)
|
# inventoryHash = calculateInventoryHash(payload)
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
def sendRawObject(self, data):
|
||||||
|
queueItemID, payload = data
|
||||||
|
endOfLifeTime, = unpack('>Q', payload[:8])
|
||||||
|
TTL = min(28 * 24 * 60 * 60, max(300, endOfLifeTime - int(time.time())))
|
||||||
|
payload = self._doPOWDefaults(
|
||||||
|
payload, TTL, log_prefix='(For raw object)')
|
||||||
|
|
||||||
|
if protocol.checkAndShareObjectWithPeers(payload) == 0:
|
||||||
|
queues.processedRawObjectsQueue.put((queueItemID, "failed"))
|
||||||
|
else:
|
||||||
|
queues.processedRawObjectsQueue.put((queueItemID, hexlify(calculateInventoryHash(payload))))
|
||||||
|
|
||||||
# This function also broadcasts out the pubkey message
|
# This function also broadcasts out the pubkey message
|
||||||
# once it is done with the POW
|
# once it is done with the POW
|
||||||
def doPOWForMyV2Pubkey(self, hash):
|
def doPOWForMyV2Pubkey(self, hash):
|
||||||
|
|
|
@ -14,3 +14,4 @@ portCheckerQueue = Queue.Queue()
|
||||||
receiveDataQueue = Queue.Queue()
|
receiveDataQueue = Queue.Queue()
|
||||||
apiAddressGeneratorReturnQueue = Queue.Queue(
|
apiAddressGeneratorReturnQueue = Queue.Queue(
|
||||||
) # The address generator thread uses this queue to get information back to the API thread.
|
) # The address generator thread uses this queue to get information back to the API thread.
|
||||||
|
processedRawObjectsQueue = Queue.Queue()
|
||||||
|
|
Reference in New Issue
Block a user