Exemplo n.º 1
0
    async def from_dict(cls, block):
        transactions = []
        for txn in block.get('transactions'):
            # TODO: do validity checking for coinbase transactions
            if str(P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(block.get('public_key')))) in [x['to'] for x in txn.get('outputs', '')] and len(txn.get('outputs', '')) == 1 and not txn.get('inputs') and not txn.get('relationship'):
                txn['coinbase'] = True  
            else:
                txn['coinbase'] = False
            transactions.append(Transaction.from_dict(txn))

        if block.get('special_target', 0) == 0:
            block['special_target'] = block.get('target')

        return await cls.init_async(
            version=block.get('version'),
            block_time=block.get('time'),
            block_index=block.get('index'),
            public_key=block.get('public_key'),
            prev_hash=block.get('prevHash'),
            nonce=block.get('nonce'),
            transactions=transactions,
            block_hash=block.get('hash'),
            merkle_root=block.get('merkleRoot'),
            signature=block.get('id'),
            special_min=block.get('special_min'),
            header=block.get('header', ''),
            target=int(block.get('target'), 16),
            special_target=int(block.get('special_target', 0), 16)
        )
Exemplo n.º 2
0
    async def newtxn(self, body, stream):
        payload = body.get('params', {})
        if (not payload.get('transaction')):
            return

        txn = Transaction.from_dict(payload.get('transaction'))
        try:
            await txn.verify()
        except:
            return

        await self.config.mongo.async_db.miner_transactions.replace_one(
            {'id': txn.transaction_signature}, txn.to_dict(), upsert=True)

        if stream.peer.protocol_version > 2:
            await self.write_result(stream, 'newtxn_confirmed',
                                    body.get('params', {}), body['id'])

        async for peer_stream in self.config.peer.get_sync_peers():
            if peer_stream.peer.rid == stream.peer.rid:
                continue
            await self.write_params(peer_stream, 'newtxn', payload)
            if peer_stream.peer.protocol_version > 1:
                self.retry_messages[(peer_stream.peer.rid, 'newtxn',
                                     txn.transaction_signature)] = body.get(
                                         'params', {})
Exemplo n.º 3
0
    async def newtxn_confirmed(self, body, stream):
        result = body.get('result', {})
        transaction = Transaction.from_dict(result.get('transaction'))

        if (stream.peer.rid, 'newtxn',
                transaction.transaction_signature) in self.retry_messages:
            del self.retry_messages[(stream.peer.rid, 'newtxn',
                                     transaction.transaction_signature)]
Exemplo n.º 4
0
    async def post(self):
        try:
            ns = json.loads(self.request.body.decode('utf-8'))
        except:
            return self.render_as_json({
                'status': 'error',
                'message': 'invalid request body'
            })
        try:
            nstxn = Transaction.from_dict(ns['txn'])
        except:
            return self.render_as_json({
                'status': 'error',
                'message': 'invalid transaction'
            })
        try:
            peer = Peer(ns['peer']['host'], ns['peer']['port'])
        except:
            return self.render_as_json({
                'status': 'error',
                'message': 'invalid peer'
            })

        existing = await self.config.mongo.async_db.name_server.find_one({
            'rid':
            nstxn.rid,
            'requester_rid':
            nstxn.requester_rid,
            'requested_rid':
            nstxn.requested_rid,
            'peer_str':
            peer.to_string(),
        })
        if not existing:
            await self.config.mongo.async_db.name_server.insert_one({
                'rid':
                nstxn.rid,
                'requester_rid':
                nstxn.requester_rid,
                'requested_rid':
                nstxn.requested_rid,
                'peer_str':
                peer.to_string(),
                'peer':
                peer.to_dict(),
                'txn':
                nstxn.to_dict()
            })
        tb = NSBroadcaster(self.config)
        await tb.ns_broadcast_job(nstxn)
        return self.render_as_json({'status': 'success'})
