mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-29 16:31:29 +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 cryptography.hazmat.primitives.ciphers.aead as AEAD
|
||||||
import aiorpcx
|
import aiorpcx
|
||||||
|
|
||||||
|
from .util import list_enabled_bits
|
||||||
from . import bitcoin
|
from . import bitcoin
|
||||||
from . import ecc
|
from . import ecc
|
||||||
from .ecc import sig_string_from_r_and_s, get_r_and_s_from_sig_string
|
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,
|
from .lnutil import (Outpoint, ChannelConfig, LocalState,
|
||||||
RemoteState, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore,
|
RemoteState, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore,
|
||||||
funding_output_script, get_ecdh, get_per_commitment_secret_from_seed,
|
funding_output_script, get_ecdh, get_per_commitment_secret_from_seed,
|
||||||
secret_to_pubkey, LNPeerAddr, PaymentFailure,
|
secret_to_pubkey, LNPeerAddr, PaymentFailure, LnLocalFeatures,
|
||||||
LOCAL, REMOTE, HTLCOwner, generate_keypair, LnKeyFamily)
|
LOCAL, REMOTE, HTLCOwner, generate_keypair, LnKeyFamily,
|
||||||
|
get_ln_flag_pair_of_bit)
|
||||||
from .lnrouter import NotFoundChanAnnouncementForUpdate, RouteEdge
|
from .lnrouter import NotFoundChanAnnouncementForUpdate, RouteEdge
|
||||||
|
|
||||||
|
|
||||||
|
@ -290,7 +292,10 @@ class Peer(PrintError):
|
||||||
self.announcement_signatures = defaultdict(asyncio.Queue)
|
self.announcement_signatures = defaultdict(asyncio.Queue)
|
||||||
self.closing_signed = defaultdict(asyncio.Queue)
|
self.closing_signed = defaultdict(asyncio.Queue)
|
||||||
self.payment_preimages = 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.invoices = lnworker.invoices
|
||||||
self.attempted_route = {}
|
self.attempted_route = {}
|
||||||
|
|
||||||
|
@ -442,7 +447,17 @@ class Peer(PrintError):
|
||||||
self.network.trigger_callback('ln_status')
|
self.network.trigger_callback('ln_status')
|
||||||
|
|
||||||
def on_init(self, payload):
|
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):
|
def on_channel_update(self, payload):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -39,7 +39,7 @@ from .storage import JsonDB
|
||||||
from .lnchannelverifier import LNChannelVerifier, verify_sig_for_channel_update
|
from .lnchannelverifier import LNChannelVerifier, verify_sig_for_channel_update
|
||||||
from .crypto import Hash
|
from .crypto import Hash
|
||||||
from . import ecc
|
from . import ecc
|
||||||
from .lnutil import LN_GLOBAL_FEATURE_BITS, LNPeerAddr
|
from .lnutil import LN_GLOBAL_FEATURES_KNOWN_SET, LNPeerAddr
|
||||||
|
|
||||||
|
|
||||||
class UnknownEvenFeatureBits(Exception): pass
|
class UnknownEvenFeatureBits(Exception): pass
|
||||||
|
@ -55,7 +55,7 @@ class ChannelInfo(PrintError):
|
||||||
self.features = channel_announcement_payload['features']
|
self.features = channel_announcement_payload['features']
|
||||||
enabled_features = list_enabled_bits(int.from_bytes(self.features, "big"))
|
enabled_features = list_enabled_bits(int.from_bytes(self.features, "big"))
|
||||||
for fbit in enabled_features:
|
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()
|
raise UnknownEvenFeatureBits()
|
||||||
|
|
||||||
self.channel_id = channel_announcement_payload['short_channel_id']
|
self.channel_id = channel_announcement_payload['short_channel_id']
|
||||||
|
@ -191,7 +191,7 @@ class NodeInfo(PrintError):
|
||||||
self.features = node_announcement_payload['features']
|
self.features = node_announcement_payload['features']
|
||||||
enabled_features = list_enabled_bits(int.from_bytes(self.features, "big"))
|
enabled_features = list_enabled_bits(int.from_bytes(self.features, "big"))
|
||||||
for fbit in enabled_features:
|
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()
|
raise UnknownEvenFeatureBits()
|
||||||
if not addresses_already_parsed:
|
if not addresses_already_parsed:
|
||||||
self.addresses = self.parse_addresses_field(node_announcement_payload['addresses'])
|
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())
|
return sha256(pt.get_public_key_bytes())
|
||||||
|
|
||||||
|
|
||||||
LN_LOCAL_FEATURE_BITS = {
|
class LnLocalFeatures(IntFlag):
|
||||||
0: 'option_data_loss_protect_req',
|
OPTION_DATA_LOSS_PROTECT_REQ = 1 << 0
|
||||||
1: 'option_data_loss_protect_opt',
|
OPTION_DATA_LOSS_PROTECT_OPT = 1 << 1
|
||||||
3: 'initial_routing_sync',
|
INITIAL_ROUTING_SYNC = 1 << 3
|
||||||
4: 'option_upfront_shutdown_script_req',
|
OPTION_UPFRONT_SHUTDOWN_SCRIPT_REQ = 1 << 4
|
||||||
5: 'option_upfront_shutdown_script_opt',
|
OPTION_UPFRONT_SHUTDOWN_SCRIPT_OPT = 1 << 5
|
||||||
6: 'gossip_queries_req',
|
GOSSIP_QUERIES_REQ = 1 << 6
|
||||||
7: 'gossip_queries_opt',
|
GOSSIP_QUERIES_OPT = 1 << 7
|
||||||
}
|
|
||||||
LN_LOCAL_FEATURE_BITS_INV = inv_dict(LN_LOCAL_FEATURE_BITS)
|
|
||||||
|
|
||||||
LN_GLOBAL_FEATURE_BITS = {}
|
# note that these are powers of two, not the bits themselves
|
||||||
LN_GLOBAL_FEATURE_BITS_INV = inv_dict(LN_GLOBAL_FEATURE_BITS)
|
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'])):
|
class LNPeerAddr(namedtuple('LNPeerAddr', ['host', 'port', 'pubkey'])):
|
||||||
|
|
Loading…
Add table
Reference in a new issue