Browse Source

lnutil+lnwire: implement ChannelType

patch-4
bitromortac 3 years ago
parent
commit
401a429080
No known key found for this signature in database GPG Key ID: 1965063FC13BEBE2
  1. 53
      electrum/lnutil.py
  2. 4
      electrum/lnwire/peer_wire.csv
  3. 14
      electrum/tests/test_lnutil.py

53
electrum/lnutil.py

@ -8,7 +8,6 @@ import json
from collections import namedtuple, defaultdict
from typing import NamedTuple, List, Tuple, Mapping, Optional, TYPE_CHECKING, Union, Dict, Set, Sequence
import re
import time
import attr
from aiorpcx import NetAddress
@ -1029,6 +1028,12 @@ class LnFeatures(IntFlag):
_ln_feature_contexts[OPTION_SHUTDOWN_ANYSEGWIT_REQ] = (LNFC.INIT | LNFC.NODE_ANN)
_ln_feature_contexts[OPTION_SHUTDOWN_ANYSEGWIT_OPT] = (LNFC.INIT | LNFC.NODE_ANN)
OPTION_CHANNEL_TYPE_REQ = 1 << 44
OPTION_CHANNEL_TYPE_OPT = 1 << 45
_ln_feature_contexts[OPTION_CHANNEL_TYPE_REQ] = (LNFC.INIT | LNFC.NODE_ANN)
_ln_feature_contexts[OPTION_CHANNEL_TYPE_OPT] = (LNFC.INIT | LNFC.NODE_ANN)
# temporary
OPTION_TRAMPOLINE_ROUTING_REQ_ECLAIR = 1 << 50
OPTION_TRAMPOLINE_ROUTING_OPT_ECLAIR = 1 << 51
@ -1103,6 +1108,52 @@ class LnFeatures(IntFlag):
or get_ln_flag_pair_of_bit(flag) in our_flags)
class ChannelType(IntFlag):
OPTION_LEGACY_CHANNEL = 0
OPTION_STATIC_REMOTEKEY = 1 << 12
OPTION_ANCHOR_OUTPUTS = 1 << 20
OPTION_ANCHORS_ZERO_FEE_HTLC_TX = 1 << 22
def discard_unknown_and_check(self):
"""Discards unknown flags and checks flag combination."""
flags = list_enabled_bits(self)
known_channel_types = []
for flag in flags:
channel_type = ChannelType(1 << flag)
if channel_type.name:
known_channel_types.append(channel_type)
final_channel_type = known_channel_types[0]
for channel_type in known_channel_types[1:]:
final_channel_type |= channel_type
final_channel_type.check_combinations()
return final_channel_type
def check_combinations(self):
if self == ChannelType.OPTION_STATIC_REMOTEKEY:
pass
elif self == ChannelType.OPTION_ANCHOR_OUTPUTS | ChannelType.OPTION_STATIC_REMOTEKEY:
pass
elif self == ChannelType.OPTION_ANCHORS_ZERO_FEE_HTLC_TX | ChannelType.OPTION_STATIC_REMOTEKEY:
pass
else:
raise ValueError("Channel type is not a valid flag combination.")
def complies_with_features(self, features: LnFeatures) -> bool:
flags = list_enabled_bits(self)
complies = True
for flag in flags:
feature = LnFeatures(1 << flag)
complies &= features.supports(feature)
return complies
def to_bytes_minimal(self):
# MUST use the smallest bitmap possible to represent the channel type.
bit_length =self.value.bit_length()
byte_length = bit_length // 8 + int(bool(bit_length % 8))
return self.to_bytes(byte_length, byteorder='big')
del LNFC # name is ambiguous without context
# features that are actually implemented and understood in our codebase:

4
electrum/lnwire/peer_wire.csv

@ -53,6 +53,8 @@ msgdata,open_channel,channel_flags,byte,
msgdata,open_channel,tlvs,open_channel_tlvs,
tlvtype,open_channel_tlvs,upfront_shutdown_script,0
tlvdata,open_channel_tlvs,upfront_shutdown_script,shutdown_scriptpubkey,byte,...
tlvtype,open_channel_tlvs,channel_type,1
tlvdata,open_channel_tlvs,channel_type,type,byte,...
msgtype,accept_channel,33
msgdata,accept_channel,temporary_channel_id,byte,32
msgdata,accept_channel,dust_limit_satoshis,u64,
@ -71,6 +73,8 @@ msgdata,accept_channel,first_per_commitment_point,point,
msgdata,accept_channel,tlvs,accept_channel_tlvs,
tlvtype,accept_channel_tlvs,upfront_shutdown_script,0
tlvdata,accept_channel_tlvs,upfront_shutdown_script,shutdown_scriptpubkey,byte,...
tlvtype,accept_channel_tlvs,channel_type,1
tlvdata,accept_channel_tlvs,channel_type,type,byte,...
msgtype,funding_created,34
msgdata,funding_created,temporary_channel_id,byte,32
msgdata,funding_created,funding_txid,sha256,

Can't render this file because it has a wrong number of fields in line 2.

14
electrum/tests/test_lnutil.py

@ -9,7 +9,7 @@ from electrum.lnutil import (RevocationStore, get_per_commitment_secret_from_see
derive_pubkey, make_htlc_tx, extract_ctn_from_tx, UnableToDeriveSecret,
get_compressed_pubkey_from_bech32, split_host_port, ConnStringFormatError,
ScriptHtlc, extract_nodeid, calc_fees_for_commitment_tx, UpdateAddHtlc, LnFeatures,
ln_compare_features, IncompatibleLightningFeatures)
ln_compare_features, IncompatibleLightningFeatures, ChannelType)
from electrum.util import bh2u, bfh, MyEncoder
from electrum.transaction import Transaction, PartialTransaction
from electrum.lnworker import LNWallet
@ -890,3 +890,15 @@ class TestLNUtil(ElectrumTestCase):
self.assertEqual(
None,
LNWallet._decode_channel_update_msg(bytes.fromhex("0101") + msg_without_prefix))
def test_channel_type(self):
# test compliance and non compliance with LN features
features = LnFeatures(LnFeatures.BASIC_MPP_OPT | LnFeatures.OPTION_STATIC_REMOTEKEY_OPT)
self.assertTrue(ChannelType.OPTION_STATIC_REMOTEKEY.complies_with_features(features))
features = LnFeatures(LnFeatures.BASIC_MPP_OPT | LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT)
self.assertFalse(ChannelType.OPTION_STATIC_REMOTEKEY.complies_with_features(features))
# ignore unknown channel types
channel_type = ChannelType(0b10000000001000000000010).discard_unknown_and_check()
self.assertEqual(ChannelType(0b10000000001000000000000), channel_type)
Loading…
Cancel
Save