Exemplo n.º 5
0
 def get_transaction_by_id(self,
                           id,
                           instance=False,
                           give_block=False,
                           include_fastgraph=False,
                           inc_mempool=False):
     from yadacoin.core.transaction import Transaction
     res = self.mongo.db.blocks.find({"transactions.id": id})
     if res.count():
         for block in res:
             if give_block:
                 return block
             for txn in block['transactions']:
                 if txn['id'] == id:
                     if instance:
                         try:
                             return FastGraph.from_dict(block['index'], txn)
                         except:
                             return Transaction.from_dict(txn)
                     else:
                         return txn
     if inc_mempool:
         res2 = self.mongo.db.miner_transactions.find_one({"id": id})
         if res2:
             if give_block:
                 raise Exception(
                     'Cannot give block for mempool transaction')
             if instance:
                 return Transaction.from_dict(res2)
             else:
                 return res2
         return None
     else:
         # fix for bug when unspent cache returns an input
         # that has been removed from the chain
         self.mongo.db.unspent_cache.remove({})
         return None
Exemplo n.º 6
0
 def check_rid_txn_fully_spent(cls, config, rid_txn, address, index):
     from yadacoin.core.transaction import Transaction
     rid_txn = Transaction.from_dict(rid_txn)
     spending_txn = rid_txn.used_as_input(rid_txn.transaction_signature)
     if spending_txn:
         for output in spending_txn['outputs']:
             if output['to'] == address and output['value'] == 0:
                 return True  # now we can create a duplicate relationship
         x = config.BU.get_transaction_by_id(spending_txn['id'],
                                             instance=True)
         result = cls.check_rid_txn_fully_spent(config, x.to_dict(),
                                                address, index)
         if result:
             return True
         return False
     else:
         return False  # hasn't been spent to zero yet
Exemplo n.º 7
0
    async def newtxn(self, body, stream):
        payload = body.get('params', {})
        if (not payload.get('transaction')):
            return

        txn = Transaction.from_dict(payload.get('transaction'))
        try:
            await txn.verify()
        except:
            return

        to_store = txn.to_dict()
        to_store['sent_to'] = [stream.peer.to_dict()]
        await self.config.mongo.async_db.miner_transactions.replace_one(
            {'id': txn.transaction_signature},
            to_store,
            upsert=True,
        )

        async for peer_stream in self.config.peer.get_sync_peers():
            if peer_stream.peer.rid == stream.peer.rid:
                continue
            await self.write_params(peer_stream, 'newtxn', payload)
Exemplo n.º 8
0
    async def generate(
        cls,
        transactions=None,
        public_key=None,
        private_key=None,
        force_version=None,
        index=0,
        force_time=None,
        prev_hash=None,
        nonce=None,
        target=CHAIN.MAX_TARGET
    ):
        config = get_config()
        app_log = getLogger("tornado.application")
        if force_version is None:
            version = CHAIN.get_version_for_height(index)
        else:
            version = force_version
        if force_time:
            xtime = str(int(force_time))
        else:
            xtime = str(int(time.time()))
        index = int(index)
        if index == 0:
            prev_hash = ''
        elif prev_hash is None and index != 0:
            prev_hash = LatestBlock.block.hash
        transactions = transactions or []

        transaction_objs = []
        fee_sum = 0.0
        used_sigs = []
        used_inputs = {}
        for txn in transactions:
            try:
                if isinstance(txn, Transaction):
                    transaction_obj = txn
                else:
                    transaction_obj = Transaction.from_dict(txn)

                if transaction_obj.transaction_signature in used_sigs:
                    print('duplicate transaction found and removed')
                    continue

                await transaction_obj.verify()
                used_sigs.append(transaction_obj.transaction_signature)
            except:
                raise InvalidTransactionException("invalid transactions")
            try:
                if int(index) > CHAIN.CHECK_TIME_FROM and (int(transaction_obj.time) > int(xtime) + CHAIN.TIME_TOLERANCE):
                    config.mongo.db.miner_transactions.remove({'id': transaction_obj.transaction_signature}, multi=True)
                    app_log.debug("Block embeds txn too far in the future {} {}".format(xtime, transaction_obj.time))
                    continue
                
                if transaction_obj.inputs:
                    failed = False
                    used_ids_in_this_txn = []
                    for x in transaction_obj.inputs:
                        if config.BU.is_input_spent(x.id, transaction_obj.public_key):
                            failed = True
                        if x.id in used_ids_in_this_txn:
                            failed = True
                        if (x.id, transaction_obj.public_key) in used_inputs:
                            failed = True
                        used_inputs[(x.id, transaction_obj.public_key)] = transaction_obj
                        used_ids_in_this_txn.append(x.id)
                    if failed:
                        continue

                transaction_objs.append(transaction_obj)

                fee_sum += float(transaction_obj.fee)
            except Exception as e:
                await config.mongo.async_db.miner_transactions.delete_many({'id': transaction_obj.transaction_signature})
                config.app_log.debug('Exception {}'.format(e))
                continue

        block_reward = CHAIN.get_block_reward(index)
        coinbase_txn = await Transaction.generate(
            public_key=public_key,
            private_key=private_key,
            outputs=[{
                'value': block_reward + float(fee_sum),
                'to': str(P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(public_key)))
            }],
            coinbase=True
        )
        transaction_objs.append(coinbase_txn)

        transactions = transaction_objs
        block = await cls.init_async(
            version=version,
            block_time=xtime,
            block_index=index,
            prev_hash=prev_hash,
            transactions=transactions,
            public_key=public_key,
            target=target
        )
        txn_hashes = block.get_transaction_hashes()
        block.set_merkle_root(txn_hashes)
        block.target = target
        block.header = block.generate_header()
        if nonce:
            block.nonce = str(nonce)
            block.hash = block.generate_hash_from_header(
                block.index,
                block.header,
                str(block.nonce)
            )
            block.signature = TU.generate_signature(block.hash, private_key)
        return block
