|
|
@ -28,6 +28,7 @@ from typing import (Optional, Dict, List, Tuple, NamedTuple, Set, Callable, |
|
|
|
import time |
|
|
|
import threading |
|
|
|
from abc import ABC, abstractmethod |
|
|
|
import itertools |
|
|
|
|
|
|
|
from aiorpcx import NetAddress |
|
|
|
import attr |
|
|
@ -37,7 +38,7 @@ from . import constants, util |
|
|
|
from .util import bfh, bh2u, chunks, TxMinedInfo, PR_PAID |
|
|
|
from .bitcoin import redeem_script_to_address |
|
|
|
from .crypto import sha256, sha256d |
|
|
|
from .transaction import Transaction, PartialTransaction |
|
|
|
from .transaction import Transaction, PartialTransaction, TxInput |
|
|
|
from .logging import Logger |
|
|
|
from .lnonion import decode_onion_error, OnionFailureCode, OnionRoutingFailureMessage |
|
|
|
from . import lnutil |
|
|
@ -971,46 +972,37 @@ class Channel(AbstractChannel): |
|
|
|
failure_message = OnionRoutingFailureMessage.from_bytes(bytes.fromhex(failure_hex)) if failure_hex else None |
|
|
|
return error_bytes, failure_message |
|
|
|
|
|
|
|
def extract_preimage_from_htlc_tx(self, tx): |
|
|
|
for _input in tx.inputs(): |
|
|
|
witness = _input.witness_elements() |
|
|
|
if len(witness) == 5: |
|
|
|
preimage = witness[3] |
|
|
|
elif len(witness) == 3: |
|
|
|
preimage = witness[1] |
|
|
|
else: |
|
|
|
continue |
|
|
|
payment_hash = sha256(preimage) |
|
|
|
for direction, htlc in self.hm.get_htlcs_in_oldest_unrevoked_ctx(REMOTE): |
|
|
|
def extract_preimage_from_htlc_txin(self, txin: TxInput) -> None: |
|
|
|
witness = txin.witness_elements() |
|
|
|
if len(witness) == 5: # HTLC success tx |
|
|
|
preimage = witness[3] |
|
|
|
elif len(witness) == 3: # spending offered HTLC directly from ctx |
|
|
|
preimage = witness[1] |
|
|
|
else: |
|
|
|
return |
|
|
|
payment_hash = sha256(preimage) |
|
|
|
for direction, htlc in itertools.chain(self.hm.get_htlcs_in_oldest_unrevoked_ctx(REMOTE), |
|
|
|
self.hm.get_htlcs_in_latest_ctx(REMOTE)): |
|
|
|
if htlc.payment_hash == payment_hash: |
|
|
|
is_sent = direction == RECEIVED |
|
|
|
break |
|
|
|
else: |
|
|
|
for direction, htlc in itertools.chain(self.hm.get_htlcs_in_oldest_unrevoked_ctx(LOCAL), |
|
|
|
self.hm.get_htlcs_in_latest_ctx(LOCAL)): |
|
|
|
if htlc.payment_hash == payment_hash: |
|
|
|
is_sent = direction == RECEIVED |
|
|
|
is_sent = direction == SENT |
|
|
|
break |
|
|
|
else: |
|
|
|
for direction, htlc in self.hm.get_htlcs_in_latest_ctx(REMOTE): |
|
|
|
if htlc.payment_hash == payment_hash: |
|
|
|
is_sent = direction == RECEIVED |
|
|
|
break |
|
|
|
else: |
|
|
|
for direction, htlc in self.hm.get_htlcs_in_oldest_unrevoked_ctx(LOCAL): |
|
|
|
if htlc.payment_hash == payment_hash: |
|
|
|
is_sent = direction == SENT |
|
|
|
break |
|
|
|
else: |
|
|
|
for direction, htlc in self.hm.get_htlcs_in_latest_ctx(LOCAL): |
|
|
|
if htlc.payment_hash == payment_hash: |
|
|
|
is_sent = direction == SENT |
|
|
|
break |
|
|
|
else: |
|
|
|
continue |
|
|
|
if self.lnworker.get_preimage(payment_hash) is None: |
|
|
|
self.logger.info(f'found preimage for {payment_hash.hex()} in witness of length {len(witness)}') |
|
|
|
self.lnworker.save_preimage(payment_hash, preimage) |
|
|
|
info = self.lnworker.get_payment_info(payment_hash) |
|
|
|
if info is not None and info.status != PR_PAID: |
|
|
|
if is_sent: |
|
|
|
self.lnworker.payment_sent(self, payment_hash) |
|
|
|
else: |
|
|
|
self.lnworker.payment_received(self, payment_hash) |
|
|
|
return |
|
|
|
if self.lnworker.get_preimage(payment_hash) is None: |
|
|
|
self.logger.info(f'found preimage for {payment_hash.hex()} in witness of length {len(witness)}') |
|
|
|
self.lnworker.save_preimage(payment_hash, preimage) |
|
|
|
info = self.lnworker.get_payment_info(payment_hash) |
|
|
|
if info is not None and info.status != PR_PAID: |
|
|
|
if is_sent: |
|
|
|
self.lnworker.payment_sent(self, payment_hash) |
|
|
|
else: |
|
|
|
self.lnworker.payment_received(self, payment_hash) |
|
|
|
|
|
|
|
def balance(self, whose: HTLCOwner, *, ctx_owner=HTLCOwner.LOCAL, ctn: int = None) -> int: |
|
|
|
assert type(whose) is HTLCOwner |
|
|
|