Source code for microraiden.proxy.resources.management

from flask_restful import Resource, reqparse
from collections import defaultdict

from microraiden.utils import sign_close
from microraiden.proxy.resources.login import auth
from eth_utils import encode_hex, is_address, to_checksum_address

from microraiden.channel_manager import Channel, ChannelManager
from microraiden.exceptions import NoOpenChannel, InvalidBalanceProof


[docs]class ChannelManagementRoot(Resource):
[docs] @staticmethod def get(): return "OK"
[docs]class ChannelManagementStats(Resource): def __init__(self, channel_manager: ChannelManager): super(ChannelManagementStats, self).__init__() self.channel_manager = channel_manager
[docs] def get(self): deposit_sum = sum([c.deposit for c in self.channel_manager.channels.values()]) unique_senders = {} open_channels = [] pending_channels = [] for k, v in self.channel_manager.channels.items(): unique_senders[k[0]] = 1 if v.is_closed is True: pending_channels.append(v) else: open_channels.append(v) contract_address = self.channel_manager.channel_manager_contract.address return {'balance_sum': self.channel_manager.get_locked_balance(), 'deposit_sum': deposit_sum, 'open_channels': len(open_channels), 'pending_channels': len(pending_channels), 'unique_senders': len(unique_senders), 'liquid_balance': self.channel_manager.get_liquid_balance(), 'token_address': self.channel_manager.token_contract.address, 'contract_address': contract_address, 'receiver_address': self.channel_manager.receiver, 'manager_abi': self.channel_manager.channel_manager_contract.abi, 'token_abi': self.channel_manager.token_contract.abi, 'sync_block': self.channel_manager.blockchain.sync_start_block }
[docs]class ChannelManagementListChannels(Resource): def __init__(self, channel_manager: ChannelManager): super(ChannelManagementListChannels, self).__init__() self.channel_manager = channel_manager
[docs] def get_all_channels(self, channel_status='all', condition=lambda k, v: True): return [ {'sender_address': k[0], 'open_block': k[1], 'state': self.get_channel_status(v), 'deposit': v.deposit, 'balance': v.balance} for k, v in self.channel_manager.channels.items() if (condition(k, v))]
[docs] def get_channel_filter(self, channel_status='all'): if channel_status == 'open' or channel_status == 'opened': return lambda c: c.is_closed is False elif channel_status == 'closed': return lambda c: c.is_closed is True else: return lambda c: True
[docs] def get_channel_status(self, channel: Channel): if channel.is_closed is True: return "closed" elif channel.is_closed is False: return "open" else: return "unknown"
[docs] def get(self, sender_address=None): parser = reqparse.RequestParser() parser.add_argument('status', help='filter channels by a status', default='open', choices=('closed', 'opened', 'open', 'all')) args = parser.parse_args() channel_filter = self.get_channel_filter(args['status']) # if sender exists, return all open blocks if sender_address is not None and is_address(sender_address): ret = self.get_all_channels( condition=lambda k, v: (k[0] == to_checksum_address(sender_address) and channel_filter(v)) ) # if sender is not specified, return all open channels else: channels = self.get_all_channels(condition=lambda k, v: channel_filter(v)) joined_channels = defaultdict(list) for c in channels: joined_channels[c['sender_address']].append(c['open_block']) ret = [ {'sender_address': k, 'blocks': v } for k, v in joined_channels.items() ] return ret, 200
[docs] def delete(self, sender_address): parser = reqparse.RequestParser() parser.add_argument('open_block', type=int, help='block the channel was opened') parser.add_argument('signature', help='last balance proof signature') args = parser.parse_args() if args.signature is None: return "Bad signature format", 400 if args.block is None: return "No opening block specified", 400 if sender_address and is_address(sender_address): sender_address = to_checksum_address(sender_address) channel = self.channel_manager.channels[sender_address, args.block] if channel.last_signature != args.signature: return "Invalid or outdated balance signature", 400 ret = sign_close(self.channel_manager.private_key, args.signature) return ret, 200
[docs]class ChannelManagementChannelInfo(Resource): def __init__(self, channel_manager): super(ChannelManagementChannelInfo, self).__init__() self.channel_manager = channel_manager
[docs] def get(self, sender_address, opening_block): if sender_address and is_address(sender_address): sender_address = to_checksum_address(sender_address) try: key = (sender_address, opening_block) sender_channel = self.channel_manager.channels[key] except KeyError: return "Sender address not found", 404 return sender_channel.to_dict(), 200
[docs] def delete(self, sender_address, opening_block): parser = reqparse.RequestParser() parser.add_argument('balance', type=int, help='last balance proof balance') args = parser.parse_args() if args.balance is None: return "Bad balance format", 400 if sender_address and is_address(sender_address): sender_address = to_checksum_address(sender_address) try: close_signature = self.channel_manager.sign_close( sender_address, opening_block, args.balance) except (NoOpenChannel, InvalidBalanceProof) as e: return str(e), 400 except KeyError: return "Channel not found", 404 ret = {'close_signature': encode_hex(close_signature)} return ret, 200
[docs]class ChannelManagementAdminChannels(Resource): def __init__(self, channel_manager): super(ChannelManagementAdminChannels, self).__init__() self.channel_manager = channel_manager
[docs] @auth.login_required def delete(self, sender_address, opening_block): if sender_address and is_address(sender_address): sender_address = to_checksum_address(sender_address) self.channel_manager.force_close_channel(sender_address, opening_block) return "force closed (%s, %d)" % (sender_address, opening_block), 200
[docs]class ChannelManagementAdmin(Resource): def __init__(self, channel_manager): super(ChannelManagementAdmin, self).__init__() self.channel_manager = channel_manager
[docs] @auth.login_required def get(self): return "NOTHING TO SEE HERE, GO AWAY", 200