Exemplo n.º 9
0
    async def post(self):
        self.get_base_graph(
        )  # TODO: did this to set bulletin_secret, refactor this
        items = json.loads(self.request.body.decode('utf-8'))
        if not isinstance(items, list):
            items = [
                items,
            ]
        else:
            items = [item for item in items]
        transactions = []
        for txn in items:
            transaction = Transaction.from_dict(txn)
            try:
                await transaction.verify()
            except InvalidTransactionException:
                await self.config.mongo.async_db.failed_transactions.insert_one(
                    {
                        'exception': 'InvalidTransactionException',
                        'txn': txn
                    })
                print('InvalidTransactionException')
                return 'InvalidTransactionException', 400
            except InvalidTransactionSignatureException:
                print('InvalidTransactionSignatureException')
                await self.config.mongo.async_db.failed_transactions.insert_one(
                    {
                        'exception': 'InvalidTransactionSignatureException',
                        'txn': txn
                    })
                return 'InvalidTransactionSignatureException', 400
            except MissingInputTransactionException:
                pass
            except:
                raise
                print('uknown error')
                return 'uknown error', 400
            transactions.append(transaction)

        for x in transactions:
            if x.rid == self.rid and x.dh_public_key:
                me_pending_exists = await self.config.mongo.async_db.miner_transactions.find_one(
                    {
                        'public_key': self.config.public_key,
                        'rid': self.rid,
                        'dh_public_key': {
                            '$exists': True
                        }
                    })
                me_blockchain_exists = await self.config.mongo.async_db.blocks.find_one(
                    {
                        'public_key': self.config.public_key,
                        'rid': self.rid,
                        'dh_public_key': {
                            '$exists': True
                        }
                    })
                if not me_pending_exists and not me_blockchain_exists:
                    created_relationship = await self.create_relationship(
                        self.bulletin_secret, self.username, self.to)
                    if isinstance(created_relationship, Transaction):
                        await self.config.mongo.async_db.miner_transactions.insert_one(
                            created_relationship.to_dict())
                        created_relationship.relationship = created_relationship.relationship
                        await self.config.mongo.async_db.name_server.insert_one(
                            {
                                'rid': created_relationship.rid,
                                'requester_rid':
                                created_relationship.requester_rid,
                                'requested_rid':
                                created_relationship.requested_rid,
                                'peer_str': 'me',
                                'peer': {
                                    'host': 'me',
                                    'port': 0
                                },
                                'txn': created_relationship.to_dict()
                            })
                        tb = NSBroadcaster(self.config)
                        await tb.ns_broadcast_job(created_relationship)
                    else:
                        self.app_log.debug(
                            'relationship creation failed for NS: {}'.format(
                                created_relationship))

                pending_exists = await self.config.mongo.async_db.miner_transactions.find_one(
                    {
                        'public_key': x.public_key,
                        'rid': self.rid,
                        'dh_public_key': {
                            '$exists': True
                        }
                    })
                blockchain_exists = await self.config.mongo.async_db.blocks.find_one(
                    {
                        'public_key': x.public_key,
                        'rid': self.rid,
                        'dh_public_key': {
                            '$exists': True
                        }
                    })
                if pending_exists or blockchain_exists:
                    continue

            if x.dh_public_key:
                dup_check_count = await self.config.mongo.async_db.miner_transactions.count_documents(
                    {
                        'dh_public_key': {
                            '$exists': True
                        },
                        'rid': x.rid,
                        'requester_rid': x.requester_rid,
                        'requested_rid': x.requested_rid,
                        'public_key': x.public_key
                    })
                if dup_check_count:
                    self.app_log.debug(
                        'found duplicate tx for rid set {}'.format(
                            x.transaction_signature))
                    return

            await self.config.mongo.async_db.miner_transactions.insert_one(
                x.to_dict())

        return self.render_as_json(items)
