1# Copyright (C) 2018 The Electrum developers
2#
3# Permission is hereby granted, free of charge, to any person obtaining a copy
4# of this software and associated documentation files (the "Software"), to deal
5# in the Software without restriction, including without limitation the rights
6# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7# copies of the Software, and to permit persons to whom the Software is
8# furnished to do so, subject to the following conditions:
9#
10# The above copyright notice and this permission notice shall be included in
11# all copies or substantial portions of the Software.
12#
13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19# THE SOFTWARE.
20
21import os
22from collections import namedtuple, defaultdict
23import binascii
24import json
25from enum import IntEnum
26from typing import (Optional, Dict, List, Tuple, NamedTuple, Set, Callable,
27                    Iterable, Sequence, TYPE_CHECKING, Iterator, Union, Mapping)
28import time
29import threading
30from abc import ABC, abstractmethod
31import itertools
32
33from aiorpcx import NetAddress
34import attr
35
36from . import ecc
37from . import constants, util
38from .util import bfh, bh2u, chunks, TxMinedInfo
39from .invoices import PR_PAID
40from .bitcoin import redeem_script_to_address
41from .crypto import sha256, sha256d
42from .transaction import Transaction, PartialTransaction, TxInput
43from .logging import Logger
44from .lnonion import decode_onion_error, OnionFailureCode, OnionRoutingFailure
45from . import lnutil
46from .lnutil import (Outpoint, LocalConfig, RemoteConfig, Keypair, OnlyPubkeyKeypair, ChannelConstraints,
47                     get_per_commitment_secret_from_seed, secret_to_pubkey, derive_privkey, make_closing_tx,
48                     sign_and_get_sig_string, RevocationStore, derive_blinded_pubkey, Direction, derive_pubkey,
49                     make_htlc_tx_with_open_channel, make_commitment, make_received_htlc, make_offered_htlc,
50                     HTLC_TIMEOUT_WEIGHT, HTLC_SUCCESS_WEIGHT, extract_ctn_from_tx_and_chan, UpdateAddHtlc,
51                     funding_output_script, SENT, RECEIVED, LOCAL, REMOTE, HTLCOwner, make_commitment_outputs,
52                     ScriptHtlc, PaymentFailure, calc_fees_for_commitment_tx, RemoteMisbehaving, make_htlc_output_witness_script,
53                     ShortChannelID, map_htlcs_to_ctx_output_idxs, LNPeerAddr,
54                     fee_for_htlc_output, offered_htlc_trim_threshold_sat,
55                     received_htlc_trim_threshold_sat, make_commitment_output_to_remote_address)
56from .lnsweep import create_sweeptxs_for_our_ctx, create_sweeptxs_for_their_ctx
57from .lnsweep import create_sweeptx_for_their_revoked_htlc, SweepInfo
58from .lnhtlc import HTLCManager
59from .lnmsg import encode_msg, decode_msg
60from .address_synchronizer import TX_HEIGHT_LOCAL
61from .lnutil import CHANNEL_OPENING_TIMEOUT
62from .lnutil import ChannelBackupStorage, ImportedChannelBackupStorage, OnchainChannelBackupStorage
63from .lnutil import format_short_channel_id
64
65if TYPE_CHECKING:
66    from .lnworker import LNWallet
67    from .json_db import StoredDict
68    from .lnrouter import RouteEdge
69
70
71# lightning channel states
72# Note: these states are persisted by name (for a given channel) in the wallet file,
73#       so consider doing a wallet db upgrade when changing them.
74class ChannelState(IntEnum):
75    PREOPENING      = 0  # Initial negotiation. Channel will not be reestablished
76    OPENING         = 1  # Channel will be reestablished. (per BOLT2)
77                         #  - Funding node: has received funding_signed (can broadcast the funding tx)
78                         #  - Non-funding node: has sent the funding_signed message.
79    FUNDED          = 2  # Funding tx was mined (requires min_depth and tx verification)
80    OPEN            = 3  # both parties have sent funding_locked
81    SHUTDOWN        = 4  # shutdown has been sent.
82    CLOSING         = 5  # closing negotiation done. we have a fully signed tx.
83    FORCE_CLOSING   = 6  # we force-closed, and closing tx is unconfirmed. Note that if the
84                         # remote force-closes then we remain OPEN until it gets mined -
85                         # the server could be lying to us with a fake tx.
86    CLOSED          = 7  # closing tx has been mined
87    REDEEMED        = 8  # we can stop watching
88
89
90class PeerState(IntEnum):
91    DISCONNECTED   = 0
92    REESTABLISHING = 1
93    GOOD           = 2
94    BAD            = 3
95
96
97cs = ChannelState
98state_transitions = [
99    (cs.PREOPENING, cs.OPENING),
100    (cs.OPENING, cs.FUNDED),
101    (cs.FUNDED, cs.OPEN),
102    (cs.OPENING, cs.SHUTDOWN),
103    (cs.FUNDED, cs.SHUTDOWN),
104    (cs.OPEN, cs.SHUTDOWN),
105    (cs.SHUTDOWN, cs.SHUTDOWN),  # if we reestablish
106    (cs.SHUTDOWN, cs.CLOSING),
107    (cs.CLOSING, cs.CLOSING),
108    # we can force close almost any time
109    (cs.OPENING,  cs.FORCE_CLOSING),
110    (cs.FUNDED,   cs.FORCE_CLOSING),
111    (cs.OPEN,     cs.FORCE_CLOSING),
112    (cs.SHUTDOWN, cs.FORCE_CLOSING),
113    (cs.CLOSING,  cs.FORCE_CLOSING),
114    # we can get force closed almost any time
115    (cs.OPENING,  cs.CLOSED),
116    (cs.FUNDED,   cs.CLOSED),
117    (cs.OPEN,     cs.CLOSED),
118    (cs.SHUTDOWN, cs.CLOSED),
119    (cs.CLOSING,  cs.CLOSED),
120    #
121    (cs.FORCE_CLOSING, cs.FORCE_CLOSING),  # allow multiple attempts
122    (cs.FORCE_CLOSING, cs.CLOSED),
123    (cs.FORCE_CLOSING, cs.REDEEMED),
124    (cs.CLOSED, cs.REDEEMED),
125    (cs.OPENING, cs.REDEEMED),  # channel never funded (dropped from mempool)
126    (cs.PREOPENING, cs.REDEEMED),  # channel never funded
127]
128del cs  # delete as name is ambiguous without context
129
130
131class RevokeAndAck(NamedTuple):
132    per_commitment_secret: bytes
133    next_per_commitment_point: bytes
134
135
136class RemoteCtnTooFarInFuture(Exception): pass
137
138
139def htlcsum(htlcs: Iterable[UpdateAddHtlc]):
140    return sum([x.amount_msat for x in htlcs])
141
142
143class HTLCWithStatus(NamedTuple):
144    channel_id: bytes
145    htlc: UpdateAddHtlc
146    direction: Direction
147    status: str
148
149
150class AbstractChannel(Logger, ABC):
151    storage: Union['StoredDict', dict]
152    config: Dict[HTLCOwner, Union[LocalConfig, RemoteConfig]]
153    _sweep_info: Dict[str, Dict[str, 'SweepInfo']]
154    lnworker: Optional['LNWallet']
155    _fallback_sweep_address: str
156    channel_id: bytes
157    funding_outpoint: Outpoint
158    node_id: bytes  # note that it might not be the full 33 bytes; for OCB it is only the prefix
159    _state: ChannelState
160
161    def set_short_channel_id(self, short_id: ShortChannelID) -> None:
162        self.short_channel_id = short_id
163        self.storage["short_channel_id"] = short_id
164
165    def get_id_for_log(self) -> str:
166        scid = self.short_channel_id
167        if scid:
168            return str(scid)
169        return self.channel_id.hex()
170
171    def short_id_for_GUI(self) -> str:
172        return format_short_channel_id(self.short_channel_id)
173
174    def set_state(self, state: ChannelState) -> None:
175        """ set on-chain state """
176        old_state = self._state
177        if (old_state, state) not in state_transitions:
178            raise Exception(f"Transition not allowed: {old_state.name} -> {state.name}")
179        self.logger.debug(f'({self.get_id_for_log()}) Setting channel state: {old_state.name} -> {state.name}')
180        self._state = state
181        self.storage['state'] = self._state.name
182        if self.lnworker:
183            self.lnworker.channel_state_changed(self)
184
185    def get_state(self) -> ChannelState:
186        return self._state
187
188    def is_funded(self):
189        return self.get_state() >= ChannelState.FUNDED
190
191    def is_open(self):
192        return self.get_state() == ChannelState.OPEN
193
194    def is_closing(self):
195        return ChannelState.SHUTDOWN <= self.get_state() <= ChannelState.FORCE_CLOSING
196
197    def is_closed(self):
198        # the closing txid has been saved
199        return self.get_state() >= ChannelState.CLOSING
200
201    def is_redeemed(self):
202        return self.get_state() == ChannelState.REDEEMED
203
204    def save_funding_height(self, *, txid: str, height: int, timestamp: Optional[int]) -> None:
205        self.storage['funding_height'] = txid, height, timestamp
206
207    def get_funding_height(self):
208        return self.storage.get('funding_height')
209
210    def delete_funding_height(self):
211        self.storage.pop('funding_height', None)
212
213    def save_closing_height(self, *, txid: str, height: int, timestamp: Optional[int]) -> None:
214        self.storage['closing_height'] = txid, height, timestamp
215
216    def get_closing_height(self):
217        return self.storage.get('closing_height')
218
219    def delete_closing_height(self):
220        self.storage.pop('closing_height', None)
221
222    def create_sweeptxs_for_our_ctx(self, ctx):
223        return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address)
224
225    def create_sweeptxs_for_their_ctx(self, ctx):
226        return create_sweeptxs_for_their_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address)
227
228    def is_backup(self):
229        return False
230
231    def sweep_ctx(self, ctx: Transaction) -> Dict[str, SweepInfo]:
232        txid = ctx.txid()
233        if self._sweep_info.get(txid) is None:
234            our_sweep_info = self.create_sweeptxs_for_our_ctx(ctx)
235            their_sweep_info = self.create_sweeptxs_for_their_ctx(ctx)
236            if our_sweep_info is not None:
237                self._sweep_info[txid] = our_sweep_info
238                self.logger.info(f'we force closed')
239            elif their_sweep_info is not None:
240                self._sweep_info[txid] = their_sweep_info
241                self.logger.info(f'they force closed.')
242            else:
243                self._sweep_info[txid] = {}
244                self.logger.info(f'not sure who closed.')
245        return self._sweep_info[txid]
246
247    def update_onchain_state(self, *, funding_txid: str, funding_height: TxMinedInfo,
248                             closing_txid: str, closing_height: TxMinedInfo, keep_watching: bool) -> None:
249        # note: state transitions are irreversible, but
250        # save_funding_height, save_closing_height are reversible
251        if funding_height.height == TX_HEIGHT_LOCAL:
252            self.update_unfunded_state()
253        elif closing_height.height == TX_HEIGHT_LOCAL:
254            self.update_funded_state(funding_txid=funding_txid, funding_height=funding_height)
255        else:
256            self.update_closed_state(funding_txid=funding_txid,
257                                     funding_height=funding_height,
258                                     closing_txid=closing_txid,
259                                     closing_height=closing_height,
260                                     keep_watching=keep_watching)
261
262    def update_unfunded_state(self):
263        self.delete_funding_height()
264        self.delete_closing_height()
265        if self.get_state() in [ChannelState.PREOPENING, ChannelState.OPENING, ChannelState.FORCE_CLOSING] and self.lnworker:
266            if self.is_initiator():
267                # set channel state to REDEEMED so that it can be removed manually
268                # to protect ourselves against a server lying by omission,
269                # we check that funding_inputs have been double spent and deeply mined
270                inputs = self.storage.get('funding_inputs', [])
271                if not inputs:
272                    self.logger.info(f'channel funding inputs are not provided')
273                    self.set_state(ChannelState.REDEEMED)
274                for i in inputs:
275                    spender_txid = self.lnworker.wallet.db.get_spent_outpoint(*i)
276                    if spender_txid is None:
277                        continue
278                    if spender_txid != self.funding_outpoint.txid:
279                        tx_mined_height = self.lnworker.wallet.get_tx_height(spender_txid)
280                        if tx_mined_height.conf > lnutil.REDEEM_AFTER_DOUBLE_SPENT_DELAY:
281                            self.logger.info(f'channel is double spent {inputs}')
282                            self.set_state(ChannelState.REDEEMED)
283                            break
284            else:
285                now = int(time.time())
286                if now - self.storage.get('init_timestamp', 0) > CHANNEL_OPENING_TIMEOUT:
287                    self.lnworker.remove_channel(self.channel_id)
288
289    def update_funded_state(self, *, funding_txid: str, funding_height: TxMinedInfo) -> None:
290        self.save_funding_height(txid=funding_txid, height=funding_height.height, timestamp=funding_height.timestamp)
291        self.delete_closing_height()
292        if funding_height.conf>0:
293            self.set_short_channel_id(ShortChannelID.from_components(
294                funding_height.height, funding_height.txpos, self.funding_outpoint.output_index))
295        if self.get_state() == ChannelState.OPENING:
296            if self.is_funding_tx_mined(funding_height):
297                self.set_state(ChannelState.FUNDED)
298
299    def update_closed_state(self, *, funding_txid: str, funding_height: TxMinedInfo,
300                            closing_txid: str, closing_height: TxMinedInfo, keep_watching: bool) -> None:
301        self.save_funding_height(txid=funding_txid, height=funding_height.height, timestamp=funding_height.timestamp)
302        self.save_closing_height(txid=closing_txid, height=closing_height.height, timestamp=closing_height.timestamp)
303        if funding_height.conf>0:
304            self.set_short_channel_id(ShortChannelID.from_components(
305                funding_height.height, funding_height.txpos, self.funding_outpoint.output_index))
306        if self.get_state() < ChannelState.CLOSED:
307            conf = closing_height.conf
308            if conf > 0:
309                self.set_state(ChannelState.CLOSED)
310            else:
311                # we must not trust the server with unconfirmed transactions,
312                # because the state transition is irreversible. if the remote
313                # force closed, we remain OPEN until the closing tx is confirmed
314                self.unconfirmed_closing_txid = closing_txid
315                if self.lnworker:
316                    util.trigger_callback('channel', self.lnworker.wallet, self)
317
318        if self.get_state() == ChannelState.CLOSED and not keep_watching:
319            self.set_state(ChannelState.REDEEMED)
320
321    @property
322    def sweep_address(self) -> str:
323        # TODO: in case of unilateral close with pending HTLCs, this address will be reused
324        addr = None
325        if self.is_static_remotekey_enabled():
326            our_payment_pubkey = self.config[LOCAL].payment_basepoint.pubkey
327            addr = make_commitment_output_to_remote_address(our_payment_pubkey)
328        if addr is None:
329            addr = self._fallback_sweep_address
330        assert addr
331        if self.lnworker:
332            assert self.lnworker.wallet.is_mine(addr)
333        return addr
334
335    @abstractmethod
336    def is_initiator(self) -> bool:
337        pass
338
339    @abstractmethod
340    def is_funding_tx_mined(self, funding_height: TxMinedInfo) -> bool:
341        pass
342
343    @abstractmethod
344    def get_funding_address(self) -> str:
345        pass
346
347    def get_state_for_GUI(self) -> str:
348        cs = self.get_state()
349        if cs <= ChannelState.OPEN and self.unconfirmed_closing_txid:
350            return 'FORCE-CLOSING'
351        return cs.name
352
353    @abstractmethod
354    def get_oldest_unrevoked_ctn(self, subject: HTLCOwner) -> int:
355        pass
356
357    @abstractmethod
358    def included_htlcs(self, subject: HTLCOwner, direction: Direction, ctn: int = None) -> Sequence[UpdateAddHtlc]:
359        pass
360
361    @abstractmethod
362    def funding_txn_minimum_depth(self) -> int:
363        pass
364
365    @abstractmethod
366    def balance(self, whose: HTLCOwner, *, ctx_owner=HTLCOwner.LOCAL, ctn: int = None) -> int:
367        """This balance (in msat) only considers HTLCs that have been settled by ctn.
368        It disregards reserve, fees, and pending HTLCs (in both directions).
369        """
370        pass
371
372    @abstractmethod
373    def balance_minus_outgoing_htlcs(self, whose: HTLCOwner, *,
374                                     ctx_owner: HTLCOwner = HTLCOwner.LOCAL,
375                                     ctn: int = None) -> int:
376        """This balance (in msat), which includes the value of
377        pending outgoing HTLCs, is used in the UI.
378        """
379        pass
380
381    @abstractmethod
382    def is_frozen_for_sending(self) -> bool:
383        """Whether the user has marked this channel as frozen for sending.
384        Frozen channels are not supposed to be used for new outgoing payments.
385        (note that payment-forwarding ignores this option)
386        """
387        pass
388
389    @abstractmethod
390    def is_frozen_for_receiving(self) -> bool:
391        """Whether the user has marked this channel as frozen for receiving.
392        Frozen channels are not supposed to be used for new incoming payments.
393        (note that payment-forwarding ignores this option)
394        """
395        pass
396
397    @abstractmethod
398    def is_static_remotekey_enabled(self) -> bool:
399        pass
400
401    @abstractmethod
402    def get_local_pubkey(self) -> bytes:
403        """Returns our node ID."""
404        pass
405
406
407class ChannelBackup(AbstractChannel):
408    """
409    current capabilities:
410      - detect force close
411      - request force close
412      - sweep my ctx to_local
413    future:
414      - will need to sweep their ctx to_remote
415    """
416
417    def __init__(self, cb: ChannelBackupStorage, *, sweep_address=None, lnworker=None):
418        self.name = None
419        Logger.__init__(self)
420        self.cb = cb
421        self.is_imported = isinstance(self.cb, ImportedChannelBackupStorage)
422        self._sweep_info = {}
423        self._fallback_sweep_address = sweep_address
424        self.storage = {} # dummy storage
425        self._state = ChannelState.OPENING
426        self.node_id = cb.node_id if self.is_imported else cb.node_id_prefix
427        self.channel_id = cb.channel_id()
428        self.funding_outpoint = cb.funding_outpoint()
429        self.lnworker = lnworker
430        self.short_channel_id = None
431        self.config = {}
432        if self.is_imported:
433            self.init_config(cb)
434        self.unconfirmed_closing_txid = None # not a state, only for GUI
435
436    def init_config(self, cb):
437        self.config[LOCAL] = LocalConfig.from_seed(
438            channel_seed=cb.channel_seed,
439            to_self_delay=cb.local_delay,
440            # dummy values
441            static_remotekey=None,
442            dust_limit_sat=None,
443            max_htlc_value_in_flight_msat=None,
444            max_accepted_htlcs=None,
445            initial_msat=None,
446            reserve_sat=None,
447            funding_locked_received=False,
448            was_announced=False,
449            current_commitment_signature=None,
450            current_htlc_signatures=b'',
451            htlc_minimum_msat=1,
452            upfront_shutdown_script='')
453        self.config[REMOTE] = RemoteConfig(
454            # payment_basepoint needed to deobfuscate ctn in our_ctx
455            payment_basepoint=OnlyPubkeyKeypair(cb.remote_payment_pubkey),
456            # revocation_basepoint is used to claim to_local in our ctx
457            revocation_basepoint=OnlyPubkeyKeypair(cb.remote_revocation_pubkey),
458            to_self_delay=cb.remote_delay,
459            # dummy values
460            multisig_key=OnlyPubkeyKeypair(None),
461            htlc_basepoint=OnlyPubkeyKeypair(None),
462            delayed_basepoint=OnlyPubkeyKeypair(None),
463            dust_limit_sat=None,
464            max_htlc_value_in_flight_msat=None,
465            max_accepted_htlcs=None,
466            initial_msat = None,
467            reserve_sat = None,
468            htlc_minimum_msat=None,
469            next_per_commitment_point=None,
470            current_per_commitment_point=None,
471            upfront_shutdown_script='')
472
473    def can_be_deleted(self):
474        return self.is_imported or self.is_redeemed()
475
476    def get_capacity(self):
477        return self.lnworker.lnwatcher.get_tx_delta(self.funding_outpoint.txid, self.cb.funding_address)
478
479    def is_backup(self):
480        return True
481
482    def create_sweeptxs_for_their_ctx(self, ctx):
483        return {}
484
485    def create_sweeptxs_for_our_ctx(self, ctx):
486        if self.is_imported:
487            return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address)
488        else:
489            # backup from op_return
490            return {}
491
492    def get_funding_address(self):
493        return self.cb.funding_address
494
495    def is_initiator(self):
496        return self.cb.is_initiator
497
498    def get_oldest_unrevoked_ctn(self, who):
499        return -1
500
501    def included_htlcs(self, subject, direction, ctn=None):
502        return []
503
504    def funding_txn_minimum_depth(self):
505        return 1
506
507    def is_funding_tx_mined(self, funding_height):
508        return funding_height.conf > 1
509
510    def balance_minus_outgoing_htlcs(self, whose: HTLCOwner, *, ctx_owner: HTLCOwner = HTLCOwner.LOCAL, ctn: int = None):
511        return 0
512
513    def balance(self, whose: HTLCOwner, *, ctx_owner=HTLCOwner.LOCAL, ctn: int = None) -> int:
514        return 0
515
516    def is_frozen_for_sending(self) -> bool:
517        return False
518
519    def is_frozen_for_receiving(self) -> bool:
520        return False
521
522    def is_static_remotekey_enabled(self) -> bool:
523        # Return False so that self.sweep_address will return self._fallback_sweep_address
524        # Since channel backups do not save the static_remotekey, payment_basepoint in
525        # their local config is not static)
526        return False
527
528    def get_local_pubkey(self) -> bytes:
529        cb = self.cb
530        assert isinstance(cb, ChannelBackupStorage)
531        if isinstance(cb, ImportedChannelBackupStorage):
532            return ecc.ECPrivkey(cb.privkey).get_public_key_bytes(compressed=True)
533        if isinstance(cb, OnchainChannelBackupStorage):
534            return self.lnworker.node_keypair.pubkey
535        raise NotImplementedError(f"unexpected cb type: {type(cb)}")
536
537
538class Channel(AbstractChannel):
539    # note: try to avoid naming ctns/ctxs/etc as "current" and "pending".
540    #       they are ambiguous. Use "oldest_unrevoked" or "latest" or "next".
541    #       TODO enforce this ^
542
543    # our forwarding parameters for forwarding HTLCs through this channel
544    forwarding_cltv_expiry_delta = 144
545    forwarding_fee_base_msat = 1000
546    forwarding_fee_proportional_millionths = 1
547
548    def __init__(self, state: 'StoredDict', *, sweep_address=None, name=None, lnworker=None, initial_feerate=None):
549        self.name = name
550        Logger.__init__(self)
551        self.lnworker = lnworker
552        self._fallback_sweep_address = sweep_address
553        self.storage = state
554        self.db_lock = self.storage.db.lock if self.storage.db else threading.RLock()
555        self.config = {}
556        self.config[LOCAL] = state["local_config"]
557        self.config[REMOTE] = state["remote_config"]
558        self.channel_id = bfh(state["channel_id"])
559        self.constraints = state["constraints"]  # type: ChannelConstraints
560        self.funding_outpoint = state["funding_outpoint"]
561        self.node_id = bfh(state["node_id"])
562        self.short_channel_id = ShortChannelID.normalize(state["short_channel_id"])
563        self.onion_keys = state['onion_keys']  # type: Dict[int, bytes]
564        self.data_loss_protect_remote_pcp = state['data_loss_protect_remote_pcp']
565        self.hm = HTLCManager(log=state['log'], initial_feerate=initial_feerate)
566        self._state = ChannelState[state['state']]
567        self.peer_state = PeerState.DISCONNECTED
568        self._sweep_info = {}
569        self._outgoing_channel_update = None  # type: Optional[bytes]
570        self._chan_ann_without_sigs = None  # type: Optional[bytes]
571        self.revocation_store = RevocationStore(state["revocation_store"])
572        self._can_send_ctx_updates = True  # type: bool
573        self._receive_fail_reasons = {}  # type: Dict[int, (bytes, OnionRoutingFailure)]
574        self.should_request_force_close = False
575        self.unconfirmed_closing_txid = None # not a state, only for GUI
576
577    def has_onchain_backup(self):
578        return self.storage.get('has_onchain_backup', False)
579
580    def can_be_deleted(self):
581        return self.is_redeemed()
582
583    def get_capacity(self):
584        return self.constraints.capacity
585
586    def is_initiator(self):
587        return self.constraints.is_initiator
588
589    def is_active(self):
590        return self.get_state() == ChannelState.OPEN and self.peer_state == PeerState.GOOD
591
592    def funding_txn_minimum_depth(self):
593        return self.constraints.funding_txn_minimum_depth
594
595    def diagnostic_name(self):
596        if self.name:
597            return str(self.name)
598        try:
599            return f"lnchannel_{bh2u(self.channel_id[-4:])}"
600        except:
601            return super().diagnostic_name()
602
603    def set_onion_key(self, key: int, value: bytes):
604        self.onion_keys[key] = value
605
606    def get_onion_key(self, key: int) -> bytes:
607        return self.onion_keys.get(key)
608
609    def set_data_loss_protect_remote_pcp(self, key, value):
610        self.data_loss_protect_remote_pcp[key] = value
611
612    def get_data_loss_protect_remote_pcp(self, key):
613        return self.data_loss_protect_remote_pcp.get(key)
614
615    def get_local_pubkey(self) -> bytes:
616        if not self.lnworker:
617            raise Exception('lnworker not set for channel!')
618        return self.lnworker.node_keypair.pubkey
619
620    def set_remote_update(self, payload: dict) -> None:
621        """Save the ChannelUpdate message for the incoming direction of this channel.
622        This message contains info we need to populate private route hints when
623        creating invoices.
624        """
625        from .channel_db import ChannelDB
626        ChannelDB.verify_channel_update(payload, start_node=self.node_id)
627        raw = payload['raw']
628        self.storage['remote_update'] = raw.hex()
629
630    def get_remote_update(self) -> Optional[bytes]:
631        return bfh(self.storage.get('remote_update')) if self.storage.get('remote_update') else None
632
633    def add_or_update_peer_addr(self, peer: LNPeerAddr) -> None:
634        if 'peer_network_addresses' not in self.storage:
635            self.storage['peer_network_addresses'] = {}
636        now = int(time.time())
637        self.storage['peer_network_addresses'][peer.net_addr_str()] = now
638
639    def get_peer_addresses(self) -> Iterator[LNPeerAddr]:
640        # sort by timestamp: most recent first
641        addrs = sorted(self.storage.get('peer_network_addresses', {}).items(),
642                       key=lambda x: x[1], reverse=True)
643        for net_addr_str, ts in addrs:
644            net_addr = NetAddress.from_string(net_addr_str)
645            yield LNPeerAddr(host=str(net_addr.host), port=net_addr.port, pubkey=self.node_id)
646
647    def get_outgoing_gossip_channel_update(self) -> bytes:
648        if self._outgoing_channel_update is not None:
649            return self._outgoing_channel_update
650        if not self.lnworker:
651            raise Exception('lnworker not set for channel!')
652        sorted_node_ids = list(sorted([self.node_id, self.get_local_pubkey()]))
653        channel_flags = b'\x00' if sorted_node_ids[0] == self.get_local_pubkey() else b'\x01'
654        now = int(time.time())
655        htlc_maximum_msat = min(self.config[REMOTE].max_htlc_value_in_flight_msat, 1000 * self.constraints.capacity)
656
657        chan_upd = encode_msg(
658            "channel_update",
659            short_channel_id=self.short_channel_id,
660            channel_flags=channel_flags,
661            message_flags=b'\x01',
662            cltv_expiry_delta=self.forwarding_cltv_expiry_delta,
663            htlc_minimum_msat=self.config[REMOTE].htlc_minimum_msat,
664            htlc_maximum_msat=htlc_maximum_msat,
665            fee_base_msat=self.forwarding_fee_base_msat,
666            fee_proportional_millionths=self.forwarding_fee_proportional_millionths,
667            chain_hash=constants.net.rev_genesis_bytes(),
668            timestamp=now,
669        )
670        sighash = sha256d(chan_upd[2 + 64:])
671        sig = ecc.ECPrivkey(self.lnworker.node_keypair.privkey).sign(sighash, ecc.sig_string_from_r_and_s)
672        message_type, payload = decode_msg(chan_upd)
673        payload['signature'] = sig
674        chan_upd = encode_msg(message_type, **payload)
675
676        self._outgoing_channel_update = chan_upd
677        return chan_upd
678
679    def construct_channel_announcement_without_sigs(self) -> bytes:
680        if self._chan_ann_without_sigs is not None:
681            return self._chan_ann_without_sigs
682        if not self.lnworker:
683            raise Exception('lnworker not set for channel!')
684
685        bitcoin_keys = [self.config[REMOTE].multisig_key.pubkey,
686                        self.config[LOCAL].multisig_key.pubkey]
687        node_ids = [self.node_id, self.get_local_pubkey()]
688        sorted_node_ids = list(sorted(node_ids))
689        if sorted_node_ids != node_ids:
690            node_ids = sorted_node_ids
691            bitcoin_keys.reverse()
692
693        chan_ann = encode_msg(
694            "channel_announcement",
695            len=0,
696            features=b'',
697            chain_hash=constants.net.rev_genesis_bytes(),
698            short_channel_id=self.short_channel_id,
699            node_id_1=node_ids[0],
700            node_id_2=node_ids[1],
701            bitcoin_key_1=bitcoin_keys[0],
702            bitcoin_key_2=bitcoin_keys[1],
703        )
704
705        self._chan_ann_without_sigs = chan_ann
706        return chan_ann
707
708    def is_static_remotekey_enabled(self) -> bool:
709        return bool(self.storage.get('static_remotekey_enabled'))
710
711    def get_wallet_addresses_channel_might_want_reserved(self) -> Sequence[str]:
712        ret = []
713        if self.is_static_remotekey_enabled():
714            our_payment_pubkey = self.config[LOCAL].payment_basepoint.pubkey
715            to_remote_address = make_commitment_output_to_remote_address(our_payment_pubkey)
716            ret.append(to_remote_address)
717        return ret
718
719    def get_feerate(self, subject: HTLCOwner, *, ctn: int) -> int:
720        # returns feerate in sat/kw
721        return self.hm.get_feerate(subject, ctn)
722
723    def get_oldest_unrevoked_feerate(self, subject: HTLCOwner) -> int:
724        return self.hm.get_feerate_in_oldest_unrevoked_ctx(subject)
725
726    def get_latest_feerate(self, subject: HTLCOwner) -> int:
727        return self.hm.get_feerate_in_latest_ctx(subject)
728
729    def get_next_feerate(self, subject: HTLCOwner) -> int:
730        return self.hm.get_feerate_in_next_ctx(subject)
731
732    def get_payments(self, status=None) -> Mapping[bytes, List[HTLCWithStatus]]:
733        out = defaultdict(list)
734        for direction, htlc in self.hm.all_htlcs_ever():
735            htlc_proposer = LOCAL if direction is SENT else REMOTE
736            if self.hm.was_htlc_failed(htlc_id=htlc.htlc_id, htlc_proposer=htlc_proposer):
737                _status = 'failed'
738            elif self.hm.was_htlc_preimage_released(htlc_id=htlc.htlc_id, htlc_proposer=htlc_proposer):
739                _status = 'settled'
740            else:
741                _status = 'inflight'
742            if status and status != _status:
743                continue
744            htlc_with_status = HTLCWithStatus(
745                channel_id=self.channel_id, htlc=htlc, direction=direction, status=_status)
746            out[htlc.payment_hash].append(htlc_with_status)
747        return out
748
749    def open_with_first_pcp(self, remote_pcp: bytes, remote_sig: bytes) -> None:
750        with self.db_lock:
751            self.config[REMOTE].current_per_commitment_point = remote_pcp
752            self.config[REMOTE].next_per_commitment_point = None
753            self.config[LOCAL].current_commitment_signature = remote_sig
754            self.hm.channel_open_finished()
755            self.peer_state = PeerState.GOOD
756
757    def get_state_for_GUI(self):
758        cs_name = super().get_state_for_GUI()
759        if self.is_closed() or self.unconfirmed_closing_txid:
760            return cs_name
761        ps = self.peer_state
762        if ps != PeerState.GOOD:
763            return ps.name
764        return cs_name
765
766    def set_can_send_ctx_updates(self, b: bool) -> None:
767        self._can_send_ctx_updates = b
768
769    def can_send_ctx_updates(self) -> bool:
770        """Whether we can send update_fee, update_*_htlc changes to the remote."""
771        if not (self.is_open() or self.is_closing()):
772            return False
773        if self.peer_state != PeerState.GOOD:
774            return False
775        if not self._can_send_ctx_updates:
776            return False
777        return True
778
779    def can_send_update_add_htlc(self) -> bool:
780        return self.can_send_ctx_updates() and not self.is_closing()
781
782    def is_frozen_for_sending(self) -> bool:
783        if self.lnworker and self.lnworker.channel_db is None and not self.lnworker.is_trampoline_peer(self.node_id):
784            return True
785        return self.storage.get('frozen_for_sending', False)
786
787    def set_frozen_for_sending(self, b: bool) -> None:
788        self.storage['frozen_for_sending'] = bool(b)
789        util.trigger_callback('channel', self.lnworker.wallet, self)
790
791    def is_frozen_for_receiving(self) -> bool:
792        return self.storage.get('frozen_for_receiving', False)
793
794    def set_frozen_for_receiving(self, b: bool) -> None:
795        self.storage['frozen_for_receiving'] = bool(b)
796        util.trigger_callback('channel', self.lnworker.wallet, self)
797
798    def _assert_can_add_htlc(self, *, htlc_proposer: HTLCOwner, amount_msat: int,
799                             ignore_min_htlc_value: bool = False) -> None:
800        """Raises PaymentFailure if the htlc_proposer cannot add this new HTLC.
801        (this is relevant both for forwarding and endpoint)
802        """
803        htlc_receiver = htlc_proposer.inverted()
804        # note: all these tests are about the *receiver's* *next* commitment transaction,
805        #       and the constraints are the ones imposed by their config
806        ctn = self.get_next_ctn(htlc_receiver)
807        chan_config = self.config[htlc_receiver]
808        if self.get_state() != ChannelState.OPEN:
809            raise PaymentFailure('Channel not open', self.get_state())
810        if htlc_proposer == LOCAL:
811            if not self.can_send_ctx_updates():
812                raise PaymentFailure('Channel cannot send ctx updates')
813            if not self.can_send_update_add_htlc():
814                raise PaymentFailure('Channel cannot add htlc')
815
816        # If proposer is LOCAL we apply stricter checks as that is behaviour we can control.
817        # This should lead to fewer disagreements (i.e. channels failing).
818        strict = (htlc_proposer == LOCAL)
819
820        # check htlc raw value
821        if not ignore_min_htlc_value:
822            if amount_msat <= 0:
823                raise PaymentFailure("HTLC value must be positive")
824            if amount_msat < chan_config.htlc_minimum_msat:
825                raise PaymentFailure(f'HTLC value too small: {amount_msat} msat')
826
827        # check proposer can afford htlc
828        max_can_send_msat = self.available_to_spend(htlc_proposer, strict=strict)
829        if max_can_send_msat < amount_msat:
830            raise PaymentFailure(f'Not enough balance. can send: {max_can_send_msat}, tried: {amount_msat}')
831
832        # check "max_accepted_htlcs"
833        # this is the loose check BOLT-02 specifies:
834        if len(self.hm.htlcs_by_direction(htlc_receiver, direction=RECEIVED, ctn=ctn)) + 1 > chan_config.max_accepted_htlcs:
835            raise PaymentFailure('Too many HTLCs already in channel')
836        # however, c-lightning is a lot stricter, so extra checks:
837        # https://github.com/ElementsProject/lightning/blob/4dcd4ca1556b13b6964a10040ba1d5ef82de4788/channeld/full_channel.c#L581
838        if strict:
839            max_concurrent_htlcs = min(self.config[htlc_proposer].max_accepted_htlcs,
840                                       self.config[htlc_receiver].max_accepted_htlcs)
841            if len(self.hm.htlcs(htlc_receiver, ctn=ctn)) + 1 > max_concurrent_htlcs:
842                raise PaymentFailure('Too many HTLCs already in channel')
843
844        # check "max_htlc_value_in_flight_msat"
845        current_htlc_sum = htlcsum(self.hm.htlcs_by_direction(htlc_receiver, direction=RECEIVED, ctn=ctn).values())
846        if current_htlc_sum + amount_msat > chan_config.max_htlc_value_in_flight_msat:
847            raise PaymentFailure(f'HTLC value sum (sum of pending htlcs: {current_htlc_sum/1000} sat '
848                                 f'plus new htlc: {amount_msat/1000} sat) '
849                                 f'would exceed max allowed: {chan_config.max_htlc_value_in_flight_msat/1000} sat')
850
851    def can_pay(self, amount_msat: int, *, check_frozen=False) -> bool:
852        """Returns whether we can add an HTLC of given value."""
853        if check_frozen and self.is_frozen_for_sending():
854            return False
855        try:
856            self._assert_can_add_htlc(htlc_proposer=LOCAL, amount_msat=amount_msat)
857        except PaymentFailure:
858            return False
859        return True
860
861    def can_receive(self, amount_msat: int, *, check_frozen=False,
862                    ignore_min_htlc_value: bool = False) -> bool:
863        """Returns whether the remote can add an HTLC of given value."""
864        if check_frozen and self.is_frozen_for_receiving():
865            return False
866        try:
867            self._assert_can_add_htlc(htlc_proposer=REMOTE,
868                                      amount_msat=amount_msat,
869                                      ignore_min_htlc_value=ignore_min_htlc_value)
870        except PaymentFailure:
871            return False
872        return True
873
874    def should_try_to_reestablish_peer(self) -> bool:
875        return ChannelState.PREOPENING < self._state < ChannelState.CLOSING and self.peer_state == PeerState.DISCONNECTED
876
877    def get_funding_address(self):
878        script = funding_output_script(self.config[LOCAL], self.config[REMOTE])
879        return redeem_script_to_address('p2wsh', script)
880
881    def add_htlc(self, htlc: UpdateAddHtlc) -> UpdateAddHtlc:
882        """Adds a new LOCAL HTLC to the channel.
883        Action must be initiated by LOCAL.
884        """
885        if isinstance(htlc, dict):  # legacy conversion  # FIXME remove
886            htlc = UpdateAddHtlc(**htlc)
887        assert isinstance(htlc, UpdateAddHtlc)
888        self._assert_can_add_htlc(htlc_proposer=LOCAL, amount_msat=htlc.amount_msat)
889        if htlc.htlc_id is None:
890            htlc = attr.evolve(htlc, htlc_id=self.hm.get_next_htlc_id(LOCAL))
891        with self.db_lock:
892            self.hm.send_htlc(htlc)
893        self.logger.info("add_htlc")
894        return htlc
895
896    def receive_htlc(self, htlc: UpdateAddHtlc, onion_packet:bytes = None) -> UpdateAddHtlc:
897        """Adds a new REMOTE HTLC to the channel.
898        Action must be initiated by REMOTE.
899        """
900        if isinstance(htlc, dict):  # legacy conversion  # FIXME remove
901            htlc = UpdateAddHtlc(**htlc)
902        assert isinstance(htlc, UpdateAddHtlc)
903        try:
904            self._assert_can_add_htlc(htlc_proposer=REMOTE, amount_msat=htlc.amount_msat)
905        except PaymentFailure as e:
906            raise RemoteMisbehaving(e) from e
907        if htlc.htlc_id is None:  # used in unit tests
908            htlc = attr.evolve(htlc, htlc_id=self.hm.get_next_htlc_id(REMOTE))
909        with self.db_lock:
910            self.hm.recv_htlc(htlc)
911            local_ctn = self.get_latest_ctn(LOCAL)
912            remote_ctn = self.get_latest_ctn(REMOTE)
913            if onion_packet:
914                # TODO neither local_ctn nor remote_ctn are used anymore... no point storing them.
915                self.hm.log['unfulfilled_htlcs'][htlc.htlc_id] = local_ctn, remote_ctn, onion_packet.hex(), False
916
917        self.logger.info("receive_htlc")
918        return htlc
919
920    def sign_next_commitment(self) -> Tuple[bytes, Sequence[bytes]]:
921        """Returns signatures for our next remote commitment tx.
922        Action must be initiated by LOCAL.
923        Finally, the next remote ctx becomes the latest remote ctx.
924        """
925        next_remote_ctn = self.get_next_ctn(REMOTE)
926        self.logger.info(f"sign_next_commitment {next_remote_ctn}")
927
928        pending_remote_commitment = self.get_next_commitment(REMOTE)
929        sig_64 = sign_and_get_sig_string(pending_remote_commitment, self.config[LOCAL], self.config[REMOTE])
930
931        their_remote_htlc_privkey_number = derive_privkey(
932            int.from_bytes(self.config[LOCAL].htlc_basepoint.privkey, 'big'),
933            self.config[REMOTE].next_per_commitment_point)
934        their_remote_htlc_privkey = their_remote_htlc_privkey_number.to_bytes(32, 'big')
935
936        htlcsigs = []
937        htlc_to_ctx_output_idx_map = map_htlcs_to_ctx_output_idxs(chan=self,
938                                                                  ctx=pending_remote_commitment,
939                                                                  pcp=self.config[REMOTE].next_per_commitment_point,
940                                                                  subject=REMOTE,
941                                                                  ctn=next_remote_ctn)
942        for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items():
943            _script, htlc_tx = make_htlc_tx_with_open_channel(chan=self,
944                                                              pcp=self.config[REMOTE].next_per_commitment_point,
945                                                              subject=REMOTE,
946                                                              ctn=next_remote_ctn,
947                                                              htlc_direction=direction,
948                                                              commit=pending_remote_commitment,
949                                                              ctx_output_idx=ctx_output_idx,
950                                                              htlc=htlc)
951            sig = bfh(htlc_tx.sign_txin(0, their_remote_htlc_privkey))
952            htlc_sig = ecc.sig_string_from_der_sig(sig[:-1])
953            htlcsigs.append((ctx_output_idx, htlc_sig))
954        htlcsigs.sort()
955        htlcsigs = [x[1] for x in htlcsigs]
956        with self.db_lock:
957            self.hm.send_ctx()
958        return sig_64, htlcsigs
959
960    def receive_new_commitment(self, sig: bytes, htlc_sigs: Sequence[bytes]) -> None:
961        """Processes signatures for our next local commitment tx, sent by the REMOTE.
962        Action must be initiated by REMOTE.
963        If all checks pass, the next local ctx becomes the latest local ctx.
964        """
965        # TODO in many failure cases below, we should "fail" the channel (force-close)
966        next_local_ctn = self.get_next_ctn(LOCAL)
967        self.logger.info(f"receive_new_commitment. ctn={next_local_ctn}, len(htlc_sigs)={len(htlc_sigs)}")
968
969        assert len(htlc_sigs) == 0 or type(htlc_sigs[0]) is bytes
970
971        pending_local_commitment = self.get_next_commitment(LOCAL)
972        preimage_hex = pending_local_commitment.serialize_preimage(0)
973        pre_hash = sha256d(bfh(preimage_hex))
974        if not ecc.verify_signature(self.config[REMOTE].multisig_key.pubkey, sig, pre_hash):
975            raise Exception(f'failed verifying signature of our updated commitment transaction: {bh2u(sig)} preimage is {preimage_hex}')
976
977        htlc_sigs_string = b''.join(htlc_sigs)
978
979        _secret, pcp = self.get_secret_and_point(subject=LOCAL, ctn=next_local_ctn)
980
981        htlc_to_ctx_output_idx_map = map_htlcs_to_ctx_output_idxs(chan=self,
982                                                                  ctx=pending_local_commitment,
983                                                                  pcp=pcp,
984                                                                  subject=LOCAL,
985                                                                  ctn=next_local_ctn)
986        if len(htlc_to_ctx_output_idx_map) != len(htlc_sigs):
987            raise Exception(f'htlc sigs failure. recv {len(htlc_sigs)} sigs, expected {len(htlc_to_ctx_output_idx_map)}')
988        for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items():
989            htlc_sig = htlc_sigs[htlc_relative_idx]
990            self._verify_htlc_sig(htlc=htlc,
991                                  htlc_sig=htlc_sig,
992                                  htlc_direction=direction,
993                                  pcp=pcp,
994                                  ctx=pending_local_commitment,
995                                  ctx_output_idx=ctx_output_idx,
996                                  ctn=next_local_ctn)
997        with self.db_lock:
998            self.hm.recv_ctx()
999            self.config[LOCAL].current_commitment_signature=sig
1000            self.config[LOCAL].current_htlc_signatures=htlc_sigs_string
1001
1002    def _verify_htlc_sig(self, *, htlc: UpdateAddHtlc, htlc_sig: bytes, htlc_direction: Direction,
1003                         pcp: bytes, ctx: Transaction, ctx_output_idx: int, ctn: int) -> None:
1004        _script, htlc_tx = make_htlc_tx_with_open_channel(chan=self,
1005                                                          pcp=pcp,
1006                                                          subject=LOCAL,
1007                                                          ctn=ctn,
1008                                                          htlc_direction=htlc_direction,
1009                                                          commit=ctx,
1010                                                          ctx_output_idx=ctx_output_idx,
1011                                                          htlc=htlc)
1012        pre_hash = sha256d(bfh(htlc_tx.serialize_preimage(0)))
1013        remote_htlc_pubkey = derive_pubkey(self.config[REMOTE].htlc_basepoint.pubkey, pcp)
1014        if not ecc.verify_signature(remote_htlc_pubkey, htlc_sig, pre_hash):
1015            raise Exception(f'failed verifying HTLC signatures: {htlc} {htlc_direction}')
1016
1017    def get_remote_htlc_sig_for_htlc(self, *, htlc_relative_idx: int) -> bytes:
1018        data = self.config[LOCAL].current_htlc_signatures
1019        htlc_sigs = list(chunks(data, 64))
1020        htlc_sig = htlc_sigs[htlc_relative_idx]
1021        remote_htlc_sig = ecc.der_sig_from_sig_string(htlc_sig) + b'\x01'
1022        return remote_htlc_sig
1023
1024    def revoke_current_commitment(self):
1025        self.logger.info("revoke_current_commitment")
1026        new_ctn = self.get_latest_ctn(LOCAL)
1027        new_ctx = self.get_latest_commitment(LOCAL)
1028        if not self.signature_fits(new_ctx):
1029            # this should never fail; as receive_new_commitment already did this test
1030            raise Exception("refusing to revoke as remote sig does not fit")
1031        with self.db_lock:
1032            self.hm.send_rev()
1033        last_secret, last_point = self.get_secret_and_point(LOCAL, new_ctn - 1)
1034        next_secret, next_point = self.get_secret_and_point(LOCAL, new_ctn + 1)
1035        return RevokeAndAck(last_secret, next_point)
1036
1037    def receive_revocation(self, revocation: RevokeAndAck):
1038        self.logger.info("receive_revocation")
1039        new_ctn = self.get_latest_ctn(REMOTE)
1040        cur_point = self.config[REMOTE].current_per_commitment_point
1041        derived_point = ecc.ECPrivkey(revocation.per_commitment_secret).get_public_key_bytes(compressed=True)
1042        if cur_point != derived_point:
1043            raise Exception('revoked secret not for current point')
1044        with self.db_lock:
1045            self.revocation_store.add_next_entry(revocation.per_commitment_secret)
1046            ##### start applying fee/htlc changes
1047            self.hm.recv_rev()
1048            self.config[REMOTE].current_per_commitment_point=self.config[REMOTE].next_per_commitment_point
1049            self.config[REMOTE].next_per_commitment_point=revocation.next_per_commitment_point
1050        assert new_ctn == self.get_oldest_unrevoked_ctn(REMOTE)
1051        # lnworker callbacks
1052        if self.lnworker:
1053            sent = self.hm.sent_in_ctn(new_ctn)
1054            for htlc in sent:
1055                self.lnworker.htlc_fulfilled(self, htlc.payment_hash, htlc.htlc_id)
1056            failed = self.hm.failed_in_ctn(new_ctn)
1057            for htlc in failed:
1058                try:
1059                    error_bytes, failure_message = self._receive_fail_reasons.pop(htlc.htlc_id)
1060                except KeyError:
1061                    error_bytes, failure_message = None, None
1062                # if we are forwarding, save error message to disk
1063                if self.lnworker.get_payment_info(htlc.payment_hash) is None:
1064                    self.save_fail_htlc_reason(htlc.htlc_id, error_bytes, failure_message)
1065                self.lnworker.htlc_failed(self, htlc.payment_hash, htlc.htlc_id, error_bytes, failure_message)
1066
1067    def save_fail_htlc_reason(
1068            self,
1069            htlc_id: int,
1070            error_bytes: Optional[bytes],
1071            failure_message: Optional['OnionRoutingFailure']):
1072        error_hex = error_bytes.hex() if error_bytes else None
1073        failure_hex = failure_message.to_bytes().hex() if failure_message else None
1074        self.hm.log['fail_htlc_reasons'][htlc_id] = (error_hex, failure_hex)
1075
1076    def pop_fail_htlc_reason(self, htlc_id):
1077        error_hex, failure_hex = self.hm.log['fail_htlc_reasons'].pop(htlc_id, (None, None))
1078        error_bytes = bytes.fromhex(error_hex) if error_hex else None
1079        failure_message = OnionRoutingFailure.from_bytes(bytes.fromhex(failure_hex)) if failure_hex else None
1080        return error_bytes, failure_message
1081
1082    def extract_preimage_from_htlc_txin(self, txin: TxInput) -> None:
1083        witness = txin.witness_elements()
1084        if len(witness) == 5:  # HTLC success tx
1085            preimage = witness[3]
1086        elif len(witness) == 3:  # spending offered HTLC directly from ctx
1087            preimage = witness[1]
1088        else:
1089            return
1090        payment_hash = sha256(preimage)
1091        for direction, htlc in itertools.chain(self.hm.get_htlcs_in_oldest_unrevoked_ctx(REMOTE),
1092                                               self.hm.get_htlcs_in_latest_ctx(REMOTE)):
1093            if htlc.payment_hash == payment_hash:
1094                is_sent = direction == RECEIVED
1095                break
1096        else:
1097            for direction, htlc in itertools.chain(self.hm.get_htlcs_in_oldest_unrevoked_ctx(LOCAL),
1098                                                   self.hm.get_htlcs_in_latest_ctx(LOCAL)):
1099                if htlc.payment_hash == payment_hash:
1100                    is_sent = direction == SENT
1101                    break
1102            else:
1103                return
1104        if self.lnworker.get_preimage(payment_hash) is None:
1105            self.logger.info(f'found preimage for {payment_hash.hex()} in witness of length {len(witness)}')
1106            self.lnworker.save_preimage(payment_hash, preimage)
1107        info = self.lnworker.get_payment_info(payment_hash)
1108        if info is not None and info.status != PR_PAID:
1109            if is_sent:
1110                self.lnworker.htlc_fulfilled(self, payment_hash, htlc.htlc_id)
1111            else:
1112                # FIXME
1113                #self.lnworker.htlc_received(self, payment_hash)
1114                pass
1115
1116    def balance(self, whose: HTLCOwner, *, ctx_owner=HTLCOwner.LOCAL, ctn: int = None) -> int:
1117        assert type(whose) is HTLCOwner
1118        initial = self.config[whose].initial_msat
1119        return self.hm.get_balance_msat(whose=whose,
1120                                        ctx_owner=ctx_owner,
1121                                        ctn=ctn,
1122                                        initial_balance_msat=initial)
1123
1124    def balance_minus_outgoing_htlcs(self, whose: HTLCOwner, *, ctx_owner: HTLCOwner = HTLCOwner.LOCAL,
1125                                     ctn: int = None) -> int:
1126        assert type(whose) is HTLCOwner
1127        if ctn is None:
1128            ctn = self.get_next_ctn(ctx_owner)
1129        committed_balance = self.balance(whose, ctx_owner=ctx_owner, ctn=ctn)
1130        direction = RECEIVED if whose != ctx_owner else SENT
1131        balance_in_htlcs = self.balance_tied_up_in_htlcs_by_direction(ctx_owner, ctn=ctn, direction=direction)
1132        return committed_balance - balance_in_htlcs
1133
1134    def balance_tied_up_in_htlcs_by_direction(self, ctx_owner: HTLCOwner = LOCAL, *, ctn: int = None,
1135                                              direction: Direction):
1136        # in msat
1137        if ctn is None:
1138            ctn = self.get_next_ctn(ctx_owner)
1139        return htlcsum(self.hm.htlcs_by_direction(ctx_owner, direction, ctn).values())
1140
1141    def available_to_spend(self, subject: HTLCOwner, *, strict: bool = True) -> int:
1142        """The usable balance of 'subject' in msat, after taking reserve and fees into
1143        consideration. Note that fees (and hence the result) fluctuate even without user interaction.
1144        """
1145        assert type(subject) is HTLCOwner
1146        sender = subject
1147        receiver = subject.inverted()
1148        initiator = LOCAL if self.constraints.is_initiator else REMOTE  # the initiator/funder pays on-chain fees
1149
1150        def consider_ctx(*, ctx_owner: HTLCOwner, is_htlc_dust: bool) -> int:
1151            ctn = self.get_next_ctn(ctx_owner)
1152            sender_balance_msat = self.balance_minus_outgoing_htlcs(whose=sender, ctx_owner=ctx_owner, ctn=ctn)
1153            receiver_balance_msat = self.balance_minus_outgoing_htlcs(whose=receiver, ctx_owner=ctx_owner, ctn=ctn)
1154            sender_reserve_msat = self.config[receiver].reserve_sat * 1000
1155            receiver_reserve_msat = self.config[sender].reserve_sat * 1000
1156            num_htlcs_in_ctx = len(self.included_htlcs(ctx_owner, SENT, ctn=ctn) + self.included_htlcs(ctx_owner, RECEIVED, ctn=ctn))
1157            feerate = self.get_feerate(ctx_owner, ctn=ctn)
1158            ctx_fees_msat = calc_fees_for_commitment_tx(
1159                num_htlcs=num_htlcs_in_ctx,
1160                feerate=feerate,
1161                is_local_initiator=self.constraints.is_initiator,
1162                round_to_sat=False,
1163            )
1164            htlc_fee_msat = fee_for_htlc_output(feerate=feerate)
1165            htlc_trim_func = received_htlc_trim_threshold_sat if ctx_owner == receiver else offered_htlc_trim_threshold_sat
1166            htlc_trim_threshold_msat = htlc_trim_func(dust_limit_sat=self.config[ctx_owner].dust_limit_sat, feerate=feerate) * 1000
1167            if sender == initiator == LOCAL:  # see https://github.com/lightningnetwork/lightning-rfc/pull/740
1168                fee_spike_buffer = calc_fees_for_commitment_tx(
1169                    num_htlcs=num_htlcs_in_ctx + int(not is_htlc_dust) + 1,
1170                    feerate=2 * feerate,
1171                    is_local_initiator=self.constraints.is_initiator,
1172                    round_to_sat=False,
1173                )[sender]
1174                max_send_msat = sender_balance_msat - sender_reserve_msat - fee_spike_buffer
1175            else:
1176                max_send_msat = sender_balance_msat - sender_reserve_msat - ctx_fees_msat[sender]
1177            if is_htlc_dust:
1178                return min(max_send_msat, htlc_trim_threshold_msat - 1)
1179            else:
1180                if sender == initiator:
1181                    return max_send_msat - htlc_fee_msat
1182                else:
1183                    # the receiver is the initiator, so they need to be able to pay tx fees
1184                    if receiver_balance_msat - receiver_reserve_msat - ctx_fees_msat[receiver] - htlc_fee_msat < 0:
1185                        return 0
1186                    return max_send_msat
1187
1188        max_send_msat = min(
1189                            max(
1190                                consider_ctx(ctx_owner=receiver, is_htlc_dust=True),
1191                                consider_ctx(ctx_owner=receiver, is_htlc_dust=False),
1192                            ),
1193                            max(
1194                                consider_ctx(ctx_owner=sender, is_htlc_dust=True),
1195                                consider_ctx(ctx_owner=sender, is_htlc_dust=False),
1196                            ),
1197        )
1198        max_send_msat = max(max_send_msat, 0)
1199        return max_send_msat
1200
1201
1202    def included_htlcs(self, subject: HTLCOwner, direction: Direction, ctn: int = None, *,
1203                       feerate: int = None) -> Sequence[UpdateAddHtlc]:
1204        """Returns list of non-dust HTLCs for subject's commitment tx at ctn,
1205        filtered by direction (of HTLCs).
1206        """
1207        assert type(subject) is HTLCOwner
1208        assert type(direction) is Direction
1209        if ctn is None:
1210            ctn = self.get_oldest_unrevoked_ctn(subject)
1211        if feerate is None:
1212            feerate = self.get_feerate(subject, ctn=ctn)
1213        conf = self.config[subject]
1214        if direction == RECEIVED:
1215            threshold_sat = received_htlc_trim_threshold_sat(dust_limit_sat=conf.dust_limit_sat, feerate=feerate)
1216        else:
1217            threshold_sat = offered_htlc_trim_threshold_sat(dust_limit_sat=conf.dust_limit_sat, feerate=feerate)
1218        htlcs = self.hm.htlcs_by_direction(subject, direction, ctn=ctn).values()
1219        return list(filter(lambda htlc: htlc.amount_msat // 1000 >= threshold_sat, htlcs))
1220
1221    def get_secret_and_point(self, subject: HTLCOwner, ctn: int) -> Tuple[Optional[bytes], bytes]:
1222        assert type(subject) is HTLCOwner
1223        assert ctn >= 0, ctn
1224        offset = ctn - self.get_oldest_unrevoked_ctn(subject)
1225        if subject == REMOTE:
1226            if offset > 1:
1227                raise RemoteCtnTooFarInFuture(f"offset: {offset}")
1228            conf = self.config[REMOTE]
1229            if offset == 1:
1230                secret = None
1231                point = conf.next_per_commitment_point
1232            elif offset == 0:
1233                secret = None
1234                point = conf.current_per_commitment_point
1235            else:
1236                secret = self.revocation_store.retrieve_secret(RevocationStore.START_INDEX - ctn)
1237                point = secret_to_pubkey(int.from_bytes(secret, 'big'))
1238        else:
1239            secret = get_per_commitment_secret_from_seed(self.config[LOCAL].per_commitment_secret_seed, RevocationStore.START_INDEX - ctn)
1240            point = secret_to_pubkey(int.from_bytes(secret, 'big'))
1241        return secret, point
1242
1243    def get_secret_and_commitment(self, subject: HTLCOwner, *, ctn: int) -> Tuple[Optional[bytes], PartialTransaction]:
1244        secret, point = self.get_secret_and_point(subject, ctn)
1245        ctx = self.make_commitment(subject, point, ctn)
1246        return secret, ctx
1247
1248    def get_commitment(self, subject: HTLCOwner, *, ctn: int) -> PartialTransaction:
1249        secret, ctx = self.get_secret_and_commitment(subject, ctn=ctn)
1250        return ctx
1251
1252    def get_next_commitment(self, subject: HTLCOwner) -> PartialTransaction:
1253        ctn = self.get_next_ctn(subject)
1254        return self.get_commitment(subject, ctn=ctn)
1255
1256    def get_latest_commitment(self, subject: HTLCOwner) -> PartialTransaction:
1257        ctn = self.get_latest_ctn(subject)
1258        return self.get_commitment(subject, ctn=ctn)
1259
1260    def get_oldest_unrevoked_commitment(self, subject: HTLCOwner) -> PartialTransaction:
1261        ctn = self.get_oldest_unrevoked_ctn(subject)
1262        return self.get_commitment(subject, ctn=ctn)
1263
1264    def create_sweeptxs(self, ctn: int) -> List[Transaction]:
1265        from .lnsweep import create_sweeptxs_for_watchtower
1266        secret, ctx = self.get_secret_and_commitment(REMOTE, ctn=ctn)
1267        return create_sweeptxs_for_watchtower(self, ctx, secret, self.sweep_address)
1268
1269    def get_oldest_unrevoked_ctn(self, subject: HTLCOwner) -> int:
1270        return self.hm.ctn_oldest_unrevoked(subject)
1271
1272    def get_latest_ctn(self, subject: HTLCOwner) -> int:
1273        return self.hm.ctn_latest(subject)
1274
1275    def get_next_ctn(self, subject: HTLCOwner) -> int:
1276        return self.hm.ctn_latest(subject) + 1
1277
1278    def total_msat(self, direction: Direction) -> int:
1279        """Return the cumulative total msat amount received/sent so far."""
1280        assert type(direction) is Direction
1281        return htlcsum(self.hm.all_settled_htlcs_ever_by_direction(LOCAL, direction))
1282
1283    def settle_htlc(self, preimage: bytes, htlc_id: int) -> None:
1284        """Settle/fulfill a pending received HTLC.
1285        Action must be initiated by LOCAL.
1286        """
1287        self.logger.info("settle_htlc")
1288        assert self.can_send_ctx_updates(), f"cannot update channel. {self.get_state()!r} {self.peer_state!r}"
1289        htlc = self.hm.get_htlc_by_id(REMOTE, htlc_id)
1290        assert htlc.payment_hash == sha256(preimage)
1291        assert htlc_id not in self.hm.log[REMOTE]['settles']
1292        self.hm.send_settle(htlc_id)
1293
1294    def get_payment_hash(self, htlc_id: int) -> bytes:
1295        htlc = self.hm.get_htlc_by_id(LOCAL, htlc_id)
1296        return htlc.payment_hash
1297
1298    def decode_onion_error(self, reason: bytes, route: Sequence['RouteEdge'],
1299                           htlc_id: int) -> Tuple[OnionRoutingFailure, int]:
1300        failure_msg, sender_idx = decode_onion_error(
1301            reason,
1302            [x.node_id for x in route],
1303            self.onion_keys[htlc_id])
1304        return failure_msg, sender_idx
1305
1306    def receive_htlc_settle(self, preimage: bytes, htlc_id: int) -> None:
1307        """Settle/fulfill a pending offered HTLC.
1308        Action must be initiated by REMOTE.
1309        """
1310        self.logger.info("receive_htlc_settle")
1311        htlc = self.hm.get_htlc_by_id(LOCAL, htlc_id)
1312        assert htlc.payment_hash == sha256(preimage)
1313        assert htlc_id not in self.hm.log[LOCAL]['settles']
1314        with self.db_lock:
1315            self.hm.recv_settle(htlc_id)
1316
1317    def fail_htlc(self, htlc_id: int) -> None:
1318        """Fail a pending received HTLC.
1319        Action must be initiated by LOCAL.
1320        """
1321        self.logger.info("fail_htlc")
1322        assert self.can_send_ctx_updates(), f"cannot update channel. {self.get_state()!r} {self.peer_state!r}"
1323        with self.db_lock:
1324            self.hm.send_fail(htlc_id)
1325
1326    def receive_fail_htlc(self, htlc_id: int, *,
1327                          error_bytes: Optional[bytes],
1328                          reason: Optional[OnionRoutingFailure] = None) -> None:
1329        """Fail a pending offered HTLC.
1330        Action must be initiated by REMOTE.
1331        """
1332        self.logger.info("receive_fail_htlc")
1333        with self.db_lock:
1334            self.hm.recv_fail(htlc_id)
1335        self._receive_fail_reasons[htlc_id] = (error_bytes, reason)
1336
1337    def get_next_fee(self, subject: HTLCOwner) -> int:
1338        return self.constraints.capacity - sum(x.value for x in self.get_next_commitment(subject).outputs())
1339
1340    def get_latest_fee(self, subject: HTLCOwner) -> int:
1341        return self.constraints.capacity - sum(x.value for x in self.get_latest_commitment(subject).outputs())
1342
1343    def update_fee(self, feerate: int, from_us: bool) -> None:
1344        # feerate uses sat/kw
1345        if self.constraints.is_initiator != from_us:
1346            raise Exception(f"Cannot update_fee: wrong initiator. us: {from_us}")
1347        sender = LOCAL if from_us else REMOTE
1348        ctx_owner = -sender
1349        ctn = self.get_next_ctn(ctx_owner)
1350        sender_balance_msat = self.balance_minus_outgoing_htlcs(whose=sender, ctx_owner=ctx_owner, ctn=ctn)
1351        sender_reserve_msat = self.config[-sender].reserve_sat * 1000
1352        num_htlcs_in_ctx = len(self.included_htlcs(ctx_owner, SENT, ctn=ctn, feerate=feerate) +
1353                               self.included_htlcs(ctx_owner, RECEIVED, ctn=ctn, feerate=feerate))
1354        ctx_fees_msat = calc_fees_for_commitment_tx(
1355            num_htlcs=num_htlcs_in_ctx,
1356            feerate=feerate,
1357            is_local_initiator=self.constraints.is_initiator,
1358        )
1359        remainder = sender_balance_msat - sender_reserve_msat - ctx_fees_msat[sender]
1360        if remainder < 0:
1361            raise Exception(f"Cannot update_fee. {sender} tried to update fee but they cannot afford it. "
1362                            f"Their balance would go below reserve: {remainder} msat missing.")
1363        with self.db_lock:
1364            if from_us:
1365                assert self.can_send_ctx_updates(), f"cannot update channel. {self.get_state()!r} {self.peer_state!r}"
1366                self.hm.send_update_fee(feerate)
1367            else:
1368                self.hm.recv_update_fee(feerate)
1369
1370    def make_commitment(self, subject: HTLCOwner, this_point: bytes, ctn: int) -> PartialTransaction:
1371        assert type(subject) is HTLCOwner
1372        feerate = self.get_feerate(subject, ctn=ctn)
1373        other = subject.inverted()
1374        local_msat = self.balance(subject, ctx_owner=subject, ctn=ctn)
1375        remote_msat = self.balance(other, ctx_owner=subject, ctn=ctn)
1376        received_htlcs = self.hm.htlcs_by_direction(subject, RECEIVED, ctn).values()
1377        sent_htlcs = self.hm.htlcs_by_direction(subject, SENT, ctn).values()
1378        remote_msat -= htlcsum(received_htlcs)
1379        local_msat -= htlcsum(sent_htlcs)
1380        assert remote_msat >= 0
1381        assert local_msat >= 0
1382        # same htlcs as before, but now without dust.
1383        received_htlcs = self.included_htlcs(subject, RECEIVED, ctn)
1384        sent_htlcs = self.included_htlcs(subject, SENT, ctn)
1385
1386        this_config = self.config[subject]
1387        other_config = self.config[-subject]
1388        other_htlc_pubkey = derive_pubkey(other_config.htlc_basepoint.pubkey, this_point)
1389        this_htlc_pubkey = derive_pubkey(this_config.htlc_basepoint.pubkey, this_point)
1390        other_revocation_pubkey = derive_blinded_pubkey(other_config.revocation_basepoint.pubkey, this_point)
1391        htlcs = []  # type: List[ScriptHtlc]
1392        for is_received_htlc, htlc_list in zip((True, False), (received_htlcs, sent_htlcs)):
1393            for htlc in htlc_list:
1394                htlcs.append(ScriptHtlc(make_htlc_output_witness_script(
1395                    is_received_htlc=is_received_htlc,
1396                    remote_revocation_pubkey=other_revocation_pubkey,
1397                    remote_htlc_pubkey=other_htlc_pubkey,
1398                    local_htlc_pubkey=this_htlc_pubkey,
1399                    payment_hash=htlc.payment_hash,
1400                    cltv_expiry=htlc.cltv_expiry), htlc))
1401        # note: maybe flip initiator here for fee purposes, we want LOCAL and REMOTE
1402        #       in the resulting dict to correspond to the to_local and to_remote *outputs* of the ctx
1403        onchain_fees = calc_fees_for_commitment_tx(
1404            num_htlcs=len(htlcs),
1405            feerate=feerate,
1406            is_local_initiator=self.constraints.is_initiator == (subject == LOCAL),
1407        )
1408
1409        if self.is_static_remotekey_enabled():
1410            payment_pubkey = other_config.payment_basepoint.pubkey
1411        else:
1412            payment_pubkey = derive_pubkey(other_config.payment_basepoint.pubkey, this_point)
1413
1414        return make_commitment(
1415            ctn=ctn,
1416            local_funding_pubkey=this_config.multisig_key.pubkey,
1417            remote_funding_pubkey=other_config.multisig_key.pubkey,
1418            remote_payment_pubkey=payment_pubkey,
1419            funder_payment_basepoint=self.config[LOCAL if     self.constraints.is_initiator else REMOTE].payment_basepoint.pubkey,
1420            fundee_payment_basepoint=self.config[LOCAL if not self.constraints.is_initiator else REMOTE].payment_basepoint.pubkey,
1421            revocation_pubkey=other_revocation_pubkey,
1422            delayed_pubkey=derive_pubkey(this_config.delayed_basepoint.pubkey, this_point),
1423            to_self_delay=other_config.to_self_delay,
1424            funding_txid=self.funding_outpoint.txid,
1425            funding_pos=self.funding_outpoint.output_index,
1426            funding_sat=self.constraints.capacity,
1427            local_amount=local_msat,
1428            remote_amount=remote_msat,
1429            dust_limit_sat=this_config.dust_limit_sat,
1430            fees_per_participant=onchain_fees,
1431            htlcs=htlcs,
1432        )
1433
1434    def make_closing_tx(self, local_script: bytes, remote_script: bytes,
1435                        fee_sat: int, *, drop_remote = False) -> Tuple[bytes, PartialTransaction]:
1436        """ cooperative close """
1437        _, outputs = make_commitment_outputs(
1438                fees_per_participant={
1439                    LOCAL:  fee_sat * 1000 if     self.constraints.is_initiator else 0,
1440                    REMOTE: fee_sat * 1000 if not self.constraints.is_initiator else 0,
1441                },
1442                local_amount_msat=self.balance(LOCAL),
1443                remote_amount_msat=self.balance(REMOTE) if not drop_remote else 0,
1444                local_script=bh2u(local_script),
1445                remote_script=bh2u(remote_script),
1446                htlcs=[],
1447                dust_limit_sat=self.config[LOCAL].dust_limit_sat)
1448
1449        closing_tx = make_closing_tx(self.config[LOCAL].multisig_key.pubkey,
1450                                     self.config[REMOTE].multisig_key.pubkey,
1451                                     funding_txid=self.funding_outpoint.txid,
1452                                     funding_pos=self.funding_outpoint.output_index,
1453                                     funding_sat=self.constraints.capacity,
1454                                     outputs=outputs)
1455
1456        der_sig = bfh(closing_tx.sign_txin(0, self.config[LOCAL].multisig_key.privkey))
1457        sig = ecc.sig_string_from_der_sig(der_sig[:-1])
1458        return sig, closing_tx
1459
1460    def signature_fits(self, tx: PartialTransaction) -> bool:
1461        remote_sig = self.config[LOCAL].current_commitment_signature
1462        preimage_hex = tx.serialize_preimage(0)
1463        msg_hash = sha256d(bfh(preimage_hex))
1464        assert remote_sig
1465        res = ecc.verify_signature(self.config[REMOTE].multisig_key.pubkey, remote_sig, msg_hash)
1466        return res
1467
1468    def force_close_tx(self) -> PartialTransaction:
1469        tx = self.get_latest_commitment(LOCAL)
1470        assert self.signature_fits(tx)
1471        tx.sign({bh2u(self.config[LOCAL].multisig_key.pubkey): (self.config[LOCAL].multisig_key.privkey, True)})
1472        remote_sig = self.config[LOCAL].current_commitment_signature
1473        remote_sig = ecc.der_sig_from_sig_string(remote_sig) + b"\x01"
1474        tx.add_signature_to_txin(txin_idx=0,
1475                                 signing_pubkey=self.config[REMOTE].multisig_key.pubkey.hex(),
1476                                 sig=remote_sig.hex())
1477        assert tx.is_complete()
1478        return tx
1479
1480    def maybe_sweep_revoked_htlc(self, ctx: Transaction, htlc_tx: Transaction) -> Optional[SweepInfo]:
1481        # look at the output address, check if it matches
1482        return create_sweeptx_for_their_revoked_htlc(self, ctx, htlc_tx, self.sweep_address)
1483
1484    def has_pending_changes(self, subject: HTLCOwner) -> bool:
1485        next_htlcs = self.hm.get_htlcs_in_next_ctx(subject)
1486        latest_htlcs = self.hm.get_htlcs_in_latest_ctx(subject)
1487        return not (next_htlcs == latest_htlcs and self.get_next_feerate(subject) == self.get_latest_feerate(subject))
1488
1489    def should_be_closed_due_to_expiring_htlcs(self, local_height) -> bool:
1490        htlcs_we_could_reclaim = {}  # type: Dict[Tuple[Direction, int], UpdateAddHtlc]
1491        # If there is a received HTLC for which we already released the preimage
1492        # but the remote did not revoke yet, and the CLTV of this HTLC is dangerously close
1493        # to the present, then unilaterally close channel
1494        recv_htlc_deadline = lnutil.NBLOCK_DEADLINE_BEFORE_EXPIRY_FOR_RECEIVED_HTLCS
1495        for sub, dir, ctn in ((LOCAL, RECEIVED, self.get_latest_ctn(LOCAL)),
1496                              (REMOTE, SENT, self.get_oldest_unrevoked_ctn(LOCAL)),
1497                              (REMOTE, SENT, self.get_latest_ctn(LOCAL)),):
1498            for htlc_id, htlc in self.hm.htlcs_by_direction(subject=sub, direction=dir, ctn=ctn).items():
1499                if not self.hm.was_htlc_preimage_released(htlc_id=htlc_id, htlc_proposer=REMOTE):
1500                    continue
1501                if htlc.cltv_expiry - recv_htlc_deadline > local_height:
1502                    continue
1503                htlcs_we_could_reclaim[(RECEIVED, htlc_id)] = htlc
1504        # If there is an offered HTLC which has already expired (+ some grace period after), we
1505        # will unilaterally close the channel and time out the HTLC
1506        offered_htlc_deadline = lnutil.NBLOCK_DEADLINE_AFTER_EXPIRY_FOR_OFFERED_HTLCS
1507        for sub, dir, ctn in ((LOCAL, SENT, self.get_latest_ctn(LOCAL)),
1508                              (REMOTE, RECEIVED, self.get_oldest_unrevoked_ctn(LOCAL)),
1509                              (REMOTE, RECEIVED, self.get_latest_ctn(LOCAL)),):
1510            for htlc_id, htlc in self.hm.htlcs_by_direction(subject=sub, direction=dir, ctn=ctn).items():
1511                if htlc.cltv_expiry + offered_htlc_deadline > local_height:
1512                    continue
1513                htlcs_we_could_reclaim[(SENT, htlc_id)] = htlc
1514
1515        total_value_sat = sum([htlc.amount_msat // 1000 for htlc in htlcs_we_could_reclaim.values()])
1516        num_htlcs = len(htlcs_we_could_reclaim)
1517        min_value_worth_closing_channel_over_sat = max(num_htlcs * 10 * self.config[REMOTE].dust_limit_sat,
1518                                                       500_000)
1519        return total_value_sat > min_value_worth_closing_channel_over_sat
1520
1521    def is_funding_tx_mined(self, funding_height):
1522        funding_txid = self.funding_outpoint.txid
1523        funding_idx = self.funding_outpoint.output_index
1524        conf = funding_height.conf
1525        if conf < self.funding_txn_minimum_depth():
1526            self.logger.info(f"funding tx is still not at sufficient depth. actual depth: {conf}")
1527            return False
1528        assert conf > 0
1529        # check funding_tx amount and script
1530        funding_tx = self.lnworker.lnwatcher.db.get_transaction(funding_txid)
1531        if not funding_tx:
1532            self.logger.info(f"no funding_tx {funding_txid}")
1533            return False
1534        outp = funding_tx.outputs()[funding_idx]
1535        redeem_script = funding_output_script(self.config[REMOTE], self.config[LOCAL])
1536        funding_address = redeem_script_to_address('p2wsh', redeem_script)
1537        funding_sat = self.constraints.capacity
1538        if not (outp.address == funding_address and outp.value == funding_sat):
1539            self.logger.info('funding outpoint mismatch')
1540            return False
1541        return True
1542