select peers with desired features before connecting
This commit is contained in:
@@ -23,7 +23,7 @@ from . import bitcoin
|
||||
from . import ecc
|
||||
from .ecc import sig_string_from_r_and_s, get_r_and_s_from_sig_string, der_sig_from_sig_string
|
||||
from . import constants
|
||||
from .util import bh2u, bfh, log_exceptions, list_enabled_bits, ignore_exceptions, chunks, SilentTaskGroup
|
||||
from .util import bh2u, bfh, log_exceptions, ignore_exceptions, chunks, SilentTaskGroup
|
||||
from .transaction import Transaction, TxOutput, PartialTxOutput
|
||||
from .logging import Logger
|
||||
from .lnonion import (new_onion_packet, decode_onion_error, OnionFailureCode, calc_hops_data_for_payment,
|
||||
@@ -36,7 +36,7 @@ from .lnutil import (Outpoint, LocalConfig, RECEIVED, UpdateAddHtlc,
|
||||
funding_output_script, get_per_commitment_secret_from_seed,
|
||||
secret_to_pubkey, PaymentFailure, LnLocalFeatures,
|
||||
LOCAL, REMOTE, HTLCOwner, generate_keypair, LnKeyFamily,
|
||||
get_ln_flag_pair_of_bit, privkey_to_pubkey, UnknownPaymentHash, MIN_FINAL_CLTV_EXPIRY_ACCEPTED,
|
||||
ln_compare_features, privkey_to_pubkey, UnknownPaymentHash, MIN_FINAL_CLTV_EXPIRY_ACCEPTED,
|
||||
LightningPeerConnectionClosed, HandshakeFailed, NotFoundChanAnnouncementForUpdate,
|
||||
MINIMUM_MAX_HTLC_VALUE_IN_FLIGHT_ACCEPTED, MAXIMUM_HTLC_MINIMUM_MSAT_ACCEPTED,
|
||||
MAXIMUM_REMOTE_TO_SELF_DELAY_ACCEPTED, RemoteMisbehaving, DEFAULT_TO_SELF_DELAY,
|
||||
@@ -187,21 +187,10 @@ class Peer(Logger):
|
||||
# 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
|
||||
their_localfeatures = int.from_bytes(payload['localfeatures'], byteorder="big")
|
||||
our_flags = set(list_enabled_bits(self.localfeatures))
|
||||
their_flags = set(list_enabled_bits(their_localfeatures))
|
||||
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 GracefulDisconnect("remote does not support {}"
|
||||
.format(str(LnLocalFeatures(1 << flag))))
|
||||
self.localfeatures ^= 1 << flag # disable flag
|
||||
else:
|
||||
# They too have this flag.
|
||||
# For easier feature-bit-testing, if this is an even flag, we also
|
||||
# set the corresponding odd flag now.
|
||||
if flag % 2 == 0 and self.localfeatures & (1 << flag):
|
||||
self.localfeatures |= 1 << get_ln_flag_pair_of_bit(flag)
|
||||
try:
|
||||
self.localfeatures = ln_compare_features(self.localfeatures, their_localfeatures)
|
||||
except ValueError as e:
|
||||
raise GracefulDisconnect(f"remote does not support {str(e)}")
|
||||
if isinstance(self.transport, LNTransport):
|
||||
self.channel_db.add_recent_peer(self.transport.peer_addr)
|
||||
self._received_init = True
|
||||
|
||||
@@ -12,6 +12,7 @@ import attr
|
||||
from aiorpcx import NetAddress
|
||||
|
||||
from .util import bfh, bh2u, inv_dict, UserFacingException
|
||||
from .util import list_enabled_bits
|
||||
from .crypto import sha256
|
||||
from .transaction import (Transaction, PartialTransaction, PartialTxInput, TxOutpoint,
|
||||
PartialTxOutput, opcodes, TxOutput)
|
||||
@@ -655,6 +656,24 @@ class LnGlobalFeatures(IntFlag):
|
||||
# note that these are powers of two, not the bits themselves
|
||||
LN_GLOBAL_FEATURES_KNOWN_SET = set(LnGlobalFeatures)
|
||||
|
||||
def ln_compare_features(our_features, their_features):
|
||||
"""raises ValueError if incompatible"""
|
||||
our_flags = set(list_enabled_bits(our_features))
|
||||
their_flags = set(list_enabled_bits(their_features))
|
||||
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 ValueError(LnLocalFeatures(1 << flag))
|
||||
our_features ^= 1 << flag # disable flag
|
||||
else:
|
||||
# They too have this flag.
|
||||
# For easier feature-bit-testing, if this is an even flag, we also
|
||||
# set the corresponding odd flag now.
|
||||
if flag % 2 == 0 and our_features & (1 << flag):
|
||||
our_features |= 1 << get_ln_flag_pair_of_bit(flag)
|
||||
return our_features
|
||||
|
||||
|
||||
class LNPeerAddr:
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ from .lnutil import (Outpoint, LNPeerAddr,
|
||||
NUM_MAX_EDGES_IN_PAYMENT_PATH, SENT, RECEIVED, HTLCOwner,
|
||||
UpdateAddHtlc, Direction, LnLocalFeatures,
|
||||
ShortChannelID, PaymentAttemptLog, PaymentAttemptFailureDetails)
|
||||
from .lnutil import ln_dummy_address
|
||||
from .lnutil import ln_dummy_address, ln_compare_features
|
||||
from .transaction import PartialTxOutput, PartialTransaction, PartialTxInput
|
||||
from .lnonion import OnionFailureCode
|
||||
from .lnmsg import decode_msg
|
||||
@@ -200,6 +200,18 @@ class LNWorker(Logger):
|
||||
self._add_peer(host, int(port), bfh(pubkey)),
|
||||
self.network.asyncio_loop)
|
||||
|
||||
def is_good_peer(self, peer):
|
||||
node_id = peer.pubkey
|
||||
node = self.channel_db._nodes.get(node_id)
|
||||
if not node:
|
||||
return False
|
||||
try:
|
||||
ln_compare_features(self.localfeatures, node.features)
|
||||
except ValueError:
|
||||
return False
|
||||
#self.logger.info(f'is_good {peer.host}')
|
||||
return True
|
||||
|
||||
async def _get_next_peers_to_try(self) -> Sequence[LNPeerAddr]:
|
||||
now = time.time()
|
||||
await self.channel_db.data_loaded.wait()
|
||||
@@ -215,6 +227,8 @@ class LNWorker(Logger):
|
||||
continue
|
||||
if peer in self._last_tried_peer:
|
||||
continue
|
||||
if not self.is_good_peer(peer):
|
||||
continue
|
||||
return [peer]
|
||||
# try random peer from graph
|
||||
unconnected_nodes = self.channel_db.get_200_randomly_sorted_nodes_not_in(self.peers.keys())
|
||||
@@ -230,6 +244,8 @@ class LNWorker(Logger):
|
||||
continue
|
||||
if peer in self._last_tried_peer:
|
||||
continue
|
||||
if not self.is_good_peer(peer):
|
||||
continue
|
||||
#self.logger.info('taking random ln peer from our channel db')
|
||||
return [peer]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user