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