Exemple #1
0
    def __init__(self, main_window, exctype, value, tb):
        BaseCrashReporter.__init__(self, exctype, value, tb)
        self.main_window = main_window

        QWidget.__init__(self)
        self.setWindowTitle('Electrum - ' + _('An Error Occurred'))
        self.setMinimumSize(600, 300)

        Logger.__init__(self)

        main_box = QVBoxLayout()

        heading = QLabel('<h2>' + BaseCrashReporter.CRASH_TITLE + '</h2>')
        main_box.addWidget(heading)
        main_box.addWidget(QLabel(BaseCrashReporter.CRASH_MESSAGE))

        main_box.addWidget(QLabel(BaseCrashReporter.REQUEST_HELP_MESSAGE))

        collapse_info = QPushButton(_("Show report contents"))
        # FIXME if traceback contains special HTML characters, e.g. '<'
        #       then formatting issues arise (due to rich_text=True)
        collapse_info.clicked.connect(
            lambda: self.msg_box(QMessageBox.NoIcon,
                                 self,
                                 _("Report contents"),
                                 self.get_report_string(),
                                 rich_text=True))

        main_box.addWidget(collapse_info)

        main_box.addWidget(QLabel(BaseCrashReporter.DESCRIBE_ERROR_MESSAGE))

        self.description_textfield = QTextEdit()
        self.description_textfield.setFixedHeight(50)
        self.description_textfield.setPlaceholderText(
            _("Do not enter sensitive/private information here. "
              "The report will be visible on the public issue tracker."))
        main_box.addWidget(self.description_textfield)

        main_box.addWidget(QLabel(BaseCrashReporter.ASK_CONFIRM_SEND))

        buttons = QHBoxLayout()

        report_button = QPushButton(_('Send Bug Report'))
        report_button.clicked.connect(self.send_report)
        report_button.setIcon(read_QIcon("tab_send.png"))
        buttons.addWidget(report_button)

        never_button = QPushButton(_('Never'))
        never_button.clicked.connect(self.show_never)
        buttons.addWidget(never_button)

        close_button = QPushButton(_('Not Now'))
        close_button.clicked.connect(self.close)
        buttons.addWidget(close_button)

        main_box.addLayout(buttons)

        self.setLayout(main_box)
        self.show()
Exemple #2
0
 def __init__(self,
              user_agent=None,
              base_url='https://api.trustedcoin.com/2/'):
     self.base_url = base_url
     self.debug = False
     self.user_agent = user_agent
     Logger.__init__(self)
Exemple #3
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
Exemple #4
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
Exemple #5
0
 def __init__(self, *, local_keypair: Keypair, chans: Iterable['Channel'],
              tx_queue):
     Logger.__init__(self)
     NetworkRetryManager.__init__(self,
                                  max_retry_delay_normal=1,
                                  init_retry_delay_normal=1)
     self.node_keypair = local_keypair
     self.network = MockNetwork(tx_queue)
     self.channel_db = self.network.channel_db
     self._channels = {chan.channel_id: chan for chan in chans}
     self.payments = {}
     self.logs = defaultdict(list)
     self.wallet = MockWallet()
     self.features = LnFeatures(0)
     self.features |= LnFeatures.OPTION_DATA_LOSS_PROTECT_OPT
     self.features |= LnFeatures.OPTION_UPFRONT_SHUTDOWN_SCRIPT_OPT
     self.pending_payments = defaultdict(asyncio.Future)
     for chan in chans:
         chan.lnworker = self
     self._peers = {}  # bytes -> Peer
     # used in tests
     self.enable_htlc_settle = asyncio.Event()
     self.enable_htlc_settle.set()
     self.received_htlcs = defaultdict(set)
     self.sent_htlcs = defaultdict(asyncio.Queue)
     self.htlc_routes = defaultdict(list)