Exemplo n.º 10
0
    async def get_pending_transactions(self):
        transaction_objs = []
        used_sigs = []
        async for txn in self.mongo.async_db.miner_transactions.find().sort([
            ('fee', -1)
        ]):
            try:
                if isinstance(txn, Transaction):
                    transaction_obj = txn
                elif isinstance(txn, dict):
                    transaction_obj = Transaction.from_dict(txn)
                else:
                    self.config.app_log.warning(
                        'transaction unrecognizable, skipping')
                    continue

                await transaction_obj.verify()

                if transaction_obj.transaction_signature in used_sigs:
                    self.config.app_log.warning(
                        'duplicate transaction found and removed')
                    continue
                used_sigs.append(transaction_obj.transaction_signature)

                failed1 = False
                failed2 = False
                used_ids_in_this_txn = []

                async for x in self.get_inputs(transaction_obj.inputs):
                    is_input_spent = await self.config.BU.is_input_spent(
                        x.id, transaction_obj.public_key)
                    if is_input_spent:
                        failed1 = True
                    if x.id in used_ids_in_this_txn:
                        failed2 = True
                    used_ids_in_this_txn.append(x.id)
                if failed1:
                    self.mongo.db.miner_transactions.remove(
                        {'id': transaction_obj.transaction_signature})
                    self.config.app_log.warning(
                        'transaction removed: input presumably spent already, not in unspent outputs {}'
                        .format(transaction_obj.transaction_signature))
                    self.mongo.db.failed_transactions.insert({
                        'reason':
                        'input presumably spent already',
                        'txn':
                        transaction_obj.to_dict()
                    })
                elif failed2:
                    self.config.app_log.warning(
                        'transaction removed: using an input used by another transaction in this block {}'
                        .format(transaction_obj.transaction_signature))
                    self.mongo.db.miner_transactions.remove(
                        {'id': transaction_obj.transaction_signature})
                    self.mongo.db.failed_transactions.insert({
                        'reason':
                        'using an input used by another transaction in this block',
                        'txn':
                        transaction_obj.to_dict()
                    })
                else:
                    transaction_objs.append(transaction_obj)

            except MissingInputTransactionException as e:
                self.config.app_log.warning(
                    'MissingInputTransactionException: transaction removed')
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason':
                    'MissingInputTransactionException',
                    'txn':
                    transaction_obj.to_dict()
                })

            except InvalidTransactionSignatureException as e:
                self.config.app_log.warning(
                    'InvalidTransactionSignatureException: transaction removed'
                )
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason':
                    'InvalidTransactionSignatureException',
                    'txn':
                    transaction_obj.to_dict()
                })

            except InvalidTransactionException as e:
                self.config.app_log.warning(
                    'InvalidTransactionException: transaction removed')
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason':
                    'InvalidTransactionException',
                    'txn':
                    transaction_obj.to_dict()
                })

            except TransactionInputOutputMismatchException as e:
                self.config.app_log.warning(
                    'TransactionInputOutputMismatchException: transaction removed'
                )
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason':
                    'TransactionInputOutputMismatchException',
                    'txn':
                    transaction_obj.to_dict()
                })

            except TotalValueMismatchException as e:
                self.config.app_log.warning(
                    'TotalValueMismatchException: transaction removed')
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason':
                    'TotalValueMismatchException',
                    'txn':
                    transaction_obj.to_dict()
                })

            except Exception as e:
                self.config.app_log.warning(format_exc())
                self.mongo.db.miner_transactions.remove(
                    {'id': transaction_obj.transaction_signature})
                self.mongo.db.failed_transactions.insert({
                    'reason': 'Unhandled exception',
                    'error': format_exc()
                })

        return transaction_objs
