-
Notifications
You must be signed in to change notification settings - Fork 268
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extended Queries: use TLV format for optional data (#1072)
* Extended Queries: use TLV format for optional data Optional query extensions now use TLV instead of a custom format. Flags are encoded as varint instead of bytes as originally proposed. With the current proposal they will all fit on a single byte, but will be much easier to extends this way. * Move query message TLVs to their own namespace We add one new class for each TLV type, with specific TLV types, and encapsulate codecs. * Optional TLVs are represented as a list, not an optional list TLVs that extend regular LN messages can be represented as a TlvStream and not an Option[TlvStream] since we don't need to explicitely terminate the stream (either by preprending its length or using a specific terminator) as we do in Onion TLVs. No TLVs simply means that the TLV stream is empty. * Update to match BOLT PR Checksums in ReplyChannelRange now have the same encoding as short channel ids and timestamps: one byte for the encoding type (uncompressed or zlib) followed by encoded data. * TLV Stream: Implement a generic "get" method for TLV fields If a have a TLV stream of type MyTLV which is a subtype of TLV, and MyTLV1 and MYTLV2 are both subtypes of MyTLV then we can use stream.get[MyTLV1] to get the TLV record of type MYTLV1 (if any) in our TLV stream. * Extended range queries: Implement latest BOLT changes Checksums are just transmitted as a raw array, with optional compression as it would be useless here. * Use extended range queries on regtest and testnet We will use them on mainnet as soon as lightning/bolts#557 has been merged. * Address review comments * Router: rework handling of ReplyChannelRange We remove the ugly and inefficient zipWithIndex we had before * NodeParams: move fee base check to its proper place * Router: minor cleanup
- Loading branch information
Showing
16 changed files
with
509 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 82 additions & 45 deletions
127
eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
eclair-core/src/main/scala/fr/acinq/eclair/wire/QueryChannelRangeTlv.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package fr.acinq.eclair.wire | ||
|
||
import fr.acinq.eclair.UInt64 | ||
import fr.acinq.eclair.wire.CommonCodecs.{shortchannelid, varint, varintoverflow} | ||
import scodec.Codec | ||
import scodec.codecs._ | ||
|
||
sealed trait QueryChannelRangeTlv extends Tlv | ||
|
||
object QueryChannelRangeTlv { | ||
/** | ||
* Optional query flag that is appended to QueryChannelRange | ||
* @param flag bit 1 set means I want timestamps, bit 2 set means I want checksums | ||
*/ | ||
case class QueryFlags(flag: Long) extends QueryChannelRangeTlv { | ||
val wantTimestamps = QueryFlags.wantTimestamps(flag) | ||
|
||
val wantChecksums = QueryFlags.wantChecksums(flag) | ||
} | ||
|
||
case object QueryFlags { | ||
val WANT_TIMESTAMPS: Long = 1 | ||
val WANT_CHECKSUMS: Long = 2 | ||
val WANT_ALL: Long = (WANT_TIMESTAMPS | WANT_CHECKSUMS) | ||
|
||
def wantTimestamps(flag: Long) = (flag & WANT_TIMESTAMPS) != 0 | ||
|
||
def wantChecksums(flag: Long) = (flag & WANT_CHECKSUMS) != 0 | ||
} | ||
|
||
val queryFlagsCodec: Codec[QueryFlags] = Codec(("flag" | varintoverflow)).as[QueryFlags] | ||
|
||
val codec: Codec[TlvStream[QueryChannelRangeTlv]] = TlvCodecs.tlvStream(discriminated.by(varint) | ||
.typecase(UInt64(1), variableSizeBytesLong(varintoverflow, queryFlagsCodec)) | ||
) | ||
|
||
} |
41 changes: 41 additions & 0 deletions
41
eclair-core/src/main/scala/fr/acinq/eclair/wire/QueryShortChannelIdsTlv.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package fr.acinq.eclair.wire | ||
|
||
import fr.acinq.eclair.UInt64 | ||
import fr.acinq.eclair.wire.CommonCodecs.{shortchannelid, varint, varintoverflow} | ||
import scodec.Codec | ||
import scodec.codecs.{byte, discriminated, list, provide, variableSizeBytesLong, zlib} | ||
|
||
sealed trait QueryShortChannelIdsTlv extends Tlv | ||
|
||
object QueryShortChannelIdsTlv { | ||
|
||
/** | ||
* Optional TLV-based query message that can be appended to QueryShortChannelIds | ||
* @param encoding 0 means uncompressed, 1 means compressed with zlib | ||
* @param array array of query flags, each flags specifies the info we want for a given channel | ||
*/ | ||
case class EncodedQueryFlags(encoding: EncodingType, array: List[Long]) extends QueryShortChannelIdsTlv | ||
|
||
case object QueryFlagType { | ||
val INCLUDE_CHANNEL_ANNOUNCEMENT: Long = 1 | ||
val INCLUDE_CHANNEL_UPDATE_1: Long = 2 | ||
val INCLUDE_CHANNEL_UPDATE_2: Long = 4 | ||
val INCLUDE_ALL: Long = (INCLUDE_CHANNEL_ANNOUNCEMENT | INCLUDE_CHANNEL_UPDATE_1 | INCLUDE_CHANNEL_UPDATE_2) | ||
|
||
def includeAnnouncement(flag: Long) = (flag & INCLUDE_CHANNEL_ANNOUNCEMENT) != 0 | ||
|
||
def includeUpdate1(flag: Long) = (flag & INCLUDE_CHANNEL_UPDATE_1) != 0 | ||
|
||
def includeUpdate2(flag: Long) = (flag & INCLUDE_CHANNEL_UPDATE_2) != 0 | ||
} | ||
|
||
val encodedQueryFlagsCodec: Codec[EncodedQueryFlags] = | ||
discriminated[EncodedQueryFlags].by(byte) | ||
.\(0) { case a@EncodedQueryFlags(EncodingType.UNCOMPRESSED, _) => a }((provide[EncodingType](EncodingType.UNCOMPRESSED) :: list(varintoverflow)).as[EncodedQueryFlags]) | ||
.\(1) { case a@EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, _) => a }((provide[EncodingType](EncodingType.COMPRESSED_ZLIB) :: zlib(list(varintoverflow))).as[EncodedQueryFlags]) | ||
|
||
|
||
val codec: Codec[TlvStream[QueryShortChannelIdsTlv]] = TlvCodecs.tlvStream(discriminated.by(varint) | ||
.typecase(UInt64(1), variableSizeBytesLong(varintoverflow, encodedQueryFlagsCodec)) | ||
) | ||
} |
Oops, something went wrong.