URI: 
       tdecode onion errors to failure message type - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit bab9f163f7a7dcae2fbcf91675e7993ef8b55163
   DIR parent b85aea1541098d0284de5b92c1ca997c12c68cdc
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Wed,  1 Aug 2018 19:06:43 +0200
       
       decode onion errors to failure message type
       
       Diffstat:
         M electrum/lnbase.py                  |      18 ++++++------------
         M electrum/lnonion.py                 |      32 +++++++++++++++++++++++++++++++
       
       2 files changed, 38 insertions(+), 12 deletions(-)
       ---
   DIR diff --git a/electrum/lnbase.py b/electrum/lnbase.py
       t@@ -31,7 +31,7 @@ from . import constants
        from . import transaction
        from .util import PrintError, bh2u, print_error, bfh
        from .transaction import opcodes, Transaction
       -from .lnonion import new_onion_packet, OnionHopsDataSingle, OnionPerHop, decode_onion_error
       +from .lnonion import new_onion_packet, OnionHopsDataSingle, OnionPerHop, decode_onion_error, ONION_FAILURE_CODE_MAP
        from .lnaddr import lndecode
        from .lnhtlc import UpdateAddHtlc, HTLCStateMachine, RevokeAndAck, SettleHtlc
        
       t@@ -817,25 +817,19 @@ class Peer(PrintError):
                route = self.attempted_route[key]
                failure_msg, sender_idx = decode_onion_error(payload["reason"], [x.node_id for x in route], self.secret_key)
                code = failure_msg.code
       +        code_name = ONION_FAILURE_CODE_MAP.get(code, 'unknown_error!!')
                data = failure_msg.data
       -        codes = []
       -        if code & 0x8000:
       -            codes += ["BADONION"]
       -        if code & 0x4000:
       -            codes += ["PERM"]
       -        if code & 0x2000:
       -            codes += ["NODE"]
       -        if code & 0x1000:
       -            codes += ["UPDATE"]
       -        print("UPDATE_FAIL_HTLC", codes, code, data)
       +        print("UPDATE_FAIL_HTLC", code_name, code, data)
                try:
                    short_chan_id = route[sender_idx + 1].short_channel_id
                except IndexError:
                    print("payment destination reported error")
                else:
       +            # TODO this should depend on the error
       +            # also, we need finer blacklisting (directed edges; nodes)
                    self.network.path_finder.blacklist.add(short_chan_id)
        
       -        self.update_fail_htlc[payload["channel_id"]].put_nowait("HTLC failure with code {} (categories {})".format(code, codes))
       +        self.update_fail_htlc[payload["channel_id"]].put_nowait("HTLC failure with code {} ({})".format(code, code_name))
        
            @aiosafe
            async def pay(self, path, chan, amount_msat, payment_hash, pubkey_in_invoice, min_final_cltv_expiry):
   DIR diff --git a/electrum/lnonion.py b/electrum/lnonion.py
       t@@ -297,3 +297,35 @@ def get_failure_msg_from_onion_error(decrypted_error_packet: bytes) -> OnionRout
            failure_code = int.from_bytes(failure_msg[:2], byteorder='big')
            failure_data = failure_msg[2:]
            return OnionRoutingFailureMessage(failure_code, failure_data)
       +
       +
       +ONION_FC_BADONION = BADONION = 0x8000
       +ONION_FC_PERM     = PERM     = 0x4000
       +ONION_FC_NODE     = NODE     = 0x2000
       +ONION_FC_UPDATE   = UPDATE   = 0x1000
       +ONION_FAILURE_CODE_MAP = {
       +    PERM | 1 : 'invalid_realm',
       +    NODE | 2 : 'temporary_node_failure',
       +    PERM | NODE | 2 : 'permanent_node_failure',
       +    PERM | NODE | 3 : 'required_node_feature_missing',
       +    BADONION | PERM | 4 : 'invalid_onion_version',
       +    BADONION | PERM | 5 : 'invalid_onion_hmac',
       +    BADONION | PERM | 6 : 'invalid_onion_key',
       +    UPDATE | 7 : 'temporary_channel_failure',
       +    PERM | 8 : 'permanent_channel_failure',
       +    PERM | 9 : 'required_channel_feature_missing',
       +    PERM | 10 : 'unknown_next_peer',
       +    UPDATE | 11 : 'amount_below_minimum',
       +    UPDATE | 12 : 'fee_insufficient',
       +    UPDATE | 13 : 'incorrect_cltv_expiry',
       +    UPDATE | 14 : 'expiry_too_soon',
       +    PERM | 15 : 'unknown_payment_hash',
       +    PERM | 16 : 'incorrect_payment_amount',
       +    17 : 'final_expiry_too_soon',
       +    18 : 'final_incorrect_cltv_expiry',
       +    19 : 'final_incorrect_htlc_amount',
       +    UPDATE | 20 : 'channel_disabled',
       +    21 : 'expiry_too_far',
       +}
       +# don't use these elsewhere, the names are ambiguous without context
       +del BADONION; del PERM; del NODE; del UPDATE