Beispiel #1
0
 def details(self):
     chan = self.chan
     return {
         _('Short Chan ID'):
         format_short_channel_id(chan.short_channel_id),
         _('Initiator'):
         'Local' if chan.constraints.is_initiator else 'Remote',
         _('State'):
         chan.get_state(),
         _('Local CTN'):
         chan.get_latest_ctn(LOCAL),
         _('Remote CTN'):
         chan.get_latest_ctn(REMOTE),
         _('Capacity'):
         self.app.format_amount_and_units(chan.constraints.capacity),
         _('Can send'):
         self.app.format_amount_and_units(
             chan.available_to_spend(LOCAL) // 1000),
         _('Current feerate'):
         str(chan.get_latest_feerate(LOCAL)),
         _('Node ID'):
         bh2u(chan.node_id),
         _('Channel ID'):
         bh2u(chan.channel_id),
         _('Funding TXID'):
         chan.funding_outpoint.txid,
     }
Beispiel #2
0
 def update_item(self, item):
     chan = item._chan
     item.status = chan.get_state()
     item.short_channel_id = format_short_channel_id(chan.short_channel_id)
     l, r = self.format_fields(chan)
     item.local_balance = _('Local') + ':' + l
     item.remote_balance = _('Remote') + ': ' + r
Beispiel #3
0
 def show_log(self, key, log):
     d = WindowModalDialog(self, _("Payment log"))
     vbox = QVBoxLayout(d)
     log_w = QTreeWidget()
     log_w.setHeaderLabels(
         [_('Route'),
          _('Channel ID'),
          _('Message'),
          _('Blacklist')])
     for i, (route, success, failure_log) in enumerate(log):
         route_str = '%d' % len(route)
         if not success:
             sender_idx, failure_msg, blacklist = failure_log
             short_channel_id = route[sender_idx + 1].short_channel_id
             data = failure_msg.data
             message = repr(failure_msg.code)
         else:
             short_channel_id = route[-1].short_channel_id
             message = _('Success')
             blacklist = False
         chan_str = format_short_channel_id(short_channel_id)
         x = QTreeWidgetItem(
             [route_str, chan_str, message,
              repr(blacklist)])
         log_w.addTopLevelItem(x)
     vbox.addWidget(log_w)
     vbox.addLayout(Buttons(CloseButton(d)))
     d.exec_()
 def __init__(self, chan: AbstractChannel, app: 'ElectrumWindow', **kwargs):
     super(ChannelBackupPopup,self).__init__(**kwargs)
     self.chan = chan
     self.app = app
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.state = chan.get_state_for_GUI()
     self.title = _('Channel Backup')
Beispiel #5
0
 def __init__(self, chan: Channel, app: 'ElectrumWindow', **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.is_closed = chan.is_closed()
     self.is_redeemed = chan.is_redeemed()
     self.app = app
     self.chan = chan
     self.title = _('Channel details')
     self.node_id = bh2u(chan.node_id)
     self.channel_id = bh2u(chan.channel_id)
     self.funding_txid = chan.funding_outpoint.txid
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.capacity = self.app.format_amount_and_units(
         chan.constraints.capacity)
     self.state = chan.get_state_for_GUI()
     self.local_ctn = chan.get_latest_ctn(LOCAL)
     self.remote_ctn = chan.get_latest_ctn(REMOTE)
     self.local_csv = chan.config[LOCAL].to_self_delay
     self.remote_csv = chan.config[REMOTE].to_self_delay
     self.initiator = 'Local' if chan.constraints.is_initiator else 'Remote'
     self.feerate = chan.get_latest_feerate(LOCAL)
     self.can_send = self.app.format_amount_and_units(
         chan.available_to_spend(LOCAL) // 1000)
     self.can_receive = self.app.format_amount_and_units(
         chan.available_to_spend(REMOTE) // 1000)
     self.is_open = chan.is_open()
     closed = chan.get_closing_height()
     if closed:
         self.closing_txid, closing_height, closing_timestamp = closed
Beispiel #6
0
 def __init__(self, chan, app, **kwargs):
     super(ChannelBackupPopup, self).__init__(**kwargs)
     self.chan = chan
     self.app = app
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.state = chan.get_state_for_GUI()
     self.title = _('Channel Backup')
Beispiel #7
0
 def format_fields(self, chan):
     labels = {}
     for subject in (REMOTE, LOCAL):
         bal_minus_htlcs = chan.balance_minus_outgoing_htlcs(subject)//1000
         label = self.parent.format_amount(bal_minus_htlcs)
         other = subject.inverted()
         bal_other = chan.balance(other)//1000
         bal_minus_htlcs_other = chan.balance_minus_outgoing_htlcs(other)//1000
         if bal_other != bal_minus_htlcs_other:
             label += ' (+' + self.parent.format_amount(bal_other - bal_minus_htlcs_other) + ')'
         labels[subject] = label
     status = chan.get_state_for_GUI()
     closed = chan.is_closed()
     if self.parent.network.is_lightning_running():
         node_info = self.lnworker.channel_db.get_node_info_for_node_id(chan.node_id)
         node_alias = (node_info.alias if node_info else '') or ''
     else:
         node_alias = ''
     return [
         format_short_channel_id(chan.short_channel_id),
         bh2u(chan.node_id),
         node_alias,
         '' if closed else labels[LOCAL],
         '' if closed else labels[REMOTE],
         status
     ]
Beispiel #8
0
 def __init__(self, chan: Channel, app: 'ElectrumWindow', **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.is_closed = chan.is_closed()
     self.can_be_deleted = chan.can_be_deleted()
     self.app = app
     self.chan = chan
     self.title = _('Channel details')
     self.node_id = bh2u(chan.node_id)
     self.channel_id = bh2u(chan.channel_id)
     self.funding_txid = chan.funding_outpoint.txid
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.capacity = self.app.format_amount_and_units(chan.get_capacity())
     self.state = chan.get_state_for_GUI()
     self.local_ctn = chan.get_latest_ctn(LOCAL)
     self.remote_ctn = chan.get_latest_ctn(REMOTE)
     self.local_csv = chan.config[LOCAL].to_self_delay
     self.remote_csv = chan.config[REMOTE].to_self_delay
     self.initiator = 'Local' if chan.constraints.is_initiator else 'Remote'
     feerate_kw = chan.get_latest_feerate(LOCAL)
     self.feerate = str(quantize_feerate(Transaction.satperbyte_from_satperkw(feerate_kw)))
     self.can_send = self.app.format_amount_and_units(chan.available_to_spend(LOCAL) // 1000)
     self.can_receive = self.app.format_amount_and_units(chan.available_to_spend(REMOTE) // 1000)
     self.is_open = chan.is_open()
     closed = chan.get_closing_height()
     if closed:
         self.closing_txid, closing_height, closing_timestamp = closed
     msg = ' '.join([
         _("Trampoline routing is enabled, but this channel is with a non-trampoline node."),
         _("This channel may still be used for receiving, but it is frozen for sending."),
         _("If you want to keep using this channel, you need to disable trampoline routing in your preferences."),
     ])
     self.warning = '' if self.app.wallet.lnworker.channel_db or self.app.wallet.lnworker.is_trampoline_peer(chan.node_id) else _('Warning') + ': ' + msg
 def update_item(self, item):
     chan = item._chan
     item.status = self.app.wallet.lnworker.get_channel_status(chan)
     item.short_channel_id = format_short_channel_id(chan.short_channel_id)
     l, r = self.format_fields(chan)
     item.local_balance = _('Local') + ':' + l
     item.remote_balance = _('Remote') + ': ' + r
     self.update_can_send()
Beispiel #10
0
 def __init__(self, chan: AbstractChannel, app, **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.chan = chan
     self.app = app
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.capacity = self.app.format_amount_and_units(chan.get_capacity())
     self.state = chan.get_state_for_GUI()
     self.title = _('Channel Backup')
Beispiel #11
0
 def __init__(self, chan: AbstractChannel, channels_list, **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.chan = chan
     self.channels_list = channels_list
     self.app = channels_list.app
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.state = chan.get_state_for_GUI()
     self.title = _('Channel Backup')
Beispiel #12
0
 def __init__(self, chan: AbstractChannel, app, **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.chan = chan
     self.is_funded = chan.get_state() == ChannelState.FUNDED
     self.can_be_deleted = chan.can_be_deleted()
     self.funding_txid = chan.funding_outpoint.txid
     self.app = app
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.capacity = self.app.format_amount_and_units(chan.get_capacity())
     self.state = chan.get_state_for_GUI()
     self.title = _('Channel Backup')
 def format_fields(self, chan):
     labels = {}
     for subject in (REMOTE, LOCAL):
         bal_minus_htlcs = chan.balance_minus_outgoing_htlcs(subject)//1000
         label = self.parent.format_amount(bal_minus_htlcs)
         other = subject.inverted()
         bal_other = chan.balance(other)//1000
         bal_minus_htlcs_other = chan.balance_minus_outgoing_htlcs(other)//1000
         if bal_other != bal_minus_htlcs_other:
             label += ' (+' + self.parent.format_amount(bal_other - bal_minus_htlcs_other) + ')'
         labels[subject] = label
     return [
         format_short_channel_id(chan.short_channel_id),
         bh2u(chan.node_id),
         labels[LOCAL],
         labels[REMOTE],
         chan.get_state()
     ]
Beispiel #14
0
 def __init__(self, chan: Channel, app: 'ElectrumWindow', **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.is_closed = chan.is_closed()
     self.can_be_deleted = chan.can_be_deleted()
     self.app = app
     self.chan = chan
     self.title = _('Channel details')
     self.node_id = bh2u(chan.node_id)
     self.channel_id = bh2u(chan.channel_id)
     self.funding_txid = chan.funding_outpoint.txid
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.capacity = self.app.format_amount_and_units(chan.get_capacity())
     self.state = chan.get_state_for_GUI()
     self.local_ctn = chan.get_latest_ctn(LOCAL)
     self.remote_ctn = chan.get_latest_ctn(REMOTE)
     self.local_csv = chan.config[LOCAL].to_self_delay
     self.remote_csv = chan.config[REMOTE].to_self_delay
     self.initiator = 'Local' if chan.constraints.is_initiator else 'Remote'
     feerate_kw = chan.get_latest_feerate(LOCAL)
     self.feerate = str(
         quantize_feerate(Transaction.satperbyte_from_satperkw(feerate_kw)))
     self.can_send = self.app.format_amount_and_units(
         chan.available_to_spend(LOCAL) // 1000)
     self.can_receive = self.app.format_amount_and_units(
         chan.available_to_spend(REMOTE) // 1000)
     self.is_open = chan.is_open()
     closed = chan.get_closing_height()
     if closed:
         self.closing_txid, closing_height, closing_timestamp = closed
     msg = messages.MSG_NON_TRAMPOLINE_CHANNEL_FROZEN_WITHOUT_GOSSIP
     self.warning = '' if self.app.wallet.lnworker.channel_db or self.app.wallet.lnworker.is_trampoline_peer(
         chan.node_id) else _('Warning') + ': ' + msg
     self.is_frozen_for_sending = chan.is_frozen_for_sending()
     self.is_frozen_for_receiving = chan.is_frozen_for_receiving()
     self.channel_type = chan.storage['channel_type'].name_minimal
     self.update_action_dropdown()
Beispiel #15
0
    def __init__(self, window: 'ElectrumWindow', chan_id: bytes):
        super().__init__(window)

        # initialize instance fields
        self.window = window
        chan = self.chan = window.wallet.lnworker.channels[chan_id]
        self.format = lambda msat: window.format_amount_and_units(msat / 1000)

        # connect signals with slots
        self.ln_payment_completed.connect(self.do_ln_payment_completed)
        self.htlc_added.connect(self.do_htlc_added)

        # register callbacks for updating
        window.network.register_callback(self.ln_payment_completed.emit,
                                         ['ln_payment_completed'])
        window.network.register_callback(self.htlc_added.emit, ['htlc_added'])

        # set attributes of QDialog
        self.setWindowTitle(_('Channel Details'))
        self.setMinimumSize(800, 400)

        # add layouts
        vbox = QtWidgets.QVBoxLayout(self)
        form_layout = QtWidgets.QFormLayout(None)
        vbox.addLayout(form_layout)

        # add form content
        form_layout.addRow(_('Node ID:'), SelectableLabel(bh2u(chan.node_id)))
        form_layout.addRow(_('Channel ID:'),
                           SelectableLabel(bh2u(chan.channel_id)))
        funding_label_text = f'<a href=click_destination>{chan.funding_outpoint.txid}</a>:{chan.funding_outpoint.output_index}'
        form_layout.addRow(_('Funding Outpoint:'),
                           LinkedLabel(funding_label_text, self.show_tx))
        form_layout.addRow(
            _('Short Channel ID:'),
            SelectableLabel(format_short_channel_id(chan.short_channel_id)))
        self.received_label = SelectableLabel()
        form_layout.addRow(_('Received (mSAT):'), self.received_label)
        self.sent_label = SelectableLabel()
        form_layout.addRow(_('Sent (mSAT):'), self.sent_label)
        self.htlc_minimum_msat = SelectableLabel(
            str(chan.config[REMOTE].htlc_minimum_msat))
        form_layout.addRow(_('Minimum HTLC value accepted by peer (mSAT):'),
                           self.htlc_minimum_msat)
        self.max_htlcs = SelectableLabel(
            str(chan.config[REMOTE].max_accepted_htlcs))
        form_layout.addRow(
            _('Maximum number of concurrent HTLCs accepted by peer:'),
            self.max_htlcs)
        self.max_htlc_value = SelectableLabel(
            self.window.format_amount_and_units(
                chan.config[REMOTE].max_htlc_value_in_flight_msat / 1000))
        form_layout.addRow(
            _('Maximum value of in-flight HTLCs accepted by peer:'),
            self.max_htlc_value)
        self.dust_limit = SelectableLabel(
            self.window.format_amount_and_units(
                chan.config[REMOTE].dust_limit_sat))
        form_layout.addRow(_('Remote dust limit:'), self.dust_limit)
        self.reserve = SelectableLabel(
            self.window.format_amount_and_units(
                chan.config[REMOTE].reserve_sat))
        form_layout.addRow(_('Remote channel reserve:'), self.reserve)

        # add htlc tree view to vbox (wouldn't scale correctly in QFormLayout)
        form_layout.addRow(_('Payments (HTLCs):'), None)
        w = QtWidgets.QTreeView(self)
        htlc_dict = chan.get_payments()
        w.setModel(self.make_model(htlc_dict))
        w.header().setSectionResizeMode(0,
                                        QtWidgets.QHeaderView.ResizeToContents)
        vbox.addWidget(w)
        vbox.addLayout(Buttons(CloseButton(self)))
        # initialize sent/received fields
        self.update_sent_received()