Exemple #6
0
 def __init__(self, parent: 'ElectrumWindow'):
     CustomModel.__init__(self, parent, len(HistoryColumns))
     Logger.__init__(self)
     self.parent = parent
     self.view = None  # type: HistoryList
     self.transactions = OrderedDictWithIndex()
     self.tx_status_cache = {}  # type: Dict[str, Tuple[int, str]]
 def __init__(self, parent: 'ElectrumWindow'):
     QAbstractItemModel.__init__(self, parent)
     Logger.__init__(self)
     self.parent = parent
     self.view = None  # type: TokenHistoryList
     self.transactions = OrderedDictWithIndex()
     self.tx_status_cache = {}  # type: Dict[str, Tuple[int, str]]
 def __init__(self, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'):
     Logger.__init__(self)
     self.logger.debug('ElectrumGUI: initialising')
     self.daemon = daemon
     self.network = daemon.network
     self.config = config
     self.plugins = plugins
 def __init__(self, main_window, *args, **kwargs):
     QObject.__init__(self, *args, **kwargs)
     Logger.__init__(self)
     if not main_window.config.get(BaseCrashReporter.config_key, default=True):
         return
     self.main_window = main_window
     sys.excepthook = self.handler
     self._report_exception.connect(_show_window)
Exemple #10
0
 def __init__(self, parent):
     QAbstractItemModel.__init__(self, parent)
     Logger.__init__(self)
     self.parent = parent
     self.view = None  # type: HistoryList
     self.transactions = OrderedDictWithIndex()
     self.tx_status_cache = {}  # type: Dict[str, Tuple[int, str]]
     self.summary = None
Exemple #11
0
 def __init__(self, chan: AbstractChannel, app: 'ElectrumWindow', **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.state = chan.get_state_for_GUI()
     self.title = _('Channel Backup')
Exemple #12
0
    def __init__(self, config: 'SimpleConfig', exctype, value, tb):
        BaseCrashReporter.__init__(self, exctype, value, tb)
        self.network = Network.get_instance()
        self.config = config

        QWidget.__init__(self)
        self.setWindowTitle('Electrum - ' + _('An Error Occurred'))
        self.setMinimumSize(600, 300)

        Logger.__init__(self)

        main_box = QVBoxLayout()

        heading = QLabel('<h2>' + BaseCrashReporter.CRASH_TITLE + '</h2>')
        main_box.addWidget(heading)
        main_box.addWidget(QLabel(BaseCrashReporter.CRASH_MESSAGE))

        main_box.addWidget(QLabel(BaseCrashReporter.REQUEST_HELP_MESSAGE))

        collapse_info = QPushButton(_("Show report contents"))
        collapse_info.clicked.connect(
            lambda: self.msg_box(QMessageBox.NoIcon,
                                 self,
                                 _("Report contents"),
                                 self.get_report_string(),
                                 rich_text=True))

        main_box.addWidget(collapse_info)

        main_box.addWidget(QLabel(BaseCrashReporter.DESCRIBE_ERROR_MESSAGE))

        self.description_textfield = QTextEdit()
        self.description_textfield.setFixedHeight(50)
        self.description_textfield.setPlaceholderText(
            self.USER_COMMENT_PLACEHOLDER)
        main_box.addWidget(self.description_textfield)

        main_box.addWidget(QLabel(BaseCrashReporter.ASK_CONFIRM_SEND))

        buttons = QHBoxLayout()

        report_button = QPushButton(_('Send Bug Report'))
        report_button.clicked.connect(self.send_report)
        report_button.setIcon(read_QIcon("tab_send.png"))
        buttons.addWidget(report_button)

        never_button = QPushButton(_('Never'))
        never_button.clicked.connect(self.show_never)
        buttons.addWidget(never_button)

        close_button = QPushButton(_('Not Now'))
        close_button.clicked.connect(self.close)
        buttons.addWidget(close_button)

        main_box.addLayout(buttons)

        self.setLayout(main_box)
        self.show()
Exemple #13
0
    def __init__(self, *, config: 'SimpleConfig'):
        QObject.__init__(self)
        Logger.__init__(self)
        assert self._INSTANCE is None, "Exception_Hook is supposed to be a singleton"
        self.config = config
        self.wallet_types_seen = set()  # type: Set[str]

        sys.excepthook = self.handler
        self._report_exception.connect(_show_window)
 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')
Exemple #15
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')
 def __init__(self, *, config: 'SimpleConfig', daemon: 'Daemon',
              plugins: 'Plugins'):
     BaseElectrumGui.__init__(self,
                              config=config,
                              daemon=daemon,
                              plugins=plugins)
     Logger.__init__(self)
     self.logger.debug('ElectrumGUI: initialising')
     self.network = daemon.network
 def __init__(self, main_window):
     base.ExceptionHandler.__init__(self)
     Logger.__init__(self)
     self.main_window = main_window
     if not main_window.electrum_config.get(BaseCrashReporter.config_key, default=True):
         return
     # For exceptions in Kivy:
     base.ExceptionManager.add_handler(self)
     # For everything else:
     sys.excepthook = lambda exctype, value, tb: self.handle_exception(value)
Exemple #18
0
 def __init__(self, text="", allow_multi=False, *, config: SimpleConfig):
     ButtonsTextEdit.__init__(self, text)
     Logger.__init__(self)
     self.allow_multi = allow_multi
     self.config = config
     self.setReadOnly(False)
     self.addButton("file.png", self.file_input, _("Read file"))
     icon = "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png"
     self.addButton(icon, self.qr_input, _("Read QR code"))
     run_hook('scan_text_edit', self)
Exemple #19
0
 def __init__(self, imap_server, username, password, callback):
     threading.Thread.__init__(self)
     Logger.__init__(self)
     self.daemon = True
     self.username = username
     self.password = password
     self.imap_server = imap_server
     self.on_receive = callback
     self.M = None
     self.reset_connect_wait()
Exemple #20
0
 def __init__(self, main_window):
     base.ExceptionHandler.__init__(self)
     Logger.__init__(self)
     self.main_window = main_window
     if not main_window.electrum_config.get(BaseCrashReporter.config_key, default=True):
         return
     # For exceptions in Kivy:
     base.ExceptionManager.add_handler(self)
     # For everything else:
     sys.excepthook = lambda exctype, value, tb: self.handle_exception(value)
 def __init__(self, handler, plugin, proto):
     assert hasattr(self, 'tx_api')  # ProtocolMixin already constructed?
     self.proto = proto
     self.device = plugin.device
     self.handler = handler
     self.tx_api = plugin
     self.types = plugin.types
     self.msg = None
     self.creating_wallet = False
     Logger.__init__(self)
     self.used()
Exemple #22
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')
Exemple #23
0
    def __init__(self, transport, handler, plugin):
        self.client = TrezorClient(transport, ui=self)
        self.plugin = plugin
        self.device = plugin.device
        self.handler = handler
        Logger.__init__(self)

        self.msg = None
        self.creating_wallet = False

        self.in_flow = False

        self.used()
Exemple #24
0
 def __init__(self, app, lnaddr=None, msg=None):
     Factory.Popup.__init__(self)
     Logger.__init__(self)
     self.app = app  # type: ElectrumWindow
     self.lnaddr = lnaddr
     self.msg = msg
     self.use_gossip = bool(self.app.network.channel_db)
     if not self.use_gossip:
         from electrum.lnworker import hardcoded_trampoline_nodes
         self.trampolines = hardcoded_trampoline_nodes()
         self.trampoline_names = list(self.trampolines.keys())
         self.trampoline_index = 0
         self.pubkey = ''
Exemple #25
0
    def __init__(self, *, config: 'SimpleConfig', daemon: 'Daemon',
                 plugins: 'Plugins'):
        set_language(config.get('language', get_default_language()))
        BaseElectrumGui.__init__(self,
                                 config=config,
                                 daemon=daemon,
                                 plugins=plugins)
        Logger.__init__(self)
        self.logger.info(
            f"Qt GUI starting up... Qt={QtCore.QT_VERSION_STR}, PyQt={QtCore.PYQT_VERSION_STR}"
        )
        # Uncomment this call to verify objects are being properly
        # GC-ed when windows are closed
        #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer,
        #                            ElectrumWindow], interval=5)])
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
        if hasattr(QtCore.Qt, "AA_ShareOpenGLContexts"):
            QtCore.QCoreApplication.setAttribute(
                QtCore.Qt.AA_ShareOpenGLContexts)
        if hasattr(QGuiApplication, 'setDesktopFileName'):
            QGuiApplication.setDesktopFileName('electrum.desktop')
        self.gui_thread = threading.current_thread()
        self.windows = []  # type: List[ElectrumWindow]
        self.efilter = OpenFileEventFilter(self.windows)
        self.app = QElectrumApplication(sys.argv)
        self.app.installEventFilter(self.efilter)
        self.app.setWindowIcon(read_QIcon("electrum.png"))
        self._cleaned_up = False
        # timer
        self.timer = QTimer(self.app)
        self.timer.setSingleShot(False)
        self.timer.setInterval(500)  # msec

        self.network_dialog = None
        self.lightning_dialog = None
        self.watchtower_dialog = None
        self.network_updated_signal_obj = QNetworkUpdatedSignalObject()
        self._num_wizards_in_progress = 0
        self._num_wizards_lock = threading.Lock()
        self.dark_icon = self.config.get("dark_icon", False)
        self.tray = None
        self._init_tray()
        self.app.new_window_signal.connect(self.start_new_window)
        self.app.quit_signal.connect(self.app.quit, Qt.QueuedConnection)
        # maybe set dark theme
        self._default_qtstylesheet = self.app.styleSheet()
        self.reload_app_stylesheet()

        run_hook('init_qt', self)
    def __init__(self, transport, handler, plugin):
        if plugin.is_outdated_fw_ignored():
            TrezorClient.is_outdated = lambda *args, **kwargs: False
        self.client = TrezorClient(transport, ui=self)
        self.plugin = plugin
        self.device = plugin.device
        self.handler = handler
        Logger.__init__(self)

        self.msg = None
        self.creating_wallet = False

        self.in_flow = False

        self.used()
Exemple #27
0
 def __init__(self, win, device):
     QObject.__init__(self)
     Logger.__init__(self)
     self.clear_signal.connect(self.clear_dialog)
     self.error_signal.connect(self.error_dialog)
     self.message_signal.connect(self.message_dialog)
     self.passphrase_signal.connect(self.passphrase_dialog)
     self.word_signal.connect(self.word_dialog)
     self.query_signal.connect(self.win_query_choice)
     self.yes_no_signal.connect(self.win_yes_no_question)
     self.status_signal.connect(self._update_status)
     self.win = win
     self.device = device
     self.dialog = None
     self.done = threading.Event()
Exemple #28
0
    def __init__(self, config, daemon, plugins):
        set_language(config.get('language', get_default_language()))
        Logger.__init__(self)
        # Uncomment this call to verify objects are being properly
        # GC-ed when windows are closed
        #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer,
        #                            ElectrumWindow], interval=5)])
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
        if hasattr(QtCore.Qt, "AA_ShareOpenGLContexts"):
            QtCore.QCoreApplication.setAttribute(
                QtCore.Qt.AA_ShareOpenGLContexts)
        if hasattr(QGuiApplication, 'setDesktopFileName'):
            QGuiApplication.setDesktopFileName('electrum.desktop')
        self.gui_thread = threading.current_thread()
        self.config = config
        self.daemon = daemon
        self.plugins = plugins
        self.windows = []
        self.efilter = OpenFileEventFilter(self.windows)
        self.app = QElectrumApplication(sys.argv)
        #new_font = self.app.font();
        #new_font.setPointSize(13)
        #self.app.setFont( new_font)
        self.app.installEventFilter(self.efilter)
        self.app.setWindowIcon(read_QIcon("electrum.png"))
        # timer
        self.timer = QTimer(self.app)
        self.timer.setSingleShot(False)
        self.timer.setInterval(500)  # msec

        self.password_timer = QTimer(self.app)
        self.password_timer.setSingleShot(False)
        self.password_timer.setInterval(300000)

        self.nd = None
        self.network_updated_signal_obj = QNetworkUpdatedSignalObject()
        self._num_wizards_in_progress = 0
        self._num_wizards_lock = threading.Lock()
        # init tray
        self.dark_icon = self.config.get("dark_icon", False)
        self.tray = QSystemTrayIcon(self.tray_icon(), None)
        self.tray.setToolTip('Electrum-Wagerr')
        self.tray.activated.connect(self.tray_activated)
        self.build_tray_menu()
        self.tray.show()
        self.app.new_window_signal.connect(self.start_new_window)
        self.set_dark_theme_if_needed()
        run_hook('init_qt', self)
Exemple #29
0
    def __init__(self, config: 'SimpleConfig', daemon: 'Daemon',
                 plugins: 'Plugins'):
        set_language(config.get('language', get_default_language()))
        Logger.__init__(self)
        self.logger.info(
            f"Qt GUI starting up... Qt={QtCore.QT_VERSION_STR}, PyQt={QtCore.PYQT_VERSION_STR}"
        )
        # Uncomment this call to verify objects are being properly
        # GC-ed when windows are closed
        #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer,
        #                            ElectrumWindow], interval=5)])
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
        if hasattr(QtCore.Qt, "AA_ShareOpenGLContexts"):
            QtCore.QCoreApplication.setAttribute(
                QtCore.Qt.AA_ShareOpenGLContexts)
        if hasattr(QGuiApplication, 'setDesktopFileName'):
            QGuiApplication.setDesktopFileName('electrum.desktop')
        self.gui_thread = threading.current_thread()
        self.config = config
        self.daemon = daemon
        self.plugins = plugins
        self.windows = []  # type: List[ElectrumWindow]
        self.efilter = OpenFileEventFilter(self.windows)
        self.app = QElectrumApplication(sys.argv)
        self.app.installEventFilter(self.efilter)
        self.app.setWindowIcon(read_QIcon("electrum.png"))
        # timer
        self.timer = QTimer(self.app)
        self.timer.setSingleShot(False)
        self.timer.setInterval(500)  # msec

        self.network_dialog = None
        self.lightning_dialog = None
        self.watchtower_dialog = None
        self.network_updated_signal_obj = QNetworkUpdatedSignalObject()
        self._num_wizards_in_progress = 0
        self._num_wizards_lock = threading.Lock()
        # init tray
        self.dark_icon = self.config.get("dark_icon", False)
        self.tray = QSystemTrayIcon(self.tray_icon(), None)
        self.tray.setToolTip(
            'Electrum ({name})'.format(name=constants.net.NAME))
        self.tray.activated.connect(self.tray_activated)
        self.build_tray_menu()
        self.tray.show()
        self.app.new_window_signal.connect(self.start_new_window)
        self.set_dark_theme_if_needed()
        run_hook('init_qt', self)
Exemple #30
0
 def __init__(self, win: Union[ElectrumWindow, InstallWizard], device: str):
     QObject.__init__(self)
     Logger.__init__(self)
     assert win.gui_thread == threading.current_thread(), 'must be called from GUI thread'
     self.clear_signal.connect(self.clear_dialog)
     self.error_signal.connect(self.error_dialog)
     self.message_signal.connect(self.message_dialog)
     self.passphrase_signal.connect(self.passphrase_dialog)
     self.word_signal.connect(self.word_dialog)
     self.query_signal.connect(self.win_query_choice)
     self.yes_no_signal.connect(self.win_yes_no_question)
     self.status_signal.connect(self._update_status)
     self.win = win
     self.device = device
     self.dialog = None
     self.done = threading.Event()
Exemple #31
0
 def __init__(self, remote_keypair, local_keypair, chan: 'Channel', tx_queue):
     Logger.__init__(self)
     self.remote_keypair = remote_keypair
     self.node_keypair = local_keypair
     self.network = MockNetwork(tx_queue)
     self.channels = {chan.channel_id: chan}
     self.payments = {}
     self.logs = defaultdict(list)
     self.wallet = MockWallet()
     self.localfeatures = LnLocalFeatures(0)
     self.localfeatures |= LnLocalFeatures.OPTION_DATA_LOSS_PROTECT_OPT
     self.pending_payments = defaultdict(asyncio.Future)
     chan.lnworker = self
     chan.node_id = remote_keypair.pubkey
     # used in tests
     self.enable_htlc_settle = asyncio.Event()
     self.enable_htlc_settle.set()