1
0
mirror of https://github.com/ACINQ/eclair.git synced 2024-11-19 01:43:22 +01:00

Fix ability for plugins to exchange custom Lightning Messages with other LN nodes (#2495)

Required for the PeerSwap plugin and other plugins that exchange custom Lightning messages
This commit is contained in:
Richard Myers 2023-01-27 19:57:11 +01:00 committed by GitHub
parent 927e1c8ad4
commit f901aeac04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 4 deletions

View File

@ -302,6 +302,11 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, wallet: OnchainP
context.system.eventStream.publish(UnknownMessageReceived(self, remoteNodeId, unknownMsg, d.connectionInfo))
stay()
case Event(RelayUnknownMessage(unknownMsg: UnknownMessage), d: ConnectedData) if nodeParams.pluginMessageTags.contains(unknownMsg.tag) =>
logMessage(unknownMsg, "OUT")
d.peerConnection forward unknownMsg
stay()
case Event(unhandledMsg: LightningMessage, _) =>
log.warning("ignoring message {}", unhandledMsg)
stay()
@ -569,6 +574,8 @@ object Peer {
case class ConnectionDown(peerConnection: ActorRef) extends RemoteTypes
case class RelayOnionMessage(messageId: ByteVector32, msg: OnionMessage, replyTo_opt: Option[typed.ActorRef[Status]])
case class RelayUnknownMessage(unknownMessage: UnknownMessage)
// @formatter:on
def makeChannelParams(nodeParams: NodeParams, initFeatures: Features[InitFeature], upfrontShutdownScript_opt: Option[ByteVector], walletStaticPaymentBasepoint_opt: Option[PublicKey], isInitiator: Boolean, dualFunded: Boolean, fundingAmount: Satoshi, unlimitedMaxHtlcValueInFlight: Boolean): LocalParams = {

View File

@ -24,7 +24,7 @@ import fr.acinq.eclair.wire.protocol.LightningMessageCodecs.{channelFlagsCodec,
import fr.acinq.eclair.{BlockHeight, CltvExpiry, MilliSatoshi, MilliSatoshiLong, UInt64}
import scodec.bits.ByteVector
import scodec.codecs._
import scodec.{Attempt, Codec}
import scodec.{Attempt, Codec, Err}
/**
* see https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md
@ -94,7 +94,10 @@ object FailureMessageCodecs {
val NODE = 0x2000
val UPDATE = 0x1000
val channelUpdateCodecWithType = meteredLightningMessageCodec.narrow[ChannelUpdate](f => Attempt.successful(f.asInstanceOf[ChannelUpdate]), g => g)
val channelUpdateCodecWithType = meteredLightningMessageCodec.narrow[ChannelUpdate]({
case f: ChannelUpdate => Attempt.successful(f)
case _ => Attempt.failure(Err("not a ChanelUpdate message"))
}, g => g)
// NB: for historical reasons some implementations were including/omitting the message type (258 for ChannelUpdate)
// this codec supports both versions for decoding, and will encode with the message type

View File

@ -410,7 +410,7 @@ object LightningMessageCodecs {
val unknownMessageCodec: Codec[UnknownMessage] = (
("tag" | uint16) ::
("message" | varsizebinarydata)
("message" | bytes)
).as[UnknownMessage]
val lightningMessageCodec = discriminated[LightningMessage].by(uint16)

View File

@ -20,7 +20,7 @@ import akka.actor.Status.Failure
import akka.actor.{ActorContext, ActorRef, ActorSystem, FSM, PoisonPill, Status}
import akka.testkit.{TestFSMRef, TestKit, TestProbe}
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
import fr.acinq.bitcoin.scalacompat.{Block, Btc, SatoshiLong, Script}
import fr.acinq.bitcoin.scalacompat.{Block, Btc, ByteVector32, SatoshiLong, Script}
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features._
import fr.acinq.eclair.TestConstants._
@ -657,6 +657,15 @@ class PeerSpec extends FixtureSpec {
peer ! RelayOnionMessage(messageId, msg, Some(probe.ref.toTyped))
probe.expectMsg(MessageRelay.Disconnected(messageId))
}
test("send UnknownMessage to peer if tag registered by a plugin") { f =>
import f._
val probe = TestProbe()
val unknownMessage = UnknownMessage(60003, ByteVector32.One)
connect(remoteNodeId, peer, peerConnection, switchboard, channels = Set(ChannelCodecsSpec.normal))
probe.send(peer, Peer.RelayUnknownMessage(unknownMessage))
peerConnection.expectMsgType[UnknownMessage]
}
}
object PeerSpec {