From 37f3fbe4b590843bf0b162e014a640ac054b30d7 Mon Sep 17 00:00:00 2001 From: Bastien Teinturier <31281497+t-bast@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:14:01 +0200 Subject: [PATCH] Assume widely supported features (#2732) /~https://github.com/lightning/bolts/pull/1092 makes some features compulsory and lets us assume that other nodes have support for them. --- eclair-core/src/main/resources/reference.conf | 6 +-- .../scala/fr/acinq/eclair/NodeParams.scala | 4 +- .../fr/acinq/eclair/io/PeerConnection.scala | 10 ++--- .../scala/fr/acinq/eclair/StartupSpec.scala | 32 ++++++++++--- .../integration/ChannelIntegrationSpec.scala | 45 ++++++++++++------- .../eclair/integration/IntegrationSpec.scala | 8 +--- .../integration/PaymentIntegrationSpec.scala | 7 ++- .../integration/StartupIntegrationSpec.scala | 10 ++--- 8 files changed, 76 insertions(+), 46 deletions(-) diff --git a/eclair-core/src/main/resources/reference.conf b/eclair-core/src/main/resources/reference.conf index f36bb3879e..8395cc7f42 100644 --- a/eclair-core/src/main/resources/reference.conf +++ b/eclair-core/src/main/resources/reference.conf @@ -54,11 +54,11 @@ eclair { // You will not be able to change this address, which can be dangerous, especially for very long lived channels. // Make sure you understand what it implies before you activate this feature. option_upfront_shutdown_script = disabled - option_data_loss_protect = optional - gossip_queries = optional + option_data_loss_protect = mandatory + gossip_queries = mandatory gossip_queries_ex = optional var_onion_optin = mandatory - option_static_remotekey = optional + option_static_remotekey = mandatory payment_secret = mandatory basic_mpp = optional option_support_large_channel = optional diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala index ac5f159043..015e3d099d 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala @@ -326,9 +326,11 @@ object NodeParams extends Logging { def validateFeatures(features: Features[Feature]): Unit = { val featuresErr = Features.validateFeatureGraph(features) require(featuresErr.isEmpty, featuresErr.map(_.message)) + 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.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.StaticRemoteKey), s"${Features.StaticRemoteKey.rfcName} must be enabled") require(features.hasFeature(Features.ChannelType), s"${Features.ChannelType.rfcName} must be enabled") } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala index ec7b626e42..228db37857 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/PeerConnection.scala @@ -393,13 +393,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) => diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala index 5f20a00a69..1bd052c264 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/StartupSpec.scala @@ -99,6 +99,7 @@ class StartupSpec extends AnyFunSuite { s"features.${VariableLengthOnion.rfcName}" -> "mandatory", s"features.${PaymentSecret.rfcName}" -> "mandatory", s"features.${BasicMultiPartPayment.rfcName}" -> "optional", + s"features.${StaticRemoteKey.rfcName}" -> "mandatory", ).asJava) // var_onion_optin cannot be disabled @@ -107,6 +108,7 @@ class StartupSpec extends AnyFunSuite { s"features.${ChannelRangeQueries.rfcName}" -> "optional", s"features.${ChannelRangeQueriesExtended.rfcName}" -> "optional", s"features.${ChannelType.rfcName}" -> "optional", + s"features.${StaticRemoteKey.rfcName}" -> "optional", ).asJava) // var_onion_optin cannot be optional @@ -115,6 +117,7 @@ class StartupSpec extends AnyFunSuite { s"features.${ChannelType.rfcName}" -> "optional", s"features.${VariableLengthOnion.rfcName}" -> "optional", s"features.${PaymentSecret.rfcName}" -> "mandatory", + s"features.${StaticRemoteKey.rfcName}" -> "optional", ).asJava) // payment_secret cannot be optional @@ -123,6 +126,7 @@ class StartupSpec extends AnyFunSuite { s"features.${ChannelType.rfcName}" -> "optional", s"features.${VariableLengthOnion.rfcName}" -> "mandatory", s"features.${PaymentSecret.rfcName}" -> "optional", + s"features.${StaticRemoteKey.rfcName}" -> "optional", ).asJava) // option_channel_type cannot be disabled @@ -133,6 +137,18 @@ class StartupSpec extends AnyFunSuite { s"features.${VariableLengthOnion.rfcName}" -> "mandatory", s"features.${PaymentSecret.rfcName}" -> "mandatory", s"features.${BasicMultiPartPayment.rfcName}" -> "optional", + s"features.${StaticRemoteKey.rfcName}" -> "optional", + ).asJava) + + // option_static_remotekey cannot be disabled + val noStaticRemoteKeyConf = ConfigFactory.parseMap(Map( + s"features.${DataLossProtect.rfcName}" -> "optional", + s"features.${ChannelRangeQueries.rfcName}" -> "optional", + s"features.${ChannelRangeQueriesExtended.rfcName}" -> "optional", + s"features.${ChannelType.rfcName}" -> "optional", + s"features.${VariableLengthOnion.rfcName}" -> "mandatory", + s"features.${PaymentSecret.rfcName}" -> "mandatory", + s"features.${BasicMultiPartPayment.rfcName}" -> "optional", ).asJava) // initial_routing_sync cannot be enabled @@ -144,6 +160,7 @@ class StartupSpec extends AnyFunSuite { s"features.${ChannelType.rfcName}" -> "optional", s"features.${VariableLengthOnion.rfcName}" -> "mandatory", s"features.${PaymentSecret.rfcName}" -> "mandatory", + s"features.${StaticRemoteKey.rfcName}" -> "optional", ).asJava) // extended channel queries without channel queries @@ -153,6 +170,7 @@ class StartupSpec extends AnyFunSuite { s"features.${ChannelType.rfcName}" -> "optional", s"features.${VariableLengthOnion.rfcName}" -> "mandatory", s"features.${PaymentSecret.rfcName}" -> "mandatory", + s"features.${StaticRemoteKey.rfcName}" -> "optional", ).asJava) assert(Try(makeNodeParamsWithDefaults(finalizeConf(legalFeaturesConf))).isSuccess) @@ -160,6 +178,7 @@ class StartupSpec extends AnyFunSuite { assert(Try(makeNodeParamsWithDefaults(finalizeConf(optionalVarOnionOptinConf))).isFailure) assert(Try(makeNodeParamsWithDefaults(finalizeConf(optionalPaymentSecretConf))).isFailure) assert(Try(makeNodeParamsWithDefaults(finalizeConf(noChannelTypeConf))).isFailure) + assert(Try(makeNodeParamsWithDefaults(finalizeConf(noStaticRemoteKeyConf))).isFailure) assert(Try(makeNodeParamsWithDefaults(finalizeConf(initialRoutingSyncConf))).isFailure) assert(Try(makeNodeParamsWithDefaults(finalizeConf(illegalFeaturesConf))).isFailure) } @@ -168,8 +187,10 @@ class StartupSpec extends AnyFunSuite { val perNodeConf = ConfigFactory.parseString( """ | features { + | option_data_loss_protect = optional | var_onion_optin = mandatory | payment_secret = mandatory + | option_static_remotekey = optional | option_channel_type = optional | } | override-init-features = [ // optional per-node features @@ -186,13 +207,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, StaticRemoteKey -> 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 @@ -211,7 +233,7 @@ class StartupSpec extends AnyFunSuite { | nodeid = "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766" | features { | basic_mpp = optional - | option_static_remotekey = disabled + | option_static_remotekey = optional | } | } | ] @@ -220,11 +242,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, StaticRemoteKey -> Optional, ChannelType -> Optional)) } test("reject non-init features in node override") { diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala index 5cc5e378db..668a376f5f 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala @@ -183,12 +183,15 @@ abstract class ChannelIntegrationSpec extends IntegrationSpec { paymentSender.expectMsgType[PaymentSent](max = 60 seconds) // we then generate enough blocks so that nodes get their main delayed output generateBlocks(25, Some(minerAddress)) - // F should have 2 recv transactions: the redeemed htlc and its main output - // C should have 1 recv transaction: its main output + val expectedTxCountC = 1 // C should have 1 recv transaction: its main output + val expectedTxCountF = commitmentFormat match { + case _: AnchorOutputsCommitmentFormat => 2 // F should have 2 recv transactions: the redeemed htlc and its main output + case Transactions.DefaultCommitmentFormat => 1 // F's main output uses static_remotekey + } awaitCond({ val receivedByC = listReceivedByAddress(finalAddressC, sender) val receivedByF = listReceivedByAddress(finalAddressF) - (receivedByF diff previouslyReceivedByF).size == 2 && (receivedByC diff previouslyReceivedByC).size == 1 + (receivedByF diff previouslyReceivedByF).size == expectedTxCountF && (receivedByC diff previouslyReceivedByC).size == expectedTxCountC }, max = 30 seconds, interval = 1 second) // we generate blocks to make txs confirm generateBlocks(2, Some(minerAddress)) @@ -221,12 +224,15 @@ abstract class ChannelIntegrationSpec extends IntegrationSpec { paymentSender.expectMsgType[PaymentSent](max = 60 seconds) // we then generate enough blocks so that F gets its htlc-success delayed output generateBlocks(25, Some(minerAddress)) - // F should have 2 recv transactions: the redeemed htlc and its main output - // C should have 1 recv transaction: its main output + val expectedTxCountC = commitmentFormat match { + case _: AnchorOutputsCommitmentFormat => 1 // C should have 1 recv transaction: its main output + case Transactions.DefaultCommitmentFormat => 0 // C's main output uses static_remotekey + } + val expectedTxCountF = 2 // F should have 2 recv transactions: the redeemed htlc and its main output awaitCond({ val receivedByC = listReceivedByAddress(finalAddressC, sender) val receivedByF = listReceivedByAddress(finalAddressF, sender) - (receivedByF diff previouslyReceivedByF).size == 2 && (receivedByC diff previouslyReceivedByC).size == 1 + (receivedByF diff previouslyReceivedByF).size == expectedTxCountF && (receivedByC diff previouslyReceivedByC).size == expectedTxCountC }, max = 30 seconds, interval = 1 second) // we generate blocks to make txs confirm generateBlocks(2, Some(minerAddress)) @@ -271,12 +277,15 @@ abstract class ChannelIntegrationSpec extends IntegrationSpec { assert(failed.failures.head.asInstanceOf[RemoteFailure].e == DecryptedFailurePacket(nodes("C").nodeParams.nodeId, PermanentChannelFailure())) // we then generate enough blocks to confirm all delayed transactions generateBlocks(25, Some(minerAddress)) - // C should have 2 recv transactions: its main output and the htlc timeout - // F should have 1 recv transaction: its main output + val expectedTxCountC = 2 // C should have 2 recv transactions: its main output and the htlc timeout + val expectedTxCountF = commitmentFormat match { + case _: AnchorOutputsCommitmentFormat => 1 // F should have 1 recv transaction: its main output + case Transactions.DefaultCommitmentFormat => 0 // F's main output uses static_remotekey + } awaitCond({ val receivedByC = listReceivedByAddress(finalAddressC, sender) val receivedByF = listReceivedByAddress(finalAddressF, sender) - (receivedByF diff previouslyReceivedByF).size == 1 && (receivedByC diff previouslyReceivedByC).size == 2 + (receivedByF diff previouslyReceivedByF).size == expectedTxCountF && (receivedByC diff previouslyReceivedByC).size == expectedTxCountC }, max = 30 seconds, interval = 1 second) // we generate blocks to make txs confirm generateBlocks(2, Some(minerAddress)) @@ -324,12 +333,15 @@ abstract class ChannelIntegrationSpec extends IntegrationSpec { assert(failed.failures.head.asInstanceOf[RemoteFailure].e == DecryptedFailurePacket(nodes("C").nodeParams.nodeId, PermanentChannelFailure())) // we then generate enough blocks to confirm all delayed transactions generateBlocks(25, Some(minerAddress)) - // C should have 2 recv transactions: its main output and the htlc timeout - // F should have 1 recv transaction: its main output + val expectedTxCountC = commitmentFormat match { + case _: AnchorOutputsCommitmentFormat => 2 // C should have 2 recv transactions: its main output and the htlc timeout + case Transactions.DefaultCommitmentFormat => 1 // C's main output uses static_remotekey + } + val expectedTxCountF = 1 // F should have 1 recv transaction: its main output awaitCond({ val receivedByC = listReceivedByAddress(finalAddressC, sender) val receivedByF = listReceivedByAddress(finalAddressF, sender) - (receivedByF diff previouslyReceivedByF).size == 1 && (receivedByC diff previouslyReceivedByC).size == 2 + (receivedByF diff previouslyReceivedByF).size == expectedTxCountF && (receivedByC diff previouslyReceivedByC).size == expectedTxCountC }, max = 30 seconds, interval = 1 second) // we generate blocks to make tx confirm generateBlocks(2, Some(minerAddress)) @@ -455,9 +467,9 @@ abstract class ChannelIntegrationSpec extends IntegrationSpec { class StandardChannelIntegrationSpec extends ChannelIntegrationSpec { test("start eclair nodes") { - instantiateEclairNode("A", ConfigFactory.parseMap(Map("eclair.node-alias" -> "A", "eclair.channel.expiry-delta-blocks" -> 40, "eclair.channel.fulfill-safety-before-timeout-blocks" -> 12, "eclair.server.port" -> (if (useEclairSigner) 29840 else 29740), "eclair.api.port" -> (if (useEclairSigner) 28190 else 28090)).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig)) + instantiateEclairNode("A", ConfigFactory.parseMap(Map("eclair.node-alias" -> "A", "eclair.channel.expiry-delta-blocks" -> 40, "eclair.channel.fulfill-safety-before-timeout-blocks" -> 12, "eclair.server.port" -> (if (useEclairSigner) 29840 else 29740), "eclair.api.port" -> (if (useEclairSigner) 28190 else 28090)).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig)) instantiateEclairNode("C", ConfigFactory.parseMap(Map("eclair.node-alias" -> "C", "eclair.channel.expiry-delta-blocks" -> 40, "eclair.channel.fulfill-safety-before-timeout-blocks" -> 12, "eclair.server.port" -> (if (useEclairSigner) 29841 else 29741), "eclair.api.port" -> (if (useEclairSigner) 28191 else 28091)).asJava).withFallback(withAnchorOutputs).withFallback(commonConfig)) - instantiateEclairNode("F", ConfigFactory.parseMap(Map("eclair.node-alias" -> "F", "eclair.channel.expiry-delta-blocks" -> 40, "eclair.channel.fulfill-safety-before-timeout-blocks" -> 12, "eclair.server.port" -> (if (useEclairSigner) 29842 else 29742), "eclair.api.port" -> (if (useEclairSigner) 28192 else 28092)).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig)) + instantiateEclairNode("F", ConfigFactory.parseMap(Map("eclair.node-alias" -> "F", "eclair.channel.expiry-delta-blocks" -> 40, "eclair.channel.fulfill-safety-before-timeout-blocks" -> 12, "eclair.server.port" -> (if (useEclairSigner) 29842 else 29742), "eclair.api.port" -> (if (useEclairSigner) 28192 else 28092)).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig)) } test("connect nodes") { @@ -614,10 +626,11 @@ class StandardChannelIntegrationSpec extends ChannelIntegrationSpec { sender.expectMsg(htlcSuccess.head.txid) bitcoinClient.publishTransaction(htlcTimeout.head).pipeTo(sender.ref) sender.expectMsg(htlcTimeout.head.txid) - // at this point C should have 6 recv transactions: its previous main output, F's main output and all htlc outputs (taken as punishment) + // at this point C should have 5 recv transactions: F's main output and all htlc outputs (taken as punishment) + // C's main output uses static_remotekey, so C doesn't need to claim it awaitCond({ val receivedByC = listReceivedByAddress(finalAddressC, sender) - (receivedByC diff previouslyReceivedByC).size == 6 + (receivedByC diff previouslyReceivedByC).size == 5 }, max = 30 seconds, interval = 1 second) // we generate blocks to make txs confirm generateBlocks(2) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala index 4da4266120..f69a3c1908 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala @@ -103,16 +103,12 @@ abstract class IntegrationSpec extends TestKitBaseClass with BitcoindService wit s"eclair.features.${RouteBlinding.rfcName}" -> "optional", ).asJava) - val withDefaultCommitment = commonFeatures.withFallback(ConfigFactory.parseMap(Map( - s"eclair.features.${StaticRemoteKey.rfcName}" -> "disabled", + val withStaticRemoteKey = commonFeatures.withFallback(ConfigFactory.parseMap(Map( + s"eclair.features.${StaticRemoteKey.rfcName}" -> "mandatory", s"eclair.features.${AnchorOutputs.rfcName}" -> "disabled", s"eclair.features.${AnchorOutputsZeroFeeHtlcTx.rfcName}" -> "disabled", ).asJava)) - val withStaticRemoteKey = ConfigFactory.parseMap(Map( - s"eclair.features.${StaticRemoteKey.rfcName}" -> "optional" - ).asJava).withFallback(withDefaultCommitment) - val withAnchorOutputs = ConfigFactory.parseMap(Map( s"eclair.features.${AnchorOutputs.rfcName}" -> "optional" ).asJava).withFallback(withStaticRemoteKey) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/PaymentIntegrationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/PaymentIntegrationSpec.scala index ea0604ab72..e0ef583e04 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/PaymentIntegrationSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/PaymentIntegrationSpec.scala @@ -16,7 +16,6 @@ package fr.acinq.eclair.integration -import akka.actor.ActorRef import akka.actor.testkit.typed.scaladsl.{TestProbe => TypedProbe} import akka.actor.typed.scaladsl.adapter._ import akka.pattern.pipe @@ -62,10 +61,10 @@ import scala.jdk.CollectionConverters._ class PaymentIntegrationSpec extends IntegrationSpec { test("start eclair nodes") { - instantiateEclairNode("A", ConfigFactory.parseMap(Map("eclair.node-alias" -> "A", "eclair.channel.expiry-delta-blocks" -> 130, "eclair.server.port" -> 29730, "eclair.api.port" -> 28080, "eclair.channel.channel-flags.announce-channel" -> false).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig)) // A's channels are private - instantiateEclairNode("B", ConfigFactory.parseMap(Map("eclair.node-alias" -> "B", "eclair.channel.expiry-delta-blocks" -> 131, "eclair.server.port" -> 29731, "eclair.api.port" -> 28081, "eclair.trampoline-payments-enable" -> true, "eclair.onion-messages.relay-policy" -> "relay-all").asJava).withFallback(withDefaultCommitment).withFallback(commonConfig)) + instantiateEclairNode("A", ConfigFactory.parseMap(Map("eclair.node-alias" -> "A", "eclair.channel.expiry-delta-blocks" -> 130, "eclair.server.port" -> 29730, "eclair.api.port" -> 28080, "eclair.channel.channel-flags.announce-channel" -> false).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig)) // A's channels are private + instantiateEclairNode("B", ConfigFactory.parseMap(Map("eclair.node-alias" -> "B", "eclair.channel.expiry-delta-blocks" -> 131, "eclair.server.port" -> 29731, "eclair.api.port" -> 28081, "eclair.trampoline-payments-enable" -> true, "eclair.onion-messages.relay-policy" -> "relay-all").asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig)) instantiateEclairNode("C", ConfigFactory.parseMap(Map("eclair.node-alias" -> "C", "eclair.channel.expiry-delta-blocks" -> 132, "eclair.server.port" -> 29732, "eclair.api.port" -> 28082, "eclair.trampoline-payments-enable" -> true).asJava).withFallback(withDualFunding).withFallback(commonConfig)) - instantiateEclairNode("D", ConfigFactory.parseMap(Map("eclair.node-alias" -> "D", "eclair.channel.expiry-delta-blocks" -> 133, "eclair.server.port" -> 29733, "eclair.api.port" -> 28083, "eclair.trampoline-payments-enable" -> true).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig)) + instantiateEclairNode("D", ConfigFactory.parseMap(Map("eclair.node-alias" -> "D", "eclair.channel.expiry-delta-blocks" -> 133, "eclair.server.port" -> 29733, "eclair.api.port" -> 28083, "eclair.trampoline-payments-enable" -> true).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig)) instantiateEclairNode("E", ConfigFactory.parseMap(Map("eclair.node-alias" -> "E", "eclair.channel.expiry-delta-blocks" -> 134, "eclair.server.port" -> 29734, "eclair.api.port" -> 28084).asJava).withFallback(withDualFunding).withFallback(commonConfig)) instantiateEclairNode("F", ConfigFactory.parseMap(Map("eclair.node-alias" -> "F", "eclair.channel.expiry-delta-blocks" -> 135, "eclair.server.port" -> 29735, "eclair.api.port" -> 28085, "eclair.trampoline-payments-enable" -> true).asJava).withFallback(commonConfig)) instantiateEclairNode("G", ConfigFactory.parseMap(Map("eclair.node-alias" -> "G", "eclair.channel.expiry-delta-blocks" -> 136, "eclair.server.port" -> 29736, "eclair.api.port" -> 28086, "eclair.relay.fees.public-channels.fee-base-msat" -> 1010, "eclair.relay.fees.public-channels.fee-proportional-millionths" -> 102, "eclair.trampoline-payments-enable" -> true).asJava).withFallback(commonConfig)) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/StartupIntegrationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/StartupIntegrationSpec.scala index 08a1ba59a9..91b47605e6 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/StartupIntegrationSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/StartupIntegrationSpec.scala @@ -31,7 +31,7 @@ import scala.jdk.CollectionConverters._ class StartupIntegrationSpec extends IntegrationSpec { test("no bitcoind wallet configured and one wallet loaded") { - instantiateEclairNode("A", ConfigFactory.parseMap(Map("eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig).withoutPath("eclair.bitcoind.wallet")) + instantiateEclairNode("A", ConfigFactory.parseMap(Map("eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig).withoutPath("eclair.bitcoind.wallet")) } test("no bitcoind wallet configured and two wallets loaded") { @@ -39,7 +39,7 @@ class StartupIntegrationSpec extends IntegrationSpec { sender.send(bitcoincli, BitcoinReq("createwallet", "")) sender.expectMsgType[Any] val thrown = intercept[BitcoinDefaultWalletException] { - instantiateEclairNode("C", ConfigFactory.parseMap(Map("eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig).withoutPath("eclair.bitcoind.wallet")) + instantiateEclairNode("C", ConfigFactory.parseMap(Map("eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig).withoutPath("eclair.bitcoind.wallet")) } assert(thrown == BitcoinDefaultWalletException(List(defaultWallet, ""))) } @@ -48,7 +48,7 @@ class StartupIntegrationSpec extends IntegrationSpec { val sender = TestProbe() sender.send(bitcoincli, BitcoinReq("createwallet", "")) sender.expectMsgType[Any] - instantiateEclairNode("D", ConfigFactory.parseMap(Map("eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig)) + instantiateEclairNode("D", ConfigFactory.parseMap(Map("eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig)) } test("explicit bitcoind wallet configured but not loaded") { @@ -56,7 +56,7 @@ class StartupIntegrationSpec extends IntegrationSpec { sender.send(bitcoincli, BitcoinReq("createwallet", "")) sender.expectMsgType[Any] val thrown = intercept[BitcoinWalletNotLoadedException] { - instantiateEclairNode("E", ConfigFactory.parseMap(Map("eclair.bitcoind.wallet" -> "notloaded", "eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withDefaultCommitment).withFallback(commonConfig)) + instantiateEclairNode("E", ConfigFactory.parseMap(Map("eclair.bitcoind.wallet" -> "notloaded", "eclair.server.port" -> TestUtils.availablePort).asJava).withFallback(withStaticRemoteKey).withFallback(commonConfig)) } assert(thrown == BitcoinWalletNotLoadedException("notloaded", List(defaultWallet, ""))) } @@ -64,7 +64,7 @@ class StartupIntegrationSpec extends IntegrationSpec { test("bitcoind started with wallets disabled") { restartBitcoind(startupFlags = "-disablewallet", loadWallet = false) val thrown = intercept[BitcoinWalletDisabledException] { - instantiateEclairNode("F", ConfigFactory.load().getConfig("eclair").withFallback(withDefaultCommitment).withFallback(commonConfig)) + instantiateEclairNode("F", ConfigFactory.load().getConfig("eclair").withFallback(withStaticRemoteKey).withFallback(commonConfig)) } assert(thrown == BitcoinWalletDisabledException(e = JsonRPCError(Error(-32601, "Method not found")))) }