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