Skip to content

Commit

Permalink
Rework channel announcement signatures handling
Browse files Browse the repository at this point in the history
Now that we wait for at least 6 confirmations before considering a
channel confirmed, we can simplify our channel announcement logic.
Whenever a channel reaches the confirmed state, it can be announced
to the network (if nodes wish to announce it). We thus don't need
the "deeply buried" state and the "temporary" scid anymore.

The logic is much simpler to follow: when the channel confirms, we
internally update the real scid to match the confirmed funding tx
and send our `announcement_signatures`. When we receive our peer's
`announcement_signatures`, we stash them if the funding tx doesn't
have enough confirmations yet, otherwise we announce the channel and
create a new `channel_update` that uses the real scid.

Whenever we create a `channel_update`, we simply look at whether the
channel is announced or not to choose which scid to use.

This will make it much simpler to announce splice transactions, which
don't need a "deeply buried" state either and will instead simply rely
on whether the splice transaction is confirmed or not to generate
`announcement_signatures`.
  • Loading branch information
t-bast committed Dec 27, 2024
1 parent 083da33 commit 8c4f001
Show file tree
Hide file tree
Showing 57 changed files with 547 additions and 717 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ object ZmqWatcher {
case class WatchFundingConfirmed(replyTo: ActorRef[WatchFundingConfirmedTriggered], txId: TxId, minDepth: Long) extends WatchConfirmed[WatchFundingConfirmedTriggered]
case class WatchFundingConfirmedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered

case class WatchFundingDeeplyBuried(replyTo: ActorRef[WatchFundingDeeplyBuriedTriggered], txId: TxId, minDepth: Long) extends WatchConfirmed[WatchFundingDeeplyBuriedTriggered]
case class WatchFundingDeeplyBuriedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered

case class RelativeDelay(parentTxId: TxId, delay: Long)
case class WatchTxConfirmed(replyTo: ActorRef[WatchTxConfirmedTriggered], txId: TxId, minDepth: Long, delay_opt: Option[RelativeDelay] = None) extends WatchConfirmed[WatchTxConfirmedTriggered]
case class WatchTxConfirmedTriggered(blockHeight: BlockHeight, txIndex: Int, tx: Transaction) extends WatchConfirmedTriggered
Expand Down Expand Up @@ -429,7 +426,6 @@ private class ZmqWatcher(nodeParams: NodeParams, blockHeight: AtomicLong, client
client.getTransactionShortId(w.txId).map {
case (height, index) => w match {
case w: WatchFundingConfirmed => context.self ! TriggerEvent(w.replyTo, w, WatchFundingConfirmedTriggered(height, index, tx))
case w: WatchFundingDeeplyBuried => context.self ! TriggerEvent(w.replyTo, w, WatchFundingDeeplyBuriedTriggered(height, index, tx))
case w: WatchTxConfirmed => context.self ! TriggerEvent(w.replyTo, w, WatchTxConfirmedTriggered(height, index, tx))
case w: WatchParentTxConfirmed => context.self ! TriggerEvent(w.replyTo, w, WatchParentTxConfirmedTriggered(height, index, tx))
case w: WatchAlternativeCommitTxConfirmed => context.self ! TriggerEvent(w.replyTo, w, WatchAlternativeCommitTxConfirmedTriggered(height, index, tx))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,27 +416,17 @@ case class RevokedCommitPublished(commitTx: Transaction, claimMainOutputTx: Opti
}
}

sealed trait RealScidStatus { def toOption: Option[RealShortChannelId] }
object RealScidStatus {
/** The funding transaction has been confirmed but hasn't reached min_depth, we must be ready for a reorg. */
case class Temporary(realScid: RealShortChannelId) extends RealScidStatus { override def toOption: Option[RealShortChannelId] = Some(realScid) }
/** The funding transaction has been deeply confirmed. */
case class Final(realScid: RealShortChannelId) extends RealScidStatus { override def toOption: Option[RealShortChannelId] = Some(realScid) }
/** We don't know the status of the funding transaction. */
case object Unknown extends RealScidStatus { override def toOption: Option[RealShortChannelId] = None }
}

/**
* Short identifiers for the channel
* Short identifiers for the channel.
*
* @param real the real scid, it may change if a reorg happens before the channel reaches 6 conf
* @param real_opt the real scid of the latest announced (and thus confirmed) funding transaction.
* @param localAlias we must remember the alias that we sent to our peer because we use it to:
* - identify incoming [[ChannelUpdate]] at the connection level
* - route outgoing payments to that channel
* @param remoteAlias_opt we only remember the last alias received from our peer, we use this to generate
* routing hints in [[fr.acinq.eclair.payment.Bolt11Invoice]]
*/
case class ShortIds(real: RealScidStatus, localAlias: Alias, remoteAlias_opt: Option[Alias])
case class ShortIds(real_opt: Option[RealShortChannelId], localAlias: Alias, remoteAlias_opt: Option[Alias])

sealed trait LocalFundingStatus {
def signedTx_opt: Option[Transaction]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ case class ChannelRestored(channel: ActorRef, channelId: ByteVector32, peer: Act
case class ChannelIdAssigned(channel: ActorRef, remoteNodeId: PublicKey, temporaryChannelId: ByteVector32, channelId: ByteVector32) extends ChannelEvent

/** This event will be sent whenever a new scid is assigned to the channel, be it a real, local alias or remote alias. */
case class ShortChannelIdAssigned(channel: ActorRef, channelId: ByteVector32, shortIds: ShortIds, remoteNodeId: PublicKey) extends ChannelEvent
case class ShortChannelIdAssigned(channel: ActorRef, channelId: ByteVector32, shortIds: ShortIds, remoteNodeId: PublicKey, isAnnounced: Boolean) extends ChannelEvent

/** This event will be sent if a channel was aborted before completing the opening flow. */
case class ChannelAborted(channel: ActorRef, remoteNodeId: PublicKey, channelId: ByteVector32) extends ChannelEvent
Expand All @@ -64,7 +64,7 @@ case class LocalChannelUpdate(channel: ActorRef, channelId: ByteVector32, shortI
def scidsForRouting: Seq[ShortChannelId] = {
val canUseRealScid = !commitments.params.channelFeatures.hasFeature(Features.ScidAlias)
if (canUseRealScid) {
shortIds.real.toOption.toSeq :+ shortIds.localAlias
shortIds.real_opt.toSeq :+ shortIds.localAlias
} else {
Seq(shortIds.localAlias)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ object Helpers {
def channelUpdateForDirectPeer(nodeParams: NodeParams, channelUpdate: ChannelUpdate, shortIds: ShortIds): ChannelUpdate = {
shortIds.remoteAlias_opt match {
case Some(remoteAlias) => Announcements.updateScid(nodeParams.privateKey, channelUpdate, remoteAlias)
case None => shortIds.real.toOption match {
case None => shortIds.real_opt match {
case Some(realScid) => Announcements.updateScid(nodeParams.privateKey, channelUpdate, realScid)
// This case is a spec violation: this is a 0-conf channel, so our peer MUST send their alias.
// They won't be able to match our channel_update with their local channel, too bad for them.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Register extends Actor with ActorLogging {
case scidAssigned: ShortChannelIdAssigned =>
// We map all known scids (real or alias) to the channel_id. The relayer is in charge of deciding whether a real
// scid can be used or not for routing (see option_scid_alias), but the register is neutral.
val m = (scidAssigned.shortIds.real.toOption.toSeq :+ scidAssigned.shortIds.localAlias).map(_ -> scidAssigned.channelId).toMap
val m = (scidAssigned.shortIds.real_opt.toSeq :+ scidAssigned.shortIds.localAlias).map(_ -> scidAssigned.channelId).toMap
// duplicate check for aliases (we use a random value in a large enough space that there should never be collisions)
shortIds.get(scidAssigned.shortIds.localAlias) match {
case Some(channelId) if channelId != scidAssigned.channelId =>
Expand Down
Loading

0 comments on commit 8c4f001

Please sign in to comment.