Use different trampoline bits than Eclair. Fixes #8141
This commit is contained in:
@@ -1090,12 +1090,19 @@ class LnFeatures(IntFlag):
|
||||
_ln_feature_contexts[OPTION_SUPPORT_LARGE_CHANNEL_OPT] = (LNFC.INIT | LNFC.NODE_ANN)
|
||||
_ln_feature_contexts[OPTION_SUPPORT_LARGE_CHANNEL_REQ] = (LNFC.INIT | LNFC.NODE_ANN)
|
||||
|
||||
# This is still a temporary number. Also used by Eclair.
|
||||
OPTION_TRAMPOLINE_ROUTING_REQ = 1 << 148
|
||||
OPTION_TRAMPOLINE_ROUTING_OPT = 1 << 149
|
||||
# Temporary number.
|
||||
OPTION_TRAMPOLINE_ROUTING_REQ_ECLAIR = 1 << 148
|
||||
OPTION_TRAMPOLINE_ROUTING_OPT_ECLAIR = 1 << 149
|
||||
|
||||
_ln_feature_contexts[OPTION_TRAMPOLINE_ROUTING_REQ] = (LNFC.INIT | LNFC.NODE_ANN | LNFC.INVOICE)
|
||||
_ln_feature_contexts[OPTION_TRAMPOLINE_ROUTING_OPT] = (LNFC.INIT | LNFC.NODE_ANN | LNFC.INVOICE)
|
||||
_ln_feature_contexts[OPTION_TRAMPOLINE_ROUTING_REQ_ECLAIR] = (LNFC.INIT | LNFC.NODE_ANN | LNFC.INVOICE)
|
||||
_ln_feature_contexts[OPTION_TRAMPOLINE_ROUTING_OPT_ECLAIR] = (LNFC.INIT | LNFC.NODE_ANN | LNFC.INVOICE)
|
||||
|
||||
# We use a different bit because Phoenix cannot do end-to-end multi-trampoline routes
|
||||
OPTION_TRAMPOLINE_ROUTING_REQ_ELECTRUM = 1 << 150
|
||||
OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM = 1 << 151
|
||||
|
||||
_ln_feature_contexts[OPTION_TRAMPOLINE_ROUTING_REQ_ELECTRUM] = (LNFC.INIT | LNFC.NODE_ANN | LNFC.INVOICE)
|
||||
_ln_feature_contexts[OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM] = (LNFC.INIT | LNFC.NODE_ANN | LNFC.INVOICE)
|
||||
|
||||
OPTION_SHUTDOWN_ANYSEGWIT_REQ = 1 << 26
|
||||
OPTION_SHUTDOWN_ANYSEGWIT_OPT = 1 << 27
|
||||
@@ -1249,7 +1256,7 @@ LN_FEATURES_IMPLEMENTED = (
|
||||
| LnFeatures.VAR_ONION_OPT | LnFeatures.VAR_ONION_REQ
|
||||
| LnFeatures.PAYMENT_SECRET_OPT | LnFeatures.PAYMENT_SECRET_REQ
|
||||
| LnFeatures.BASIC_MPP_OPT | LnFeatures.BASIC_MPP_REQ
|
||||
| LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT | LnFeatures.OPTION_TRAMPOLINE_ROUTING_REQ
|
||||
| LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM | LnFeatures.OPTION_TRAMPOLINE_ROUTING_REQ_ELECTRUM
|
||||
| LnFeatures.OPTION_SHUTDOWN_ANYSEGWIT_OPT | LnFeatures.OPTION_SHUTDOWN_ANYSEGWIT_REQ
|
||||
| LnFeatures.OPTION_CHANNEL_TYPE_OPT | LnFeatures.OPTION_CHANNEL_TYPE_REQ
|
||||
)
|
||||
|
||||
@@ -184,7 +184,7 @@ LNWALLET_FEATURES = BASE_FEATURES\
|
||||
| LnFeatures.OPTION_STATIC_REMOTEKEY_REQ\
|
||||
| LnFeatures.GOSSIP_QUERIES_REQ\
|
||||
| LnFeatures.BASIC_MPP_OPT\
|
||||
| LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT\
|
||||
| LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM\
|
||||
| LnFeatures.OPTION_SHUTDOWN_ANYSEGWIT_OPT\
|
||||
| LnFeatures.OPTION_CHANNEL_TYPE_OPT\
|
||||
|
||||
@@ -1531,9 +1531,10 @@ class LNWallet(LNWorker):
|
||||
if is_hardcoded_trampoline(node_id):
|
||||
return True
|
||||
peer = self._peers.get(node_id)
|
||||
if peer and peer.their_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT):
|
||||
return True
|
||||
return False
|
||||
if not peer:
|
||||
return False
|
||||
return (peer.their_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ECLAIR)\
|
||||
or peer.their_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM))
|
||||
|
||||
def suggest_peer(self) -> Optional[bytes]:
|
||||
if not self.uses_trampoline():
|
||||
|
||||
@@ -150,7 +150,7 @@ class MockLNWallet(Logger, EventListener, NetworkRetryManager[LNPeerAddr]):
|
||||
self.features |= LnFeatures.OPTION_UPFRONT_SHUTDOWN_SCRIPT_OPT
|
||||
self.features |= LnFeatures.VAR_ONION_OPT
|
||||
self.features |= LnFeatures.PAYMENT_SECRET_OPT
|
||||
self.features |= LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT
|
||||
self.features |= LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM
|
||||
self.features |= LnFeatures.OPTION_CHANNEL_TYPE_OPT
|
||||
self.pending_payments = defaultdict(asyncio.Future)
|
||||
for chan in chans:
|
||||
@@ -1071,7 +1071,7 @@ class TestPeer(TestCaseForTestnet):
|
||||
if mpp_invoice:
|
||||
graph.workers['dave'].features |= LnFeatures.BASIC_MPP_OPT
|
||||
if disable_trampoline_receiving:
|
||||
graph.workers['dave'].features &= ~LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT
|
||||
graph.workers['dave'].features &= ~LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM
|
||||
if not bob_forwarding:
|
||||
graph.workers['bob'].enable_htlc_forwarding = False
|
||||
if alice_uses_trampoline:
|
||||
@@ -1165,7 +1165,7 @@ class TestPeer(TestCaseForTestnet):
|
||||
peers = graph.peers.values()
|
||||
if is_legacy:
|
||||
# turn off trampoline features in invoice
|
||||
graph.workers['dave'].features = graph.workers['dave'].features ^ LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT
|
||||
graph.workers['dave'].features = graph.workers['dave'].features ^ LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM
|
||||
|
||||
# declare routing nodes as trampoline nodes
|
||||
electrum.trampoline._TRAMPOLINE_NODES_UNITTESTS = {
|
||||
|
||||
@@ -869,7 +869,7 @@ class TestLNUtil(ElectrumTestCase):
|
||||
self.assertTrue(f1.supports(LnFeatures.PAYMENT_SECRET_OPT))
|
||||
self.assertTrue(f1.supports(LnFeatures.BASIC_MPP_REQ))
|
||||
self.assertFalse(f1.supports(LnFeatures.OPTION_STATIC_REMOTEKEY_OPT))
|
||||
self.assertFalse(f1.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_REQ))
|
||||
self.assertFalse(f1.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_REQ_ELECTRUM))
|
||||
|
||||
def test_lnworker_decode_channel_update_msg(self):
|
||||
msg_without_prefix = bytes.fromhex("439b71c8ddeff63004e4ff1f9764a57dcf20232b79d9d669aef0e31c42be8e44208f7d868d0133acb334047f30e9399dece226ccd98e5df5330adf7f356290516fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000008762700054a00005ef2cf9c0101009000000000000003e80000000000000001000000002367b880")
|
||||
@@ -896,7 +896,7 @@ class TestLNUtil(ElectrumTestCase):
|
||||
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)
|
||||
features = LnFeatures(LnFeatures.BASIC_MPP_OPT | LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM)
|
||||
self.assertFalse(ChannelType.OPTION_STATIC_REMOTEKEY.complies_with_features(features))
|
||||
|
||||
# ignore unknown channel types
|
||||
|
||||
@@ -102,7 +102,8 @@ def is_legacy_relay(invoice_features, r_tags) -> Tuple[bool, List[bytes]]:
|
||||
"""
|
||||
invoice_features = LnFeatures(invoice_features)
|
||||
# trampoline-supporting wallets:
|
||||
if invoice_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT):
|
||||
if invoice_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ECLAIR)\
|
||||
or invoice_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM):
|
||||
# If there are no r_tags (routing hints) included, the wallet doesn't have
|
||||
# private channels and is probably directly connected to a trampoline node.
|
||||
# Any trampoline node should be able to figure out a path to the receiver and
|
||||
|
||||
Reference in New Issue
Block a user