Exemplo n.º 11
0
 async def get_payload_txn(self, payload):
     txn = None
     if payload.get('transaction'):
         txn = Transaction.from_dict(payload.get('transaction'))
     return txn
Exemplo n.º 12
0
    async def do_payout_for_blocks(self, blocks):
        # check if we already paid out
        outputs = {}
        coinbases = []
        for block in blocks:
            if self.config.debug:
                self.app_log.debug('do_payout_for_blocks begin loop {}'.format(
                    block.index))
            already_used = await self.already_used(block.get_coinbase())
            if already_used:
                await self.config.mongo.async_db.shares.delete_many(
                    {'index': block.index})
                continue

            if self.config.debug:
                self.app_log.debug(
                    'do_payout_for_blocks passed already_used {}'.format(
                        block.index))
            existing = await self.config.mongo.async_db.share_payout.find_one(
                {'index': block.index})
            if existing:
                pending = await self.config.mongo.async_db.miner_transactions.find_one(
                    {'inputs.id': block.get_coinbase().transaction_signature})
                if pending:
                    return
                else:
                    # rebroadcast
                    transaction = Transaction.from_dict(existing['txn'])
                    await self.config.mongo.async_db.miner_transactions.insert_one(
                        transaction.to_dict())
                    await self.broadcast_transaction(transaction)
                    return
            if self.config.debug:
                self.app_log.debug(
                    'do_payout_for_blocks passed existing {}'.format(
                        block.index))
            try:
                shares = await self.get_share_list_for_height(block.index)
                if not shares:
                    continue
            except KeyError as e:
                self.app_log.warning(e)
                return
            except Exception as e:
                self.app_log.warning(e)
                return
            if self.config.debug:
                self.app_log.debug(
                    'do_payout_for_blocks passed get_share_list_for_height {}'.
                    format(block.index))
            coinbase = block.get_coinbase()
            if coinbase.outputs[0].to != self.config.address:
                return
            if self.config.debug:
                self.app_log.debug(
                    'do_payout_for_blocks passed address compare {}'.format(
                        block.index))
            pool_take = self.config.pool_take
            total_pool_take = coinbase.outputs[0].value * pool_take
            total_payout = coinbase.outputs[0].value - total_pool_take
            coinbases.append(coinbase)
            if self.config.debug:
                self.app_log.debug(
                    'do_payout_for_blocks coinbases so far {}'.format(
                        coinbases))

            if self.config.debug:
                self.app_log.debug(
                    'do_payout_for_blocks passed coinbase calcs {}'.format(
                        block.index))
            for address, x in shares.items():
                if self.config.debug:
                    self.app_log.debug(
                        'do_payout_for_blocks shares loop {}'.format(
                            block.index))
                exists = await self.config.mongo.async_db.share_payout.find_one(
                    {
                        'index': block.index,
                        'txn.outputs.to': address
                    })
                if exists:
                    raise PartialPayoutException(
                        'this index has been partially paid out.')

                if self.config.debug:
                    self.app_log.debug(
                        'do_payout_for_blocks passed shares exists {}'.format(
                            block.index))
                if address not in outputs:
                    outputs[address] = 0.0
                payout = total_payout * x['payout_share']
                outputs[address] += payout
                if self.config.debug:
                    self.app_log.debug(
                        'do_payout_for_blocks passed adding payout to outputs {}'
                        .format(block.index))

        outputs_formatted = []
        for address, output in outputs.items():
            outputs_formatted.append({'to': address, 'value': output})
        if hasattr(self.config, 'pool_payout_address_override'
                   ) and self.config.pool_payout_address_override:
            outputs_formatted.append({
                'to': self.config.pool_payout_address_override,
                'value': total_pool_take
            })
        if self.config.debug:
            self.app_log.debug(
                'do_payout_for_blocks done formatting outputs {}'.format([{
                    'id':
                    coinbase.transaction_signature
                } for coinbase in coinbases]))
        try:
            transaction = await Transaction.generate(
                fee=0.0001,
                public_key=self.config.public_key,
                private_key=self.config.private_key,
                inputs=[{
                    'id': coinbase.transaction_signature
                } for coinbase in coinbases],
                outputs=outputs_formatted,
            )
            self.app_log.debug("transaction generated: {}".format(
                transaction.transaction_signature))
        except NotEnoughMoneyException as e:
            if self.config.debug:
                self.app_log.debug("not enough money yet")
                self.app_log.debug(e)
            return
        except Exception as e:
            if self.config.debug:
                self.app_log.debug(e)

        try:
            await transaction.verify()
        except Exception as e:
            if self.config.debug:
                self.app_log.debug(e)
            raise
        self.app_log.debug('transaction verified')
        await self.config.mongo.async_db.miner_transactions.insert_one(
            transaction.to_dict())
        await self.config.mongo.async_db.share_payout.insert_one({
            'index':
            block.index,
            'txn':
            transaction.to_dict()
        })
