def test_refresh_masternode_list(self, bc_obj, get_blockchain_connection): bc_obj.return_value.masternode_list.return_value = mn_list get_blockchain_connection.return_value.masternode_list.return_value = mn_list self.assertEqual(Masternode.get_active_nodes().count(), 0) refresh_masternode_list() self.assertEqual(Masternode.get_active_nodes().count(), 3) self.assertEqual(ChunkMnDistance.select().count(), 0)
def setUp(self): MASTERNODE_DB.init(':memory:') MASTERNODE_DB.connect(reuse_if_open=True) MASTERNODE_DB.create_tables(DB_MODELS) Masternode.create( ext_address='127.0.0.1:444', pastel_id= 'jXZVtBmehoxYPotVrLdByFNNcB8jsryXhFPgqRa95i2x1mknbzSef1oGjnzfiwRtzReimfugvg41VtA7qGfDZR' ) Masternode.create( ext_address='127.0.0.1:4441', pastel_id= 'jXZVtBmehoxYPotVrLdByFNNcB7jsryXhFPgqRa95i2x1mknbzSef1oGjnzfiwRtzReimfugvg41VtA7qGfDZR' )
def setUp(self): MASTERNODE_DB.init(':memory:') MASTERNODE_DB.connect(reuse_if_open=True) MASTERNODE_DB.create_tables(DB_MODELS) for i in range(3): Masternode.create( ext_address='127.0.0.1:444{}'.format(i), pastel_id= 'jXZVtBmehoxYPotVrLdByFNNcB8jsryXhFPgqRa95i2x1mknbzSef1oGjnzfiwRtzReimfugvg41VtA7qGfDZ{}' .format(i)) Chunk.create( chunk_id= '1231231231231231232323934384834890089238429382938429384934{}'. format(i), image_hash=b'asdasdasd') index_new_chunks()
def get_owned_chunks(): """ Return list of database chunk records we should store. """ current_mn_id = Masternode.get( pastel_id=get_blockchain_connection().pastelid).id chunks_ranked_qs = ChunkMnRanked.select().where( ChunkMnRanked.masternode_id == current_mn_id) return [c.chunk for c in chunks_ranked_qs]
def test_calculate_xor_distances_for_masternodes( self, bc_obj, get_blockchain_connection): bc_obj.return_value.masternode_list.return_value = mn_list get_blockchain_connection.return_value.masternode_list.return_value = mn_list for i in range(3): Chunk.create( chunk_id= '1231231231231231232323934384834890089238429382938429384934{}'. format(i), image_hash=b'asdasdasd') refresh_masternode_list() self.assertEqual(Masternode.get_active_nodes().count(), 3) self.assertEqual(ChunkMnDistance.select().count(), 9)
def update_masternode_list(): """ Fetch current masternode list from cNode (by calling `masternode list extra`) and update database Masternode table accordingly. Return 2 sets of MN pastelIDs - added and removed, """ masternode_list = get_blockchain_connection().masternode_list() # parse new list fresh_mn_list = {} for k in masternode_list: node = masternode_list[k] # generate dict of {pastelid: <ip:port>} if len(node['extKey']) > 20 and len(node['extAddress']) > 4: fresh_mn_list[node['extKey']] = node['extAddress'] existing_mn_pastelids = set( [mn.pastel_id for mn in Masternode.get_active_nodes()]) fresh_mn_pastelids = set(fresh_mn_list.keys()) added_pastelids = fresh_mn_pastelids - existing_mn_pastelids removed_pastelids = existing_mn_pastelids - fresh_mn_pastelids # FIXME: uncomment this if cNode will not return empty keys. # cNode returns empty extKey for random masternode, but it does not mean that this MNs should be deleted.. # maybe need to delete MN only if it has not responses several times for fetch chunk request # if len(removed_pastelids): # Masternode.delete().where(Masternode.pastel_id.in_(removed_pastelids)).execute() if len(added_pastelids): tasks_logger.warn('Got new Masternodes. Adding to the list') data_for_insert = [{ 'pastel_id': pastelid, 'ext_address': fresh_mn_list[pastelid] } for pastelid in added_pastelids] Masternode.insert(data_for_insert).execute() return added_pastelids, removed_pastelids
async def get_status(self, request): self.__logger.info('Status request received') # filter = await request.content.read() active_mns = list(Masternode.get_active_nodes()) # mn_status = {} result = { "status": "alive", "pastel_id": get_blockchain_connection().pastelid, "masternodes": { "count": len(active_mns) } } return web.json_response(result)
def calculate_xor_distances_for_masternodes(pastelids): """ `pastelids` - list of pastelids of masternodes. PastelID is a string. """ mns_db = Masternode.get_active_nodes().where( Masternode.pastel_id.in_(pastelids)) for mn in mns_db: for chunk in Chunk.select(): # we store chunk.chunk_id as CharField, but essentially it's very long integer (more then 8 bytes, # doesn't fit in database INT type) xor_distance = calculate_xor_distance(mn.pastel_id, int(chunk.chunk_id)) ChunkMnDistance.create(chunk=chunk, masternode=mn, distance=str(xor_distance))
def get_missing_chunk_ids(pastel_id=None): """ :param pastel_id: str :return: list of str chunkd ids (big integer numbers wrapper to string as they're stored in DB """ if not pastel_id: pastel_id = get_blockchain_connection().pastelid # return chunks that we're owner of but don't have it in the storage try: current_mn_id = Masternode.get(pastel_id=pastel_id).id except DoesNotExist: return [] chunks_ranked_qs = ChunkMnRanked.select().join(Chunk).where( (ChunkMnRanked.masternode_id == current_mn_id) & (Chunk.stored == False) & (Chunk.attempts_to_load < 1000)) return [c.chunk.chunk_id for c in chunks_ranked_qs]
def calculate_xor_distances_for_chunks(chunk_ids): """ `chunk_ids` - list of chunks ids. Chunk ID is a very long integer. """ chunk_storage_logger.info( 'Calculating XOR distance for {} chunks...'.format(len(chunk_ids))) chunk_ids_str = [str(x) for x in chunk_ids] chunks_db = Chunk.select().where(Chunk.chunk_id.in_(chunk_ids_str)) counter = 0 for chunk in chunks_db: for mn in Masternode.get_active_nodes(): # we store chunk.chunk_id as CharField, but essentially it's very long integer (more then 8 bytes, # doesn't fit in database INT type) xor_distance = calculate_xor_distance(mn.pastel_id, int(chunk.chunk_id)) ChunkMnDistance.create(chunk=chunk, masternode=mn, distance=str(xor_distance)) counter += 1 chunk_storage_logger.info('..Caculated {} distances'.format(counter))
def test_xor_distance_task_without_chunks_without_masternodes(self): Masternode.delete() self.assertEqual(len(Chunk.select()), 0) index_new_chunks() self.assertEqual(len(ChunkMnDistance.select()), 0)