Added API for raw objects

This commit is contained in:
Biryuzovye Kleshni 2018-04-25 01:30:15 +00:00
parent c9a2240b44
commit 1fd021760a
3 changed files with 100 additions and 1 deletions

View File

@ -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

View File

@ -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):

View File

@ -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()