diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/PluginParams.scala b/eclair-core/src/main/scala/fr/acinq/eclair/PluginParams.scala index c98f62b587..2946c8923d 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/PluginParams.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/PluginParams.scala @@ -67,7 +67,7 @@ case class InterceptOpenChannelReceived(replyTo: ActorRef[InterceptOpenChannelRe } sealed trait InterceptOpenChannelResponse -case class AcceptOpenChannel(temporaryChannelId: ByteVector32, defaultParams: DefaultParams) extends InterceptOpenChannelResponse +case class AcceptOpenChannel(temporaryChannelId: ByteVector32, defaultParams: DefaultParams, localFundingAmount_opt: Option[Satoshi]) extends InterceptOpenChannelResponse case class RejectOpenChannel(temporaryChannelId: ByteVector32, error: Error) extends InterceptOpenChannelResponse // @formatter:on diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala index 52b9de2a34..2a2d379164 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/OpenChannelInterceptor.scala @@ -167,7 +167,8 @@ private class OpenChannelInterceptor(peer: ActorRef[Any], nodeParams.pluginOpenChannelInterceptor match { case Some(plugin) => queryPlugin(plugin, request, localParams, ChannelConfig.standard, channelType) case None => - peer ! SpawnChannelNonInitiator(request.open, ChannelConfig.standard, channelType, localParams, request.peerConnection.toClassic) + // NB: we don't add a contribution to the funding amount. + peer ! SpawnChannelNonInitiator(request.open, ChannelConfig.standard, channelType, localParams, None, request.peerConnection.toClassic) waitForRequest() } case PendingChannelsRateLimiterResponse(PendingChannelsRateLimiter.ChannelRateLimited) => @@ -186,7 +187,7 @@ private class OpenChannelInterceptor(peer: ActorRef[Any], receiveCommandMessage[QueryPluginCommands](context, "queryPlugin") { case PluginOpenChannelResponse(pluginResponse: AcceptOpenChannel) => val localParams1 = updateLocalParams(localParams, pluginResponse.defaultParams) - peer ! SpawnChannelNonInitiator(request.open, channelConfig, channelType, localParams1, request.peerConnection.toClassic) + peer ! SpawnChannelNonInitiator(request.open, channelConfig, channelType, localParams1, pluginResponse.localFundingAmount_opt, request.peerConnection.toClassic) timers.cancel(PluginTimeout) waitForRequest() case PluginOpenChannelResponse(pluginResponse: RejectOpenChannel) => diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala index 5cb90f4fd0..4b752e2d06 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala @@ -199,7 +199,7 @@ class Peer(val nodeParams: NodeParams, stay() } - case Event(SpawnChannelNonInitiator(open, channelConfig, channelType, localParams, peerConnection), d: ConnectedData) => + case Event(SpawnChannelNonInitiator(open, channelConfig, channelType, localParams, localFundingAmount_opt, peerConnection), d: ConnectedData) => val temporaryChannelId = open.fold(_.temporaryChannelId, _.temporaryChannelId) if (peerConnection == d.peerConnection) { val channel = spawnChannel() @@ -209,8 +209,7 @@ class Peer(val nodeParams: NodeParams, channel ! INPUT_INIT_CHANNEL_NON_INITIATOR(open.temporaryChannelId, None, dualFunded = false, None, localParams, d.peerConnection, d.remoteInit, channelConfig, channelType) channel ! open case Right(open) => - // NB: we don't add a contribution to the funding amount. - channel ! INPUT_INIT_CHANNEL_NON_INITIATOR(open.temporaryChannelId, None, dualFunded = true, None, localParams, d.peerConnection, d.remoteInit, channelConfig, channelType) + channel ! INPUT_INIT_CHANNEL_NON_INITIATOR(open.temporaryChannelId, localFundingAmount_opt, dualFunded = true, None, localParams, d.peerConnection, d.remoteInit, channelConfig, channelType) channel ! open } stay() using d.copy(channels = d.channels + (TemporaryChannelId(temporaryChannelId) -> channel)) @@ -545,7 +544,7 @@ object Peer { } case class SpawnChannelInitiator(replyTo: akka.actor.typed.ActorRef[OpenChannelResponse], cmd: Peer.OpenChannel, channelConfig: ChannelConfig, channelType: SupportedChannelType, localParams: LocalParams) - case class SpawnChannelNonInitiator(open: Either[protocol.OpenChannel, protocol.OpenDualFundedChannel], channelConfig: ChannelConfig, channelType: SupportedChannelType, localParams: LocalParams, peerConnection: ActorRef) + case class SpawnChannelNonInitiator(open: Either[protocol.OpenChannel, protocol.OpenDualFundedChannel], channelConfig: ChannelConfig, channelType: SupportedChannelType, localParams: LocalParams, localFundingAmount_opt: Option[Satoshi], peerConnection: ActorRef) case class GetPeerInfo(replyTo: Option[typed.ActorRef[PeerInfoResponse]]) sealed trait PeerInfoResponse { def nodeId: PublicKey } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/OpenChannelInterceptorSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/OpenChannelInterceptorSpec.scala index 6149722688..6923e389fa 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/OpenChannelInterceptorSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/OpenChannelInterceptorSpec.scala @@ -87,13 +87,14 @@ class OpenChannelInterceptorSpec extends ScalaTestWithActorTestKit(ConfigFactory val openChannelNonInitiator = OpenChannelNonInitiator(remoteNodeId, Left(openChannel), Features.empty, Features.empty, peerConnection.ref, remoteAddress) openChannelInterceptor ! openChannelNonInitiator pendingChannelsRateLimiter.expectMessageType[AddOrRejectChannel].replyTo ! PendingChannelsRateLimiter.AcceptOpenChannel - pluginInterceptor.expectMessageType[InterceptOpenChannelReceived].replyTo ! AcceptOpenChannel(randomBytes32(), defaultParams) - val updatedLocalParams = peer.expectMessageType[SpawnChannelNonInitiator].localParams - assert(updatedLocalParams.dustLimit == defaultParams.dustLimit) - assert(updatedLocalParams.htlcMinimum == defaultParams.htlcMinimum) - assert(updatedLocalParams.maxAcceptedHtlcs == defaultParams.maxAcceptedHtlcs) - assert(updatedLocalParams.maxHtlcValueInFlightMsat == defaultParams.maxHtlcValueInFlightMsat) - assert(updatedLocalParams.toSelfDelay == defaultParams.toSelfDelay) + pluginInterceptor.expectMessageType[InterceptOpenChannelReceived].replyTo ! AcceptOpenChannel(randomBytes32(), defaultParams, Some(50_000 sat)) + val response = peer.expectMessageType[SpawnChannelNonInitiator] + assert(response.localFundingAmount_opt.contains(50_000 sat)) + assert(response.localParams.dustLimit == defaultParams.dustLimit) + assert(response.localParams.htlcMinimum == defaultParams.htlcMinimum) + assert(response.localParams.maxAcceptedHtlcs == defaultParams.maxAcceptedHtlcs) + assert(response.localParams.maxHtlcValueInFlightMsat == defaultParams.maxHtlcValueInFlightMsat) + assert(response.localParams.toSelfDelay == defaultParams.toSelfDelay) } test("continue channel open if no interceptor plugin registered and pending channels rate limiter accepts it") { f => @@ -146,7 +147,7 @@ class OpenChannelInterceptorSpec extends ScalaTestWithActorTestKit(ConfigFactory assert(peer.expectMessageType[OutgoingMessage].msg.asInstanceOf[Error].channelId == ByteVector32.One) // original request accepted after plugin accepts it - pluginInterceptor.expectMessageType[InterceptOpenChannelReceived].replyTo ! AcceptOpenChannel(randomBytes32(), defaultParams) + pluginInterceptor.expectMessageType[InterceptOpenChannelReceived].replyTo ! AcceptOpenChannel(randomBytes32(), defaultParams, None) assert(peer.expectMessageType[SpawnChannelNonInitiator].open == Left(openChannel)) eventListener.expectMessageType[ChannelAborted] } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala index 622f952309..021d4ed2f0 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala @@ -629,7 +629,7 @@ class PeerSpec extends FixtureSpec { val open = createOpenChannelMessage() system.eventStream.subscribe(probe.ref, classOf[ChannelAborted]) connect(remoteNodeId, peer, peerConnection, switchboard) - peer ! SpawnChannelNonInitiator(Left(open), ChannelConfig.standard, ChannelTypes.Standard(), localParams, ActorRef.noSender) + peer ! SpawnChannelNonInitiator(Left(open), ChannelConfig.standard, ChannelTypes.Standard(), localParams, None, ActorRef.noSender) val channelAborted = probe.expectMsgType[ChannelAborted] assert(channelAborted.remoteNodeId == remoteNodeId) assert(channelAborted.channelId == open.temporaryChannelId)