Skip to content

Commit

Permalink
Updated with suggested initial fixes
Browse files Browse the repository at this point in the history
 - only use quiescence if both nodes signal the feature
 - reduce timeout to 1 min
 - use message type 2 for `stfu`
 - Use feature bits 34/35 for option_quiesce a per spec
  • Loading branch information
remyers committed Jun 15, 2023
1 parent 22c7a7c commit f4ce212
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 12 deletions.
2 changes: 1 addition & 1 deletion eclair-core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ eclair {
channel-opener-whitelist = [] // a list of public keys; we will ignore rate limits on pending channels from these peers
}

quiescence-timeout = 2 minutes // maximum time we will wait for quiescence to complete before disconnecting
quiescence-timeout = 1 minutes // maximum time we will wait for quiescence to complete before disconnecting
}

balance-check-interval = 1 hour
Expand Down
4 changes: 1 addition & 3 deletions eclair-core/src/main/scala/fr/acinq/eclair/Features.scala
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,9 @@ object Features {
val mandatory = 154
}

// TODO: @remyers reserve feature bits here: currently reserved here: https://github.com/lightning/bolts/issues/605
// TODO: @remyers option_quiesce implementation, to be replaced once quiescence is spec-ed
case object QuiescePrototype extends Feature with InitFeature {
val rfcName = "option_quiesce_prototype"
val mandatory = 158
val mandatory = 34
}

val knownFeatures: Set[Feature] = Set(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ case class ChannelParams(channelId: ByteVector32,
else Right(remoteScriptPubKey)
}

def useQuiescence: Boolean = localParams.initFeatures.hasFeature(Features.QuiescePrototype) && remoteParams.initFeatures.hasFeature(Features.QuiescePrototype)
}

object ChannelParams {
Expand Down Expand Up @@ -797,7 +798,7 @@ case class Commitments(params: ChannelParams,

// @formatter:off
// HTLCs and pending changes are the same for all active commitments, so we don't need to loop through all of them.
def isIdle: Boolean = active.head.isIdle(changes, params.remoteParams.initFeatures.hasFeature(QuiescePrototype))
def isIdle: Boolean = active.head.isIdle(changes, params.localParams.initFeatures.hasFeature(QuiescePrototype) && params.remoteParams.initFeatures.hasFeature(QuiescePrototype))
def hasNoPendingHtlcsOrFeeUpdate: Boolean = active.head.hasNoPendingHtlcsOrFeeUpdate(changes)
def hasPendingOrProposedHtlcs: Boolean = active.head.hasPendingOrProposedHtlcs(changes)
def timedOutOutgoingHtlcs(currentHeight: BlockHeight): Set[UpdateAddHtlc] = active.head.timedOutOutgoingHtlcs(currentHeight)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case _ => handleCommandError(error, c)
}

case Event(msg: ForbiddenMessageDuringSplice, d: DATA_NORMAL) if d.commitments.params.remoteParams.initFeatures.hasFeature(QuiescePrototype) && d.spliceStatus != SpliceStatus.NoSplice && !d.spliceStatus.isInstanceOf[SpliceStatus.InitiatorQuiescent] =>
case Event(msg: ForbiddenMessageDuringSplice, d: DATA_NORMAL) if d.commitments.params.useQuiescence && d.spliceStatus != SpliceStatus.NoSplice && !d.spliceStatus.isInstanceOf[SpliceStatus.InitiatorQuiescent] =>
val error = ForbiddenDuringSplice(d.channelId, msg.getClass.getSimpleName)
msg match {
case fulfill: UpdateFulfillHtlc =>
Expand Down Expand Up @@ -809,7 +809,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with

case Event(cmd: CMD_SPLICE, d: DATA_NORMAL) =>
if (d.commitments.params.remoteParams.initFeatures.hasFeature(SplicePrototype)) {
if (d.commitments.params.remoteParams.initFeatures.hasFeature(QuiescePrototype) && d.spliceStatus == SpliceStatus.NoSplice) {
if (d.commitments.params.useQuiescence && d.spliceStatus == SpliceStatus.NoSplice) {
startSingleTimer(QuiescenceTimeout.toString, QuiescenceTimeout(peer), nodeParams.channelConf.revocationTimeout)
if (d.commitments.changes.localChanges.all.isEmpty) {
stay() using d.copy(spliceStatus = SpliceStatus.InitiatorQuiescent(cmd)) sending Stfu(d.channelId, 1)
Expand All @@ -826,7 +826,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
}

case Event(msg: Stfu, d: DATA_NORMAL) =>
if (d.commitments.params.remoteParams.initFeatures.hasFeature(QuiescePrototype)) {
if (d.commitments.params.useQuiescence) {
d.spliceStatus match {
case SpliceStatus.NoSplice =>
startSingleTimer(QuiescenceTimeout.toString, QuiescenceTimeout(peer), nodeParams.channelConf.quiescenceTimeout)
Expand Down Expand Up @@ -856,7 +856,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
stay()
}
} else {
log.warning("ignoring stfu because peer doesn't support quiescence")
log.warning("ignoring stfu because both peers do not advertise quiescence")
stay()
}

Expand Down Expand Up @@ -2644,7 +2644,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
}

private def replayQuiescenceSettlements(d: DATA_NORMAL): Unit =
if (d.commitments.params.remoteParams.initFeatures.hasFeature(QuiescePrototype)) {
if (d.commitments.params.useQuiescence) {
PendingCommandsDb.getSettlementCommands(nodeParams.db.pendingCommands, d.channelId).foreach(self ! _)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ object LightningMessageCodecs {

val lightningMessageCodec = discriminated[LightningMessage].by(uint16)
.typecase(1, warningCodec)
.typecase(2, stfuCodec)
.typecase(16, initCodec)
.typecase(17, errorCodec)
.typecase(18, pingCodec)
Expand Down Expand Up @@ -481,7 +482,6 @@ object LightningMessageCodecs {
.typecase(37000, spliceInitCodec)
.typecase(37002, spliceAckCodec)
.typecase(37004, spliceLockedCodec)
.typecase(37006, stfuCodec)
//

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ case class ChannelReady(channelId: ByteVector32,
val alias_opt: Option[Alias] = tlvStream.get[ShortChannelIdTlv].map(_.alias)
}

case class Stfu(channelId: ByteVector32, initiator: Byte) extends LightningMessage

case class SpliceInit(channelId: ByteVector32,
fundingContribution: Satoshi,
feerate: FeeratePerKw,
Expand Down Expand Up @@ -562,7 +564,6 @@ case class GossipTimestampFilter(chainHash: ByteVector32, firstTimestamp: Timest

case class OnionMessage(blindingKey: PublicKey, onionRoutingPacket: OnionRoutingPacket, tlvStream: TlvStream[OnionMessageTlv] = TlvStream.empty) extends LightningMessage

case class Stfu(channelId: ByteVector32, initiator: Byte) extends LightningMessage
// NB: blank lines to minimize merge conflicts

//
Expand Down

0 comments on commit f4ce212

Please sign in to comment.