Exemplo n.º 13
0
    async def route(self, body):
        # our peer SHOULD only ever been a service provider if we're offering a websocket but we'll give other options here
        params = body.get('params')
        transaction = Transaction.from_dict(params['transaction'])
        await self.config.mongo.async_db.miner_transactions.replace_one(
            {'id': transaction.transaction_signature},
            transaction.to_dict(),
            upsert=True)
        if isinstance(self.config.peer, Seed):
            pass
            # for rid, peer_stream in self.config.nodeServer.inbound_streams[Seed.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

            # for rid, peer_stream in self.config.nodeServer.inbound_streams[SeedGateway.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

            # for rid, peer_stream in self.config.nodeClient.outbound_streams[Seed.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

        elif isinstance(self.config.peer, SeedGateway):
            pass
            # for rid, peer_stream in self.config.nodeServer.inbound_streams[ServiceProvider.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

            # for rid, peer_stream in self.config.nodeClient.outbound_streams[Seed.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

        elif isinstance(self.config.peer, ServiceProvider):
            pass
            # for rid, peer_stream in self.config.nodeServer.inbound_streams[User.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

            # for rid, peer_stream in self.config.nodeClient.outbound_streams[SeedGateway.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

            if transaction.requested_rid in self.config.websocketServer.inbound_streams[
                    Group.__name__]:
                for rid, peer_stream in self.config.websocketServer.inbound_streams[
                        Group.__name__][transaction.requested_rid].items():
                    if rid == transaction.requester_rid:
                        continue
                    await peer_stream.write_params('route', params)

            if transaction.requested_rid in self.config.websocketServer.inbound_streams[
                    User.__name__]:
                peer_stream = self.config.websocketServer.inbound_streams[
                    User.__name__][transaction.requested_rid]
                if peer_stream.peer.rid != transaction.requester_rid:
                    await peer_stream.write_params('route', params)

            if 'group' in params:
                group = Group.from_dict({
                    'host': None,
                    'port': None,
                    'identity': params['group']
                })
                params2 = params.copy()
                to = User.from_dict({
                    'host': None,
                    'port': None,
                    'identity': params['to']
                })
                peer_stream = self.config.websocketServer.inbound_streams[
                    Group.__name__][group.rid].get(to.rid)
                if peer_stream:
                    await peer_stream.write_params('route', params2)

        elif isinstance(self.config.peer, User):
            pass
            # for rid, peer_stream in self.config.nodeClient.outbound_streams[ServiceProvider.__name__].items():
            #     await BaseRPC().write_params(peer_stream, 'route', params)

        else:
            self.config.app_log.error(
                'inbound peer is not defined, disconnecting')
            self.close()
            return {}
        await self.write_result('route_server_confirm', {}, body=body)