mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-29 08:21:27 +00:00
clean up local/global features
This commit is contained in:
parent
4d32478f30
commit
eced61123d
3 changed files with 51 additions and 19 deletions
|
@ -17,6 +17,7 @@ from typing import List
|
|||
import cryptography.hazmat.primitives.ciphers.aead as AEAD
|
||||
import aiorpcx
|
||||
|
||||
from .util import list_enabled_bits
|
||||
from . import bitcoin
|
||||
from . import ecc
|
||||
from .ecc import sig_string_from_r_and_s, get_r_and_s_from_sig_string
|
||||
|
@ -30,8 +31,9 @@ from .lnhtlc import HTLCStateMachine, RevokeAndAck
|
|||
from .lnutil import (Outpoint, ChannelConfig, LocalState,
|
||||
RemoteState, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore,
|
||||
funding_output_script, get_ecdh, get_per_commitment_secret_from_seed,
|
||||
secret_to_pubkey, LNPeerAddr, PaymentFailure,
|
||||
LOCAL, REMOTE, HTLCOwner, generate_keypair, LnKeyFamily)
|
||||
secret_to_pubkey, LNPeerAddr, PaymentFailure, LnLocalFeatures,
|
||||
LOCAL, REMOTE, HTLCOwner, generate_keypair, LnKeyFamily,
|
||||
get_ln_flag_pair_of_bit)
|
||||
from .lnrouter import NotFoundChanAnnouncementForUpdate, RouteEdge
|
||||
|
||||
|
||||
|
@ -290,7 +292,10 @@ class Peer(PrintError):
|
|||
self.announcement_signatures = defaultdict(asyncio.Queue)
|
||||
self.closing_signed = defaultdict(asyncio.Queue)
|
||||
self.payment_preimages = defaultdict(asyncio.Queue)
|
||||
self.localfeatures = (0x08 if request_initial_sync else 0)
|
||||
self.localfeatures = LnLocalFeatures(0)
|
||||
if request_initial_sync:
|
||||
self.localfeatures |= LnLocalFeatures.INITIAL_ROUTING_SYNC
|
||||
self.localfeatures |= LnLocalFeatures.OPTION_DATA_LOSS_PROTECT_OPT
|
||||
self.invoices = lnworker.invoices
|
||||
self.attempted_route = {}
|
||||
|
||||
|
@ -442,7 +447,17 @@ class Peer(PrintError):
|
|||
self.network.trigger_callback('ln_status')
|
||||
|
||||
def on_init(self, payload):
|
||||
pass
|
||||
# if they required some even flag we don't have, they will close themselves
|
||||
# but if we require an even flag they don't have, we close
|
||||
our_flags = set(list_enabled_bits(self.localfeatures))
|
||||
their_flags = set(list_enabled_bits(int.from_bytes(payload['localfeatures'], byteorder="big")))
|
||||
for flag in our_flags:
|
||||
if flag not in their_flags and get_ln_flag_pair_of_bit(flag) not in their_flags:
|
||||
# they don't have this feature we wanted :(
|
||||
if flag % 2 == 0: # even flags are compulsory
|
||||
raise LightningPeerConnectionClosed("remote does not have even flag {}"
|
||||
.format(str(LnLocalFeatures(1 << flag))))
|
||||
self.localfeatures ^= 1 << flag # disable flag
|
||||
|
||||
def on_channel_update(self, payload):
|
||||
try:
|
||||
|
|
|
@ -39,7 +39,7 @@ from .storage import JsonDB
|
|||
from .lnchannelverifier import LNChannelVerifier, verify_sig_for_channel_update
|
||||
from .crypto import Hash
|
||||
from . import ecc
|
||||
from .lnutil import LN_GLOBAL_FEATURE_BITS, LNPeerAddr
|
||||
from .lnutil import LN_GLOBAL_FEATURES_KNOWN_SET, LNPeerAddr
|
||||
|
||||
|
||||
class UnknownEvenFeatureBits(Exception): pass
|
||||
|
@ -55,7 +55,7 @@ class ChannelInfo(PrintError):
|
|||
self.features = channel_announcement_payload['features']
|
||||
enabled_features = list_enabled_bits(int.from_bytes(self.features, "big"))
|
||||
for fbit in enabled_features:
|
||||
if fbit not in LN_GLOBAL_FEATURE_BITS and fbit % 2 == 0:
|
||||
if (1 << fbit) not in LN_GLOBAL_FEATURES_KNOWN_SET and fbit % 2 == 0:
|
||||
raise UnknownEvenFeatureBits()
|
||||
|
||||
self.channel_id = channel_announcement_payload['short_channel_id']
|
||||
|
@ -191,7 +191,7 @@ class NodeInfo(PrintError):
|
|||
self.features = node_announcement_payload['features']
|
||||
enabled_features = list_enabled_bits(int.from_bytes(self.features, "big"))
|
||||
for fbit in enabled_features:
|
||||
if fbit not in LN_GLOBAL_FEATURE_BITS and fbit % 2 == 0:
|
||||
if (1 << fbit) not in LN_GLOBAL_FEATURES_KNOWN_SET and fbit % 2 == 0:
|
||||
raise UnknownEvenFeatureBits()
|
||||
if not addresses_already_parsed:
|
||||
self.addresses = self.parse_addresses_field(node_announcement_payload['addresses'])
|
||||
|
|
|
@ -426,19 +426,36 @@ def get_ecdh(priv: bytes, pub: bytes) -> bytes:
|
|||
return sha256(pt.get_public_key_bytes())
|
||||
|
||||
|
||||
LN_LOCAL_FEATURE_BITS = {
|
||||
0: 'option_data_loss_protect_req',
|
||||
1: 'option_data_loss_protect_opt',
|
||||
3: 'initial_routing_sync',
|
||||
4: 'option_upfront_shutdown_script_req',
|
||||
5: 'option_upfront_shutdown_script_opt',
|
||||
6: 'gossip_queries_req',
|
||||
7: 'gossip_queries_opt',
|
||||
}
|
||||
LN_LOCAL_FEATURE_BITS_INV = inv_dict(LN_LOCAL_FEATURE_BITS)
|
||||
class LnLocalFeatures(IntFlag):
|
||||
OPTION_DATA_LOSS_PROTECT_REQ = 1 << 0
|
||||
OPTION_DATA_LOSS_PROTECT_OPT = 1 << 1
|
||||
INITIAL_ROUTING_SYNC = 1 << 3
|
||||
OPTION_UPFRONT_SHUTDOWN_SCRIPT_REQ = 1 << 4
|
||||
OPTION_UPFRONT_SHUTDOWN_SCRIPT_OPT = 1 << 5
|
||||
GOSSIP_QUERIES_REQ = 1 << 6
|
||||
GOSSIP_QUERIES_OPT = 1 << 7
|
||||
|
||||
LN_GLOBAL_FEATURE_BITS = {}
|
||||
LN_GLOBAL_FEATURE_BITS_INV = inv_dict(LN_GLOBAL_FEATURE_BITS)
|
||||
# note that these are powers of two, not the bits themselves
|
||||
LN_LOCAL_FEATURES_KNOWN_SET = set(LnLocalFeatures)
|
||||
|
||||
|
||||
def get_ln_flag_pair_of_bit(flag_bit: int):
|
||||
"""Ln Feature flags are assigned in pairs, one even, one odd. See BOLT-09.
|
||||
Return the other flag from the pair.
|
||||
e.g. 6 -> 7
|
||||
e.g. 7 -> 6
|
||||
"""
|
||||
if flag_bit % 2 == 0:
|
||||
return flag_bit + 1
|
||||
else:
|
||||
return flag_bit - 1
|
||||
|
||||
|
||||
class LnGlobalFeatures(IntFlag):
|
||||
pass
|
||||
|
||||
# note that these are powers of two, not the bits themselves
|
||||
LN_GLOBAL_FEATURES_KNOWN_SET = set(LnGlobalFeatures)
|
||||
|
||||
|
||||
class LNPeerAddr(namedtuple('LNPeerAddr', ['host', 'port', 'pubkey'])):
|
||||
|
|
Loading…
Add table
Reference in a new issue