commit 3897cf725d216db784511f99998f2c42b7eefad8
parent af4a3328f78ccc0d50efa3f6fa88facb328ef436
Author: ThomasV <thomasv@electrum.org>
Date: Sat, 12 Oct 2019 18:22:19 +0200
move handle_error_code_from_failed_htlc to lnworker because it requires access to the network object
Diffstat:
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/electrum/channel_db.py b/electrum/channel_db.py
@@ -39,8 +39,6 @@ from .util import bh2u, profiler, get_headers_dir, bfh, is_ip_address, list_enab
from .logging import Logger
from .lnutil import LN_GLOBAL_FEATURES_KNOWN_SET, LNPeerAddr, format_short_channel_id, ShortChannelID
from .lnverifier import LNChannelVerifier, verify_sig_for_channel_update
-from .lnonion import OnionFailureCode
-from .lnmsg import decode_msg
if TYPE_CHECKING:
from .network import Network
@@ -387,57 +385,6 @@ class ChannelDB(SqlDB):
# the update may be categorized as deprecated because of caching
categorized_chan_upds = self.add_channel_updates([payload], verify=False)
- def handle_error_code_from_failed_htlc(self, code, data, sender_idx, route, peer):
- # handle some specific error codes
- failure_codes = {
- OnionFailureCode.TEMPORARY_CHANNEL_FAILURE: 0,
- OnionFailureCode.AMOUNT_BELOW_MINIMUM: 8,
- OnionFailureCode.FEE_INSUFFICIENT: 8,
- OnionFailureCode.INCORRECT_CLTV_EXPIRY: 4,
- OnionFailureCode.EXPIRY_TOO_SOON: 0,
- OnionFailureCode.CHANNEL_DISABLED: 2,
- }
- if code in failure_codes:
- offset = failure_codes[code]
- channel_update_len = int.from_bytes(data[offset:offset+2], byteorder="big")
- channel_update_as_received = data[offset+2: offset+2+channel_update_len]
- channel_update_typed = (258).to_bytes(length=2, byteorder="big") + channel_update_as_received
- # note: some nodes put channel updates in error msgs with the leading msg_type already there.
- # we try decoding both ways here.
- try:
- message_type, payload = decode_msg(channel_update_typed)
- payload['raw'] = channel_update_typed
- except: # FIXME: too broad
- message_type, payload = decode_msg(channel_update_as_received)
- payload['raw'] = channel_update_as_received
- categorized_chan_upds = self.add_channel_updates([payload])
- blacklist = False
- if categorized_chan_upds.good:
- self.logger.info("applied channel update on our db")
- peer.maybe_save_remote_update(payload)
- elif categorized_chan_upds.orphaned:
- # maybe it is a private channel (and data in invoice was outdated)
- self.logger.info("maybe channel update is for private channel?")
- start_node_id = route[sender_idx].node_id
- self.add_channel_update_for_private_channel(payload, start_node_id)
- elif categorized_chan_upds.expired:
- blacklist = True
- elif categorized_chan_upds.deprecated:
- self.logger.info(f'channel update is not more recent.')
- blacklist = True
- else:
- blacklist = True
- if blacklist:
- # blacklist channel after reporter node
- # TODO this should depend on the error (even more granularity)
- # also, we need finer blacklisting (directed edges; nodes)
- try:
- short_chan_id = route[sender_idx + 1].short_channel_id
- except IndexError:
- self.logger.info("payment destination reported error")
- else:
- self.network.path_finder.add_to_blacklist(short_chan_id)
-
def create_database(self):
c = self.conn.cursor()
c.execute(create_node_info)
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
@@ -48,6 +48,8 @@ from .lnutil import (Outpoint, LNPeerAddr,
NUM_MAX_EDGES_IN_PAYMENT_PATH, SENT, RECEIVED, HTLCOwner,
UpdateAddHtlc, Direction, LnLocalFeatures, format_short_channel_id,
ShortChannelID)
+from .lnonion import OnionFailureCode
+from .lnmsg import decode_msg
from .i18n import _
from .lnrouter import RouteEdge, is_route_sane_to_use
from .address_synchronizer import TX_HEIGHT_LOCAL
@@ -888,11 +890,62 @@ class LNWallet(LNWorker):
else:
failure_msg, sender_idx = chan.decode_onion_error(reason, route, htlc.htlc_id)
code, data = failure_msg.code, failure_msg.data
- self.logger.info(f"UPDATE_FAIL_HTLC {repr(code)} {data}")
- self.logger.info(f"error reported by {bh2u(route[sender_idx].node_id)}")
- self.channel_db.handle_error_code_from_failed_htlc(code, data, sender_idx, route, peer)
+ self.handle_error_code_from_failed_htlc(code, data, sender_idx, route, peer)
return success, preimage, sender_idx, failure_msg
+ def handle_error_code_from_failed_htlc(self, code, data, sender_idx, route, peer):
+ self.logger.info(f"UPDATE_FAIL_HTLC {repr(code)} {data}")
+ self.logger.info(f"error reported by {bh2u(route[sender_idx].node_id)}")
+ # handle some specific error codes
+ failure_codes = {
+ OnionFailureCode.TEMPORARY_CHANNEL_FAILURE: 0,
+ OnionFailureCode.AMOUNT_BELOW_MINIMUM: 8,
+ OnionFailureCode.FEE_INSUFFICIENT: 8,
+ OnionFailureCode.INCORRECT_CLTV_EXPIRY: 4,
+ OnionFailureCode.EXPIRY_TOO_SOON: 0,
+ OnionFailureCode.CHANNEL_DISABLED: 2,
+ }
+ if code in failure_codes:
+ offset = failure_codes[code]
+ channel_update_len = int.from_bytes(data[offset:offset+2], byteorder="big")
+ channel_update_as_received = data[offset+2: offset+2+channel_update_len]
+ channel_update_typed = (258).to_bytes(length=2, byteorder="big") + channel_update_as_received
+ # note: some nodes put channel updates in error msgs with the leading msg_type already there.
+ # we try decoding both ways here.
+ try:
+ message_type, payload = decode_msg(channel_update_typed)
+ payload['raw'] = channel_update_typed
+ except: # FIXME: too broad
+ message_type, payload = decode_msg(channel_update_as_received)
+ payload['raw'] = channel_update_as_received
+ categorized_chan_upds = self.channel_db.add_channel_updates([payload])
+ blacklist = False
+ if categorized_chan_upds.good:
+ self.logger.info("applied channel update on our db")
+ peer.maybe_save_remote_update(payload)
+ elif categorized_chan_upds.orphaned:
+ # maybe it is a private channel (and data in invoice was outdated)
+ self.logger.info("maybe channel update is for private channel?")
+ start_node_id = route[sender_idx].node_id
+ self.channel_db.add_channel_update_for_private_channel(payload, start_node_id)
+ elif categorized_chan_upds.expired:
+ blacklist = True
+ elif categorized_chan_upds.deprecated:
+ self.logger.info(f'channel update is not more recent.')
+ blacklist = True
+ else:
+ blacklist = True
+ if blacklist:
+ # blacklist channel after reporter node
+ # TODO this should depend on the error (even more granularity)
+ # also, we need finer blacklisting (directed edges; nodes)
+ try:
+ short_chan_id = route[sender_idx + 1].short_channel_id
+ except IndexError:
+ self.logger.info("payment destination reported error")
+ else:
+ self.network.path_finder.add_to_blacklist(short_chan_id)
+
@staticmethod
def _check_invoice(invoice, amount_sat=None):
addr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)