Merge remote-tracking branch 'remotes/bitromortac-fork/2107-fix-self-payments'
This commit is contained in:
@@ -517,7 +517,7 @@ class LNPathFinder(Logger):
|
||||
nodeA: bytes,
|
||||
nodeB: bytes,
|
||||
invoice_amount_msat: int,
|
||||
my_channels: Dict[ShortChannelID, 'Channel'] = None,
|
||||
my_sending_channels: Dict[ShortChannelID, 'Channel'] = None,
|
||||
private_route_edges: Dict[ShortChannelID, RouteEdge] = None,
|
||||
) -> Dict[bytes, PathEdge]:
|
||||
# note: we don't lock self.channel_db, so while the path finding runs,
|
||||
@@ -551,24 +551,24 @@ class LNPathFinder(Logger):
|
||||
edge_endnode, my_channels={}, private_route_edges=private_route_edges)
|
||||
else: # in the next steps, we only take sending channels
|
||||
channels_for_endnode = self.channel_db.get_channels_for_node(
|
||||
edge_endnode, my_channels=my_channels, private_route_edges={})
|
||||
edge_endnode, my_channels=my_sending_channels, private_route_edges={})
|
||||
else:
|
||||
channels_for_endnode = self.channel_db.get_channels_for_node(
|
||||
edge_endnode, my_channels=my_channels, private_route_edges=private_route_edges)
|
||||
edge_endnode, my_channels=my_sending_channels, private_route_edges=private_route_edges)
|
||||
|
||||
for edge_channel_id in channels_for_endnode:
|
||||
assert isinstance(edge_channel_id, bytes)
|
||||
if blacklist and edge_channel_id in blacklist:
|
||||
continue
|
||||
channel_info = self.channel_db.get_channel_info(
|
||||
edge_channel_id, my_channels=my_channels, private_route_edges=private_route_edges)
|
||||
edge_channel_id, my_channels=my_sending_channels, private_route_edges=private_route_edges)
|
||||
if channel_info is None:
|
||||
continue
|
||||
edge_startnode = channel_info.node2_id if channel_info.node1_id == edge_endnode else channel_info.node1_id
|
||||
is_mine = edge_channel_id in my_channels
|
||||
is_mine = edge_channel_id in my_sending_channels
|
||||
if is_mine:
|
||||
if edge_startnode == nodeA: # payment outgoing, on our channel
|
||||
if not my_channels[edge_channel_id].can_pay(amount_msat, check_frozen=True):
|
||||
if not my_sending_channels[edge_channel_id].can_pay(amount_msat, check_frozen=True):
|
||||
continue
|
||||
edge_cost, fee_for_edge_msat = self._edge_cost(
|
||||
short_channel_id=edge_channel_id,
|
||||
@@ -577,7 +577,7 @@ class LNPathFinder(Logger):
|
||||
payment_amt_msat=amount_msat,
|
||||
ignore_costs=(edge_startnode == nodeA),
|
||||
is_mine=is_mine,
|
||||
my_channels=my_channels,
|
||||
my_channels=my_sending_channels,
|
||||
private_route_edges=private_route_edges)
|
||||
alt_dist_to_neighbour = distance_from_start[edge_endnode] + edge_cost
|
||||
if alt_dist_to_neighbour < distance_from_start[edge_startnode]:
|
||||
@@ -601,21 +601,21 @@ class LNPathFinder(Logger):
|
||||
nodeA: bytes,
|
||||
nodeB: bytes,
|
||||
invoice_amount_msat: int,
|
||||
my_channels: Dict[ShortChannelID, 'Channel'] = None,
|
||||
my_sending_channels: Dict[ShortChannelID, 'Channel'] = None,
|
||||
private_route_edges: Dict[ShortChannelID, RouteEdge] = None,
|
||||
) -> Optional[LNPaymentPath]:
|
||||
"""Return a path from nodeA to nodeB."""
|
||||
assert type(nodeA) is bytes
|
||||
assert type(nodeB) is bytes
|
||||
assert type(invoice_amount_msat) is int
|
||||
if my_channels is None:
|
||||
my_channels = {}
|
||||
if my_sending_channels is None:
|
||||
my_sending_channels = {}
|
||||
|
||||
previous_hops = self.get_shortest_path_hops(
|
||||
nodeA=nodeA,
|
||||
nodeB=nodeB,
|
||||
invoice_amount_msat=invoice_amount_msat,
|
||||
my_channels=my_channels,
|
||||
my_sending_channels=my_sending_channels,
|
||||
private_route_edges=private_route_edges)
|
||||
|
||||
if nodeA not in previous_hops:
|
||||
@@ -677,7 +677,7 @@ class LNPathFinder(Logger):
|
||||
nodeB: bytes,
|
||||
invoice_amount_msat: int,
|
||||
path = None,
|
||||
my_channels: Dict[ShortChannelID, 'Channel'] = None,
|
||||
my_sending_channels: Dict[ShortChannelID, 'Channel'] = None,
|
||||
private_route_edges: Dict[ShortChannelID, RouteEdge] = None,
|
||||
) -> Optional[LNPaymentRoute]:
|
||||
route = None
|
||||
@@ -686,9 +686,9 @@ class LNPathFinder(Logger):
|
||||
nodeA=nodeA,
|
||||
nodeB=nodeB,
|
||||
invoice_amount_msat=invoice_amount_msat,
|
||||
my_channels=my_channels,
|
||||
my_sending_channels=my_sending_channels,
|
||||
private_route_edges=private_route_edges)
|
||||
if path:
|
||||
route = self.create_route_from_path(
|
||||
path, my_channels=my_channels, private_route_edges=private_route_edges)
|
||||
path, my_channels=my_sending_channels, private_route_edges=private_route_edges)
|
||||
return route
|
||||
|
||||
@@ -1467,11 +1467,12 @@ class LNWallet(LNWorker):
|
||||
invoice_features = LnFeatures(invoice_features)
|
||||
trampoline_features = LnFeatures.VAR_ONION_OPT
|
||||
local_height = self.network.get_local_height()
|
||||
active_channels = [chan for chan in self.channels.values() if chan.is_active() and not chan.is_frozen_for_sending()]
|
||||
my_active_channels = [chan for chan in self.channels.values() if
|
||||
chan.is_active() and not chan.is_frozen_for_sending()]
|
||||
try:
|
||||
# try to send over a single channel
|
||||
if not self.channel_db:
|
||||
for chan in active_channels:
|
||||
for chan in my_active_channels:
|
||||
if not self.is_trampoline_peer(chan.node_id):
|
||||
continue
|
||||
if chan.node_id == invoice_pubkey:
|
||||
@@ -1522,7 +1523,7 @@ class LNWallet(LNWorker):
|
||||
min_cltv_expiry=min_cltv_expiry,
|
||||
r_tags=r_tags,
|
||||
invoice_features=invoice_features,
|
||||
channels=active_channels,
|
||||
my_sending_channels=my_active_channels,
|
||||
full_path=full_path
|
||||
)
|
||||
)
|
||||
@@ -1530,9 +1531,8 @@ class LNWallet(LNWorker):
|
||||
except NoPathFound:
|
||||
if not invoice_features.supports(LnFeatures.BASIC_MPP_OPT):
|
||||
raise
|
||||
channels_with_funds = {
|
||||
(chan.channel_id, chan.node_id): int(chan.available_to_spend(HTLCOwner.LOCAL))
|
||||
for chan in active_channels}
|
||||
channels_with_funds = {(chan.channel_id, chan.node_id): int(chan.available_to_spend(HTLCOwner.LOCAL))
|
||||
for chan in my_active_channels}
|
||||
self.logger.info(f"channels_with_funds: {channels_with_funds}")
|
||||
# for trampoline mpp payments we have to restrict ourselves to pay
|
||||
# to a single node due to some incompatibility in Eclair, see:
|
||||
@@ -1603,7 +1603,7 @@ class LNWallet(LNWorker):
|
||||
min_cltv_expiry=min_cltv_expiry,
|
||||
r_tags=r_tags,
|
||||
invoice_features=invoice_features,
|
||||
channels=[channel],
|
||||
my_sending_channels=[channel],
|
||||
full_path=None
|
||||
)
|
||||
)
|
||||
@@ -1623,13 +1623,11 @@ class LNWallet(LNWorker):
|
||||
min_cltv_expiry: int,
|
||||
r_tags,
|
||||
invoice_features: int,
|
||||
channels: List[Channel],
|
||||
my_sending_channels: List[Channel],
|
||||
full_path: Optional[LNPaymentPath]) -> LNPaymentRoute:
|
||||
|
||||
scid_to_my_channels = {
|
||||
chan.short_channel_id: chan for chan in channels
|
||||
if chan.short_channel_id is not None
|
||||
}
|
||||
my_sending_channels = {chan.short_channel_id: chan for chan in my_sending_channels
|
||||
if chan.short_channel_id is not None}
|
||||
# Collect all private edges from route hints.
|
||||
# Note: if some route hints are multiple edges long, and these paths cross each other,
|
||||
# we allow our path finding to cross the paths; i.e. the route hints are not isolated.
|
||||
@@ -1647,7 +1645,7 @@ class LNWallet(LNWorker):
|
||||
channel_policy = self.channel_db.get_policy_for_node(
|
||||
short_channel_id=short_channel_id,
|
||||
node_id=start_node,
|
||||
my_channels=scid_to_my_channels)
|
||||
my_channels=my_sending_channels)
|
||||
if channel_policy:
|
||||
fee_base_msat = channel_policy.fee_base_msat
|
||||
fee_proportional_millionths = channel_policy.fee_proportional_millionths
|
||||
@@ -1670,7 +1668,7 @@ class LNWallet(LNWorker):
|
||||
nodeB=invoice_pubkey,
|
||||
invoice_amount_msat=amount_msat,
|
||||
path=full_path,
|
||||
my_channels=scid_to_my_channels,
|
||||
my_sending_channels=my_sending_channels,
|
||||
private_route_edges=private_route_edges)
|
||||
except NoChannelPolicy as e:
|
||||
raise NoPathFound() from e
|
||||
|
||||
Reference in New Issue
Block a user