|
@ -39,13 +39,14 @@ from .ecc import der_sig_from_sig_string |
|
|
from .ecc_fast import is_using_fast_ecc |
|
|
from .ecc_fast import is_using_fast_ecc |
|
|
from .lnchannel import Channel, ChannelJsonEncoder |
|
|
from .lnchannel import Channel, ChannelJsonEncoder |
|
|
from . import lnutil |
|
|
from . import lnutil |
|
|
from .lnutil import (Outpoint, calc_short_channel_id, LNPeerAddr, |
|
|
from .lnutil import (Outpoint, LNPeerAddr, |
|
|
get_compressed_pubkey_from_bech32, extract_nodeid, |
|
|
get_compressed_pubkey_from_bech32, extract_nodeid, |
|
|
PaymentFailure, split_host_port, ConnStringFormatError, |
|
|
PaymentFailure, split_host_port, ConnStringFormatError, |
|
|
generate_keypair, LnKeyFamily, LOCAL, REMOTE, |
|
|
generate_keypair, LnKeyFamily, LOCAL, REMOTE, |
|
|
UnknownPaymentHash, MIN_FINAL_CLTV_EXPIRY_FOR_INVOICE, |
|
|
UnknownPaymentHash, MIN_FINAL_CLTV_EXPIRY_FOR_INVOICE, |
|
|
NUM_MAX_EDGES_IN_PAYMENT_PATH, SENT, RECEIVED, HTLCOwner, |
|
|
NUM_MAX_EDGES_IN_PAYMENT_PATH, SENT, RECEIVED, HTLCOwner, |
|
|
UpdateAddHtlc, Direction, LnLocalFeatures, format_short_channel_id) |
|
|
UpdateAddHtlc, Direction, LnLocalFeatures, format_short_channel_id, |
|
|
|
|
|
ShortChannelID) |
|
|
from .i18n import _ |
|
|
from .i18n import _ |
|
|
from .lnrouter import RouteEdge, is_route_sane_to_use |
|
|
from .lnrouter import RouteEdge, is_route_sane_to_use |
|
|
from .address_synchronizer import TX_HEIGHT_LOCAL |
|
|
from .address_synchronizer import TX_HEIGHT_LOCAL |
|
@ -553,10 +554,11 @@ class LNWallet(LNWorker): |
|
|
if conf > 0: |
|
|
if conf > 0: |
|
|
block_height, tx_pos = self.lnwatcher.get_txpos(chan.funding_outpoint.txid) |
|
|
block_height, tx_pos = self.lnwatcher.get_txpos(chan.funding_outpoint.txid) |
|
|
assert tx_pos >= 0 |
|
|
assert tx_pos >= 0 |
|
|
chan.short_channel_id_predicted = calc_short_channel_id(block_height, tx_pos, chan.funding_outpoint.output_index) |
|
|
chan.short_channel_id_predicted = ShortChannelID.from_components( |
|
|
|
|
|
block_height, tx_pos, chan.funding_outpoint.output_index) |
|
|
if conf >= chan.constraints.funding_txn_minimum_depth > 0: |
|
|
if conf >= chan.constraints.funding_txn_minimum_depth > 0: |
|
|
self.logger.info(f"save_short_channel_id") |
|
|
|
|
|
chan.short_channel_id = chan.short_channel_id_predicted |
|
|
chan.short_channel_id = chan.short_channel_id_predicted |
|
|
|
|
|
self.logger.info(f"save_short_channel_id: {chan.short_channel_id}") |
|
|
self.save_channel(chan) |
|
|
self.save_channel(chan) |
|
|
self.on_channels_updated() |
|
|
self.on_channels_updated() |
|
|
else: |
|
|
else: |
|
@ -795,7 +797,7 @@ class LNWallet(LNWorker): |
|
|
else: |
|
|
else: |
|
|
self.network.trigger_callback('payment_status', key, 'failure') |
|
|
self.network.trigger_callback('payment_status', key, 'failure') |
|
|
|
|
|
|
|
|
def get_channel_by_short_id(self, short_channel_id): |
|
|
def get_channel_by_short_id(self, short_channel_id: ShortChannelID) -> Channel: |
|
|
with self.lock: |
|
|
with self.lock: |
|
|
for chan in self.channels.values(): |
|
|
for chan in self.channels.values(): |
|
|
if chan.short_channel_id == short_channel_id: |
|
|
if chan.short_channel_id == short_channel_id: |
|
@ -815,7 +817,7 @@ class LNWallet(LNWorker): |
|
|
for i in range(attempts): |
|
|
for i in range(attempts): |
|
|
route = await self._create_route_from_invoice(decoded_invoice=addr) |
|
|
route = await self._create_route_from_invoice(decoded_invoice=addr) |
|
|
if not self.get_channel_by_short_id(route[0].short_channel_id): |
|
|
if not self.get_channel_by_short_id(route[0].short_channel_id): |
|
|
scid = format_short_channel_id(route[0].short_channel_id) |
|
|
scid = route[0].short_channel_id |
|
|
raise Exception(f"Got route with unknown first channel: {scid}") |
|
|
raise Exception(f"Got route with unknown first channel: {scid}") |
|
|
self.network.trigger_callback('payment_status', key, 'progress', i) |
|
|
self.network.trigger_callback('payment_status', key, 'progress', i) |
|
|
if await self._pay_to_route(route, addr, invoice): |
|
|
if await self._pay_to_route(route, addr, invoice): |
|
@ -826,8 +828,8 @@ class LNWallet(LNWorker): |
|
|
short_channel_id = route[0].short_channel_id |
|
|
short_channel_id = route[0].short_channel_id |
|
|
chan = self.get_channel_by_short_id(short_channel_id) |
|
|
chan = self.get_channel_by_short_id(short_channel_id) |
|
|
if not chan: |
|
|
if not chan: |
|
|
scid = format_short_channel_id(short_channel_id) |
|
|
raise Exception(f"PathFinder returned path with short_channel_id " |
|
|
raise Exception(f"PathFinder returned path with short_channel_id {scid} that is not in channel list") |
|
|
f"{short_channel_id} that is not in channel list") |
|
|
peer = self.peers[route[0].node_id] |
|
|
peer = self.peers[route[0].node_id] |
|
|
htlc = await peer.pay(route, chan, int(addr.amount * COIN * 1000), addr.paymenthash, addr.get_min_final_cltv_expiry()) |
|
|
htlc = await peer.pay(route, chan, int(addr.amount * COIN * 1000), addr.paymenthash, addr.get_min_final_cltv_expiry()) |
|
|
self.network.trigger_callback('htlc_added', htlc, addr, SENT) |
|
|
self.network.trigger_callback('htlc_added', htlc, addr, SENT) |
|
@ -879,6 +881,7 @@ class LNWallet(LNWorker): |
|
|
prev_node_id = border_node_pubkey |
|
|
prev_node_id = border_node_pubkey |
|
|
for node_pubkey, edge_rest in zip(private_route_nodes, private_route_rest): |
|
|
for node_pubkey, edge_rest in zip(private_route_nodes, private_route_rest): |
|
|
short_channel_id, fee_base_msat, fee_proportional_millionths, cltv_expiry_delta = edge_rest |
|
|
short_channel_id, fee_base_msat, fee_proportional_millionths, cltv_expiry_delta = edge_rest |
|
|
|
|
|
short_channel_id = ShortChannelID(short_channel_id) |
|
|
# if we have a routing policy for this edge in the db, that takes precedence, |
|
|
# if we have a routing policy for this edge in the db, that takes precedence, |
|
|
# as it is likely from a previous failure |
|
|
# as it is likely from a previous failure |
|
|
channel_policy = self.channel_db.get_routing_policy_for_channel(prev_node_id, short_channel_id) |
|
|
channel_policy = self.channel_db.get_routing_policy_for_channel(prev_node_id, short_channel_id) |
|
@ -1030,7 +1033,7 @@ class LNWallet(LNWorker): |
|
|
if amount_sat and chan.balance(REMOTE) // 1000 < amount_sat: |
|
|
if amount_sat and chan.balance(REMOTE) // 1000 < amount_sat: |
|
|
continue |
|
|
continue |
|
|
chan_id = chan.short_channel_id |
|
|
chan_id = chan.short_channel_id |
|
|
assert type(chan_id) is bytes, chan_id |
|
|
assert isinstance(chan_id, bytes), chan_id |
|
|
channel_info = self.channel_db.get_channel_info(chan_id) |
|
|
channel_info = self.channel_db.get_channel_info(chan_id) |
|
|
# note: as a fallback, if we don't have a channel update for the |
|
|
# note: as a fallback, if we don't have a channel update for the |
|
|
# incoming direction of our private channel, we fill the invoice with garbage. |
|
|
# incoming direction of our private channel, we fill the invoice with garbage. |
|
@ -1048,8 +1051,7 @@ class LNWallet(LNWorker): |
|
|
cltv_expiry_delta = policy.cltv_expiry_delta |
|
|
cltv_expiry_delta = policy.cltv_expiry_delta |
|
|
missing_info = False |
|
|
missing_info = False |
|
|
if missing_info: |
|
|
if missing_info: |
|
|
scid = format_short_channel_id(chan_id) |
|
|
self.logger.info(f"Warning. Missing channel update for our channel {chan_id}; " |
|
|
self.logger.info(f"Warning. Missing channel update for our channel {scid}; " |
|
|
|
|
|
f"filling invoice with incorrect data.") |
|
|
f"filling invoice with incorrect data.") |
|
|
routing_hints.append(('r', [(chan.node_id, |
|
|
routing_hints.append(('r', [(chan.node_id, |
|
|
chan_id, |
|
|
chan_id, |
|
|