Skip to content

Commit

Permalink
Assume widely supported features
Browse files Browse the repository at this point in the history
lightning/bolts#1092 makes some features compulsory
and lets us assume that other nodes have support for them.
  • Loading branch information
t-bast committed Aug 29, 2023
1 parent 8d42052 commit fc2a411
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 10 deletions.
Expand Up @@ -327,6 +327,7 @@ object NodeParams extends Logging {
require(features.hasFeature(Features.VariableLengthOnion, Some(FeatureSupport.Mandatory)), s"${Features.VariableLengthOnion.rfcName} must be enabled and mandatory")
require(features.hasFeature(Features.PaymentSecret, Some(FeatureSupport.Mandatory)), s"${Features.PaymentSecret.rfcName} must be enabled and mandatory")
require(!features.hasFeature(Features.InitialRoutingSync), s"${Features.InitialRoutingSync.rfcName} is not supported anymore, use ${Features.ChannelRangeQueries.rfcName} instead")
require(features.hasFeature(Features.DataLossProtect), s"${Features.DataLossProtect.rfcName} must be enabled")
require(features.hasFeature(Features.ChannelType), s"${Features.ChannelType.rfcName} must be enabled")
}

Expand Down
Expand Up @@ -389,13 +389,11 @@ class PeerConnection(keyPair: KeyPair, conf: PeerConnection.Conf, switchboard: A
stay() using d.copy(behavior = behavior1)

case Event(DoSync(replacePrevious), d: ConnectedData) =>
val canUseChannelRangeQueries = Features.canUseFeature(d.localInit.features, d.remoteInit.features, Features.ChannelRangeQueries)
// We assume support for standard range queries since https://github.com/lightning/bolts/pull/1092
val canUseChannelRangeQueriesEx = Features.canUseFeature(d.localInit.features, d.remoteInit.features, Features.ChannelRangeQueriesExtended)
if (canUseChannelRangeQueries || canUseChannelRangeQueriesEx) {
val flags_opt = if (canUseChannelRangeQueriesEx) Some(QueryChannelRangeTlv.QueryFlags(QueryChannelRangeTlv.QueryFlags.WANT_ALL)) else None
log.debug(s"sending sync channel range query with flags_opt=$flags_opt replacePrevious=$replacePrevious")
router ! SendChannelQuery(d.chainHash, d.remoteNodeId, self, replacePrevious, flags_opt)
}
val flags_opt = if (canUseChannelRangeQueriesEx) Some(QueryChannelRangeTlv.QueryFlags(QueryChannelRangeTlv.QueryFlags.WANT_ALL)) else None
log.debug(s"sending sync channel range query with flags_opt=$flags_opt replacePrevious=$replacePrevious")
router ! SendChannelQuery(d.chainHash, d.remoteNodeId, self, replacePrevious, flags_opt)
stay()

case Event(ResumeAnnouncements, d: ConnectedData) =>
Expand Down
10 changes: 6 additions & 4 deletions eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala
Expand Up @@ -168,6 +168,7 @@ class StartupSpec extends AnyFunSuite {
val perNodeConf = ConfigFactory.parseString(
"""
| features {
| option_data_loss_protect = optional
| var_onion_optin = mandatory
| payment_secret = mandatory
| option_channel_type = optional
Expand All @@ -186,13 +187,14 @@ class StartupSpec extends AnyFunSuite {

val nodeParams = makeNodeParamsWithDefaults(perNodeConf.withFallback(defaultConf.withoutPath("features")))
val perNodeFeatures = nodeParams.initFeaturesFor(PublicKey(ByteVector.fromValidHex("031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f")))
assert(perNodeFeatures == Features(VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Mandatory, ChannelRangeQueries -> Optional, ChannelType -> Optional))
assert(perNodeFeatures == Features(DataLossProtect -> Optional, VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Mandatory, ChannelRangeQueries -> Optional, ChannelType -> Optional))
}

test("combine node override features with default features") {
val perNodeConf = ConfigFactory.parseString(
"""
| features {
| option_data_loss_protect = optional
| var_onion_optin = mandatory
| payment_secret = mandatory
| basic_mpp = mandatory
Expand Down Expand Up @@ -220,11 +222,11 @@ class StartupSpec extends AnyFunSuite {

val nodeParams = makeNodeParamsWithDefaults(perNodeConf.withFallback(defaultConf.withoutPath("features")))
val defaultFeatures = nodeParams.features
assert(defaultFeatures == Features(VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Mandatory, StaticRemoteKey -> Optional, ChannelType -> Optional))
assert(defaultFeatures == Features(DataLossProtect -> Optional, VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Mandatory, StaticRemoteKey -> Optional, ChannelType -> Optional))
val perNodeFeatures1 = nodeParams.initFeaturesFor(PublicKey(ByteVector.fromValidHex("031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f")))
assert(perNodeFeatures1 == Features(VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Mandatory, StaticRemoteKey -> Mandatory, AnchorOutputsZeroFeeHtlcTx -> Optional, ChannelType -> Optional))
assert(perNodeFeatures1 == Features(DataLossProtect -> Optional, VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Mandatory, StaticRemoteKey -> Mandatory, AnchorOutputsZeroFeeHtlcTx -> Optional, ChannelType -> Optional))
val perNodeFeatures2 = nodeParams.initFeaturesFor(PublicKey(ByteVector.fromValidHex("024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766")))
assert(perNodeFeatures2 == Features(VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Optional, ChannelType -> Optional))
assert(perNodeFeatures2 == Features(DataLossProtect -> Optional, VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Optional, ChannelType -> Optional))
}

test("reject non-init features in node override") {
Expand Down

0 comments on commit fc2a411

Please sign in to comment.