tlnchannel.py - electrum - Electrum Bitcoin wallet
HTML git clone https://git.parazyd.org/electrum
DIR Log
DIR Files
DIR Refs
DIR Submodules
---
tlnchannel.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