From e8bf5d10483e998be394d9a8c407849f672ef9b2 Mon Sep 17 00:00:00 2001 From: Bastien Teinturier <31281497+t-bast@users.noreply.github.com> Date: Thu, 8 Oct 2020 11:07:27 +0200 Subject: [PATCH] [OpenChannel] Use TLV for channel version (#1534) We were previously using an encoding that was incompatible with TLV. We keep the old format, but also understand the channel version when provided in a TLV field. If the old format is provided, it will be preferred. --- .../fr/acinq/eclair/wire/ChannelTlv.scala | 4 ++++ .../fr/acinq/eclair/wire/OpenTlvSpec.scala | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelTlv.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelTlv.scala index 4c7b30041..982c06319 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelTlv.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelTlv.scala @@ -45,7 +45,11 @@ object OpenChannelTlv { val openTlvCodec: Codec[TlvStream[OpenChannelTlv]] = tlvStream(discriminated[OpenChannelTlv].by(varint) .typecase(UInt64(0), variableSizeBytesLong(varintoverflow, bytes).as[UpfrontShutdownScript]) + // TODO: @t-bast: once enough active Phoenix users have upgraded to versions > 1.3.3, we should configure the ACINQ + // node to write with the new encoding (0x47000001). + // Once that's done, we can remove the old encoding below (0x47000000) for future Phoenix upgrades. .typecase(UInt64(0x47000000), bits(ChannelVersion.LENGTH_BITS).as[ChannelVersion].as[ChannelVersionTlv]) + .typecase(UInt64(0x47000001), variableSizeBytesLong(varintoverflow, bits(ChannelVersion.LENGTH_BITS)).as[ChannelVersion].as[ChannelVersionTlv]) ) } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/OpenTlvSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/OpenTlvSpec.scala index 372fe5f8e..0a5272388 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/OpenTlvSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/OpenTlvSpec.scala @@ -19,19 +19,24 @@ package fr.acinq.eclair.wire import fr.acinq.eclair.channel.ChannelVersion import fr.acinq.eclair.wire.OpenChannelTlv.ChannelVersionTlv import org.scalatest.funsuite.AnyFunSuite -import scodec.{Attempt, DecodeResult} import scodec.bits._ +import scodec.{Attempt, DecodeResult} class OpenTlvSpec extends AnyFunSuite { test("channel version tlv") { - - val refs = Map( - ChannelVersion.STANDARD -> hex"fe47000000 00000001".bits, - (ChannelVersion.STANDARD | ChannelVersion.ZERO_RESERVE) -> hex"fe47000000 00000009".bits + case class TestCase(expected: ChannelVersion, encoded: BitVector, reEncoded: BitVector) + val testCases = Seq( + TestCase(ChannelVersion.STANDARD, hex"fe47000000 00000001".bits, hex"fe47000000 00000001".bits), + TestCase(ChannelVersion.STANDARD, hex"fe47000001 04 00000001".bits, hex"fe47000000 00000001".bits), + TestCase(ChannelVersion.STANDARD | ChannelVersion.ZERO_RESERVE, hex"fe47000000 00000009".bits, hex"fe47000000 00000009".bits), + TestCase(ChannelVersion.STANDARD | ChannelVersion.ZERO_RESERVE, hex"fe47000001 04 00000009".bits, hex"fe47000000 00000009".bits) ) - refs.foreach { case (cv, bits) => assert(OpenChannelTlv.openTlvCodec.encode(TlvStream(ChannelVersionTlv(cv))) === Attempt.Successful(bits)) } - refs.foreach { case (cv, bits) => assert(OpenChannelTlv.openTlvCodec.decode(bits) === Attempt.successful(DecodeResult(TlvStream(ChannelVersionTlv(cv)), BitVector.empty))) } + for (testCase <- testCases) { + assert(OpenChannelTlv.openTlvCodec.decode(testCase.encoded) === Attempt.successful(DecodeResult(TlvStream(ChannelVersionTlv(testCase.expected)), BitVector.empty))) + assert(OpenChannelTlv.openTlvCodec.encode(TlvStream(ChannelVersionTlv(testCase.expected))) === Attempt.Successful(testCase.reEncoded)) + } } + } \ No newline at end of file