channel_db: raise specific exception when channelDB not loaded, allowing lnworker to mark payment as failed. (#8431)
On mobile, it can take a while before channelDB is loaded. If payment is attempted before the DB is fully loaded, this would result in a payment failure, but also leaves the payment attempt in IN_PROGRESS state. This patch adds a more specific ChannelDBNotLoaded exception class, so we can handle this case more gracefully, since we know the payment didn't succeed.
This commit is contained in:
@@ -38,7 +38,7 @@ from aiorpcx import NetAddress
|
|||||||
|
|
||||||
from .sql_db import SqlDB, sql
|
from .sql_db import SqlDB, sql
|
||||||
from . import constants, util
|
from . import constants, util
|
||||||
from .util import profiler, get_headers_dir, is_ip_address, json_normalize
|
from .util import profiler, get_headers_dir, is_ip_address, json_normalize, UserFacingException
|
||||||
from .logging import Logger
|
from .logging import Logger
|
||||||
from .lnutil import (LNPeerAddr, format_short_channel_id, ShortChannelID,
|
from .lnutil import (LNPeerAddr, format_short_channel_id, ShortChannelID,
|
||||||
validate_features, IncompatibleOrInsaneFeatures, InvalidGossipMsg)
|
validate_features, IncompatibleOrInsaneFeatures, InvalidGossipMsg)
|
||||||
@@ -59,6 +59,9 @@ FLAG_DISABLE = 1 << 1
|
|||||||
FLAG_DIRECTION = 1 << 0
|
FLAG_DIRECTION = 1 << 0
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelDBNotLoaded(UserFacingException): pass
|
||||||
|
|
||||||
|
|
||||||
class ChannelInfo(NamedTuple):
|
class ChannelInfo(NamedTuple):
|
||||||
short_channel_id: ShortChannelID
|
short_channel_id: ShortChannelID
|
||||||
node1_id: bytes
|
node1_id: bytes
|
||||||
@@ -375,7 +378,7 @@ class ChannelDB(SqlDB):
|
|||||||
|
|
||||||
def get_recent_peers(self):
|
def get_recent_peers(self):
|
||||||
if not self.data_loaded.is_set():
|
if not self.data_loaded.is_set():
|
||||||
raise Exception("channelDB data not loaded yet!")
|
raise ChannelDBNotLoaded("channelDB data not loaded yet!")
|
||||||
with self.lock:
|
with self.lock:
|
||||||
ret = [self.get_last_good_address(node_id)
|
ret = [self.get_last_good_address(node_id)
|
||||||
for node_id in self._recent_peers]
|
for node_id in self._recent_peers]
|
||||||
@@ -842,7 +845,7 @@ class ChannelDB(SqlDB):
|
|||||||
) -> Set[ShortChannelID]:
|
) -> Set[ShortChannelID]:
|
||||||
"""Returns the set of short channel IDs where node_id is one of the channel participants."""
|
"""Returns the set of short channel IDs where node_id is one of the channel participants."""
|
||||||
if not self.data_loaded.is_set():
|
if not self.data_loaded.is_set():
|
||||||
raise Exception("channelDB data not loaded yet!")
|
raise ChannelDBNotLoaded("channelDB data not loaded yet!")
|
||||||
relevant_channels = self._channels_for_node.get(node_id) or set()
|
relevant_channels = self._channels_for_node.get(node_id) or set()
|
||||||
relevant_channels = set(relevant_channels) # copy
|
relevant_channels = set(relevant_channels) # copy
|
||||||
# add our own channels # TODO maybe slow?
|
# add our own channels # TODO maybe slow?
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ from .lnwatcher import LNWalletWatcher
|
|||||||
from .crypto import pw_encode_with_version_and_mac, pw_decode_with_version_and_mac
|
from .crypto import pw_encode_with_version_and_mac, pw_decode_with_version_and_mac
|
||||||
from .lnutil import ImportedChannelBackupStorage, OnchainChannelBackupStorage
|
from .lnutil import ImportedChannelBackupStorage, OnchainChannelBackupStorage
|
||||||
from .lnchannel import ChannelBackup
|
from .lnchannel import ChannelBackup
|
||||||
from .channel_db import UpdateStatus
|
from .channel_db import UpdateStatus, ChannelDBNotLoaded
|
||||||
from .channel_db import get_mychannel_info, get_mychannel_policy
|
from .channel_db import get_mychannel_info, get_mychannel_policy
|
||||||
from .submarine_swaps import SwapManager
|
from .submarine_swaps import SwapManager
|
||||||
from .channel_db import ChannelInfo, Policy
|
from .channel_db import ChannelInfo, Policy
|
||||||
@@ -1202,6 +1202,9 @@ class LNWallet(LNWorker):
|
|||||||
except PaymentFailure as e:
|
except PaymentFailure as e:
|
||||||
self.logger.info(f'payment failure: {e!r}')
|
self.logger.info(f'payment failure: {e!r}')
|
||||||
reason = str(e)
|
reason = str(e)
|
||||||
|
except ChannelDBNotLoaded as e:
|
||||||
|
self.logger.info(f'payment failure: {e!r}')
|
||||||
|
reason = str(e)
|
||||||
finally:
|
finally:
|
||||||
self.logger.info(f"pay_invoice ending session for RHASH={payment_hash.hex()}. {success=}")
|
self.logger.info(f"pay_invoice ending session for RHASH={payment_hash.hex()}. {success=}")
|
||||||
if success:
|
if success:
|
||||||
|
|||||||
Reference in New Issue
Block a user