commit 10c21834613318f15bd30213fa52eaada50d1285
parent c2111a2616d2e9b759ce84304ad61d4b90f3db8f
Author: SomberNight <somber.night@protonmail.com>
Date: Wed, 24 Jun 2020 21:33:44 +0200
handle_error_code_from_failed_htlc: omg brainfart :(
follow-up 85841ba20de7cb6459066538474d3f13e010031e
Diffstat:
2 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
@@ -7,7 +7,7 @@ import os
from decimal import Decimal
import random
import time
-from typing import Optional, Sequence, Tuple, List, Dict, TYPE_CHECKING, NamedTuple, Union, Mapping
+from typing import Optional, Sequence, Tuple, List, Dict, TYPE_CHECKING, NamedTuple, Union, Mapping, Any
import threading
import socket
import aiohttp
@@ -968,21 +968,10 @@ class LNWallet(LNWorker):
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)
- if not payload['chain_hash'] != constants.net.rev_genesis_bytes(): raise Exception()
- payload['raw'] = channel_update_typed
- except: # FIXME: too broad
- try:
- message_type, payload = decode_msg(channel_update_as_received)
- if not payload['chain_hash'] != constants.net.rev_genesis_bytes(): raise Exception()
- payload['raw'] = channel_update_as_received
- except:
- self.logger.info(f'could not decode channel_update for failed htlc: {channel_update_as_received.hex()}')
- return True
+ payload = self._decode_channel_update_msg(channel_update_as_received)
+ if payload is None:
+ self.logger.info(f'could not decode channel_update for failed htlc: {channel_update_as_received.hex()}')
+ return True
r = self.channel_db.add_channel_update(payload)
blacklist = False
short_channel_id = ShortChannelID(payload['short_channel_id'])
@@ -1005,6 +994,26 @@ class LNWallet(LNWorker):
blacklist = True
return blacklist
+ @classmethod
+ def _decode_channel_update_msg(cls, chan_upd_msg: bytes) -> Optional[Dict[str, Any]]:
+ channel_update_as_received = chan_upd_msg
+ 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)
+ if payload['chain_hash'] != constants.net.rev_genesis_bytes(): raise Exception()
+ payload['raw'] = channel_update_typed
+ return payload
+ except: # FIXME: too broad
+ try:
+ message_type, payload = decode_msg(channel_update_as_received)
+ if payload['chain_hash'] != constants.net.rev_genesis_bytes(): raise Exception()
+ payload['raw'] = channel_update_as_received
+ return payload
+ except:
+ return None
+
@staticmethod
def _check_invoice(invoice: str, *, amount_msat: int = None) -> LnAddr:
addr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)
diff --git a/electrum/tests/test_lnutil.py b/electrum/tests/test_lnutil.py
@@ -11,6 +11,7 @@ from electrum.lnutil import (RevocationStore, get_per_commitment_secret_from_see
ScriptHtlc, extract_nodeid, calc_fees_for_commitment_tx, UpdateAddHtlc, LnFeatures)
from electrum.util import bh2u, bfh, MyEncoder
from electrum.transaction import Transaction, PartialTransaction
+from electrum.lnworker import LNWallet
from . import ElectrumTestCase
@@ -805,3 +806,23 @@ class TestLNUtil(ElectrumTestCase):
features.for_invoice())
features = LnFeatures.BASIC_MPP_OPT | LnFeatures.PAYMENT_SECRET_REQ | LnFeatures.VAR_ONION_REQ
self.assertEqual(features, features.for_invoice())
+
+ def test_lnworker_decode_channel_update_msg(self):
+ msg_without_prefix = bytes.fromhex("439b71c8ddeff63004e4ff1f9764a57dcf20232b79d9d669aef0e31c42be8e44208f7d868d0133acb334047f30e9399dece226ccd98e5df5330adf7f356290516fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000008762700054a00005ef2cf9c0101009000000000000003e80000000000000001000000002367b880")
+ # good messages
+ self.assertNotEqual(
+ None,
+ LNWallet._decode_channel_update_msg(msg_without_prefix))
+ self.assertNotEqual(
+ None,
+ LNWallet._decode_channel_update_msg(bytes.fromhex("0102") + msg_without_prefix))
+ # bad messages
+ self.assertEqual(
+ None,
+ LNWallet._decode_channel_update_msg(bytes.fromhex("0102030405")))
+ self.assertEqual(
+ None,
+ LNWallet._decode_channel_update_msg(bytes.fromhex("ffff") + msg_without_prefix))
+ self.assertEqual(
+ None,
+ LNWallet._decode_channel_update_msg(bytes.fromhex("0101") + msg_without_prefix))