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