Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework channel announcement signatures handling #2969

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion eclair-core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ eclair {

to-remote-delay-blocks = 720 // number of blocks that the other node's to-self outputs must be delayed (720 ~ 5 days)
max-to-local-delay-blocks = 2016 // maximum number of blocks that we are ready to accept for our own delayed outputs (2016 ~ 2 weeks)
mindepth-blocks = 3
min-depth-funding-blocks = 6 // minimum number of confirmations for funding transactions
min-depth-closing-blocks = 3 // minimum number of confirmations for closing transactions
expiry-delta-blocks = 144
max-expiry-delta-blocks = 2016 // we won't forward HTLCs with timeouts greater than this delta
// When we receive the preimage for an HTLC and want to fulfill it but the upstream peer stops responding, we want to
Expand Down
9 changes: 6 additions & 3 deletions eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,11 @@ object NodeParams extends Logging {
"channel.min-funding-satoshis" -> "channel.min-public-funding-satoshis, channel.min-private-funding-satoshis",
// v0.8.0
"bitcoind.batch-requests" -> "bitcoind.batch-watcher-requests",
// vx.x.x
// v0.9.0
"on-chain-fees.target-blocks.safe-utxos-threshold" -> "on-chain-fees.safe-utxos-threshold",
"on-chain-fees.target-blocks" -> "on-chain-fees.confirmation-priority"
"on-chain-fees.target-blocks" -> "on-chain-fees.confirmation-priority",
// v0.12.0
"channel.mindepth-blocks" -> "channel.min-depth-funding-blocks",
)
deprecatedKeyPaths.foreach {
case (old, new_) => require(!config.hasPath(old), s"configuration key '$old' has been replaced by '$new_'")
Expand Down Expand Up @@ -573,7 +575,8 @@ object NodeParams extends Logging {
minFundingPrivateSatoshis = Satoshi(config.getLong("channel.min-private-funding-satoshis")),
toRemoteDelay = offeredCLTV,
maxToLocalDelay = maxToLocalCLTV,
minDepthBlocks = config.getInt("channel.mindepth-blocks"),
minDepthFunding = config.getInt("channel.min-depth-funding-blocks"),
minDepthClosing = config.getInt("channel.min-depth-closing-blocks"),
expiryDelta = expiryDelta,
maxExpiryDelta = maxExpiryDelta,
fulfillSafetyBeforeTimeout = fulfillSafetyBeforeTimeout,
Expand Down
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 @@ -141,8 +141,8 @@ object ChannelParams {
// small amount: not scaled
defaultMinDepth
} else {
val blockReward = 6.25 // this is true as of ~May 2020, but will be too large after 2024
val scalingFactor = 15
val blockReward = 3.125 // this will be too large after the halving in 2028
val scalingFactor = 10
val blocksToReachFunding = (((scalingFactor * amount.toBtc.toDouble) / blockReward).ceil + 1).toInt
defaultMinDepth.max(blocksToReachFunding)
}
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
Loading