Skip to content

Commit

Permalink
Add closing_signed fee_range TLV
Browse files Browse the repository at this point in the history
  • Loading branch information
t-bast committed Aug 13, 2021
1 parent 19f4d1f commit 50a23ac
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
})

when(NEGOTIATING)(handleExceptions {
case Event(c@ClosingSigned(_, remoteClosingFee, remoteSig), d: DATA_NEGOTIATING) =>
case Event(c@ClosingSigned(_, remoteClosingFee, remoteSig, _), d: DATA_NEGOTIATING) =>
log.info("received closingFeeSatoshis={}", remoteClosingFee)
Closing.checkClosingSignature(keyManager, d.commitments, d.localShutdown.scriptPubKey, d.remoteShutdown.scriptPubKey, remoteClosingFee, remoteSig) match {
case Right(signedClosingTx) if d.closingTxProposed.last.lastOption.exists(_.localClosingSigned.feeSatoshis == remoteClosingFee) || d.closingTxProposed.flatten.size >= MAX_NEGOTIATION_ITERATIONS =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@

package fr.acinq.eclair.wire.protocol

import fr.acinq.bitcoin.Satoshi
import fr.acinq.eclair.UInt64
import fr.acinq.eclair.wire.protocol.TlvCodecs.tlvStream
import fr.acinq.eclair.wire.protocol.CommonCodecs._
import fr.acinq.eclair.wire.protocol.TlvCodecs.tlvStream
import scodec.Codec
import scodec.bits.ByteVector
import scodec.codecs._
Expand Down Expand Up @@ -53,4 +54,19 @@ object AcceptChannelTlv {
val acceptTlvCodec: Codec[TlvStream[AcceptChannelTlv]] = tlvStream(discriminated[AcceptChannelTlv].by(varint)
.typecase(UInt64(0), variableSizeBytesLong(varintoverflow, bytes).as[UpfrontShutdownScript])
)
}

}

sealed trait ClosingSignedTlv extends Tlv

object ClosingSignedTlv {

case class FeeRange(min: Satoshi, max: Satoshi) extends ClosingSignedTlv

private val feeRange: Codec[FeeRange] = (("min_fee_satoshis" | satoshi) :: ("max_fee_satoshis" | satoshi)).as[FeeRange]

val closingSignedTlvCodec: Codec[TlvStream[ClosingSignedTlv]] = tlvStream(discriminated[ClosingSignedTlv].by(varint)
.typecase(UInt64(1), variableSizeBytesLong(varintoverflow, feeRange))
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ object LightningMessageCodecs {
val closingSignedCodec: Codec[ClosingSigned] = (
("channelId" | bytes32) ::
("feeSatoshis" | satoshi) ::
("signature" | bytes64)).as[ClosingSigned]
("signature" | bytes64) ::
("tlvStream" | ClosingSignedTlv.closingSignedTlvCodec)).as[ClosingSigned]

val updateAddHtlcCodec: Codec[UpdateAddHtlc] = (
("channelId" | bytes32) ::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ case class Shutdown(channelId: ByteVector32,

case class ClosingSigned(channelId: ByteVector32,
feeSatoshis: Satoshi,
signature: ByteVector64) extends ChannelMessage with HasChannelId
signature: ByteVector64,
tlvStream: TlvStream[ClosingSignedTlv] = TlvStream.empty) extends ChannelMessage with HasChannelId {
val feeRange_opt = tlvStream.get[ClosingSignedTlv.FeeRange]
}

case class UpdateAddHtlc(channelId: ByteVector32,
id: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,25 @@ class LightningMessageCodecsSpec extends AnyFunSuite {
}
}

test("encode/decode closing_signed") {
val defaultSig = ByteVector64(hex"01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101")
val testCases = Seq(
hex"0100000000000000000000000000000000000000000000000000000000000000 0000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -> ClosingSigned(ByteVector32.One, 0 sat, ByteVector64.Zeroes),
hex"0100000000000000000000000000000000000000000000000000000000000000 00000000000003e8 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -> ClosingSigned(ByteVector32.One, 1000 sat, ByteVector64.Zeroes),
hex"0100000000000000000000000000000000000000000000000000000000000000 00000000000005dc 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" -> ClosingSigned(ByteVector32.One, 1500 sat, defaultSig),
hex"0100000000000000000000000000000000000000000000000000000000000000 00000000000005dc 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0110000000000000006400000000000007d0" -> ClosingSigned(ByteVector32.One, 1500 sat, ByteVector64.Zeroes, TlvStream(ClosingSignedTlv.FeeRange(100 sat, 2000 sat))),
hex"0100000000000000000000000000000000000000000000000000000000000000 00000000000003e8 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 0110000000000000006400000000000007d0" -> ClosingSigned(ByteVector32.One, 1000 sat, defaultSig, TlvStream(ClosingSignedTlv.FeeRange(100 sat, 2000 sat))),
hex"0100000000000000000000000000000000000000000000000000000000000000 0000000000000064 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0110000000000000006400000000000003e8 030401020304" -> ClosingSigned(ByteVector32.One, 100 sat, ByteVector64.Zeroes, TlvStream(Seq(ClosingSignedTlv.FeeRange(100 sat, 1000 sat)), Seq(GenericTlv(UInt64(3), hex"01020304")))),
)

for ((encoded, expected) <- testCases) {
val decoded = closingSignedCodec.decode(encoded.bits).require.value
assert(decoded === expected)
val reEncoded = closingSignedCodec.encode(decoded).require.bytes
assert(reEncoded === encoded)
}
}

test("encode/decode all channel messages") {
val open = OpenChannel(randomBytes32(), randomBytes32(), 3 sat, 4 msat, 5 sat, UInt64(6), 7 sat, 8 msat, FeeratePerKw(9 sat), CltvExpiryDelta(10), 11, publicKey(1), point(2), point(3), point(4), point(5), point(6), 0.toByte)
val accept = AcceptChannel(randomBytes32(), 3 sat, UInt64(4), 5 sat, 6 msat, 7, CltvExpiryDelta(8), 9, publicKey(1), point(2), point(3), point(4), point(5), point(6))
Expand Down

0 comments on commit 50a23ac

Please sign in to comment.