1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-03-13 11:35:47 +01:00

Get rid of various unnecessary warnings in logs (#2981)

* Watch explicit event for channel actor termination

We use an explicit event in the `Peer` when watching for child channel
actors being terminated. This should get rid of the warnings in the logs
about the `Terminated` event not being handled, or at least provide us
more hints of which actors aren't properly being tracked.

* Fix disconnect response in channel actors

We weren't watching for the right event, which creates a lot of log
lines saying that the `Disconnecting` event is unhandled.

* Ignore closing negotiation if closing or closed

If we receive an outdated closing message, we ignore it without creating
a warning in the logs.

* Ignore HTLC settlement commands while disconnected

We ignore HTLC settlement commands while we're disconnected, they will
be retried once the channel has been reestablished. We also ignore
commands asking us to sign the latest state or update fees.
This commit is contained in:
Bastien Teinturier 2025-01-16 08:32:16 +01:00 committed by GitHub
parent 8827a04349
commit 1c38591d0b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 72 additions and 21 deletions

View file

@ -2024,7 +2024,19 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case Event(e: Error, d: DATA_CLOSING) => handleRemoteError(e, d)
case Event(INPUT_DISCONNECTED | INPUT_RECONNECTED(_, _, _), _) => stay() // we don't really care at this point
case Event(_: Shutdown, _) =>
log.debug("ignoring shutdown, closing transaction already published")
stay()
case Event(_: ClosingSigned, _) =>
log.debug("ignoring closing_signed, closing transaction already published")
stay()
case Event(_: AnnouncementSignatures, _) =>
log.debug("ignoring announcement_signatures, channel is closing")
stay()
case Event(INPUT_DISCONNECTED | _: INPUT_RECONNECTED, _) => stay() // we don't really care at this point
})
when(CLOSED)(handleExceptions {
@ -2045,10 +2057,22 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
stay()
case Event(w: WatchTriggered, _) =>
log.warning("ignoring watch event, channel is closed (event={})", w)
log.debug("ignoring watch event, channel is closed (event={})", w)
stay()
case Event(INPUT_DISCONNECTED, _) => stay() // we are disconnected, but it doesn't matter anymore
case Event(_: Shutdown, _) =>
log.debug("ignoring shutdown, channel is closed")
stay()
case Event(_: ClosingSigned, _) =>
log.debug("ignoring closing_signed, channel is closed")
stay()
case Event(_: AnnouncementSignatures, _) =>
log.debug("ignoring announcement_signatures, channel is closed")
stay()
case Event(INPUT_DISCONNECTED | _: INPUT_RECONNECTED, _) => stay() // we are disconnected, but it doesn't matter anymore
})
when(OFFLINE)(handleExceptions {
@ -2118,6 +2142,14 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case Event(c: CMD_ADD_HTLC, d: DATA_NORMAL) => handleAddDisconnected(c, d)
case Event(e: HtlcSettlementCommand, _) =>
log.debug("cannot settle htlc_id={}, channel is offline", e.id)
stay()
case Event(_: CMD_SIGN, _) => stay()
case Event(_: CMD_UPDATE_FEE, _) => stay()
case Event(c: CMD_UPDATE_RELAY_FEE, d: DATA_NORMAL) => handleUpdateRelayFeeDisconnected(c, d)
case Event(getTxResponse: GetTxWithMetaResponse, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) if getTxResponse.txid == d.commitments.latest.fundingTxId => handleGetFundingTx(getTxResponse, d.waitingSince, d.fundingTx_opt)
@ -2325,6 +2357,14 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case Event(c: CMD_ADD_HTLC, d: DATA_NORMAL) => handleAddDisconnected(c, d)
case Event(e: HtlcSettlementCommand, _) =>
log.debug("cannot settle htlc_id={}, channel is syncing", e.id)
stay()
case Event(_: CMD_SIGN, _) => stay()
case Event(_: CMD_UPDATE_FEE, _) => stay()
case Event(c: CMD_UPDATE_RELAY_FEE, d: DATA_NORMAL) => handleUpdateRelayFeeDisconnected(c, d)
case Event(channelReestablish: ChannelReestablish, d: DATA_SHUTDOWN) =>
@ -2469,7 +2509,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case Event(_: BroadcastChannelUpdate, _) => stay()
// we receive this when we tell the peer to disconnect
case Event("disconnecting", _) => stay()
case Event(_: Peer.DisconnectResponse, _) => stay()
// funding tx was confirmed in time, let's just ignore this
case Event(BITCOIN_FUNDING_TIMEOUT, _: PersistentChannelData) => stay()

View file

@ -18,7 +18,7 @@ package fr.acinq.eclair.io
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.scaladsl.adapter.{ClassicActorContextOps, ClassicActorRefOps}
import akka.actor.{Actor, ActorContext, ActorRef, ExtendedActorSystem, FSM, OneForOneStrategy, PossiblyHarmful, Props, Status, SupervisorStrategy, Terminated, typed}
import akka.actor.{Actor, ActorContext, ActorRef, ExtendedActorSystem, FSM, OneForOneStrategy, PossiblyHarmful, Props, Status, SupervisorStrategy, typed}
import akka.event.Logging.MDC
import akka.event.{BusLogging, DiagnosticLoggingAdapter}
import akka.util.Timeout
@ -103,11 +103,15 @@ class Peer(val nodeParams: NodeParams,
case Event(connectionReady: PeerConnection.ConnectionReady, d: DisconnectedData) =>
gotoConnected(connectionReady, d.channels.map { case (k: ChannelId, v) => (k, v) }, d.activeChannels, d.peerStorage)
case Event(Terminated(actor), d: DisconnectedData) if d.channels.values.toSet.contains(actor) =>
// we have at most 2 ids: a TemporaryChannelId and a FinalChannelId
val channelIds = d.channels.filter(_._2 == actor).keys
log.info(s"channel closed: channelId=${channelIds.mkString("/")}")
val channels1 = d.channels -- channelIds
case Event(ChannelTerminated(actor), d: DisconnectedData) =>
val channels1 = if (d.channels.values.toSet.contains(actor)) {
// we have at most 2 ids: a TemporaryChannelId and a FinalChannelId
val channelIds = d.channels.filter(_._2 == actor).keys
log.info(s"channel closed: channelId=${channelIds.mkString("/")}")
d.channels -- channelIds
} else {
d.channels
}
if (channels1.isEmpty && canForgetPendingOnTheFlyFunding()) {
log.info("that was the last open channel")
context.system.eventStream.publish(LastChannelClosed(self, remoteNodeId))
@ -495,17 +499,21 @@ class Peer(val nodeParams: NodeParams,
goto(DISCONNECTED) using DisconnectedData(d.channels.collect { case (k: FinalChannelId, v) => (k, v) }, d.activeChannels, d.peerStorage)
}
case Event(Terminated(actor), d: ConnectedData) if d.channels.values.toSet.contains(actor) =>
// we have at most 2 ids: a TemporaryChannelId and a FinalChannelId
val channelIds = d.channels.filter(_._2 == actor).keys
log.info(s"channel closed: channelId=${channelIds.mkString("/")}")
val channels1 = d.channels -- channelIds
if (channels1.isEmpty) {
log.info("that was the last open channel, closing the connection")
context.system.eventStream.publish(LastChannelClosed(self, remoteNodeId))
d.peerConnection ! PeerConnection.Kill(KillReason.NoRemainingChannel)
case Event(ChannelTerminated(actor), d: ConnectedData) =>
if (d.channels.values.toSet.contains(actor)) {
// we have at most 2 ids: a TemporaryChannelId and a FinalChannelId
val channelIds = d.channels.filter(_._2 == actor).keys
log.info(s"channel closed: channelId=${channelIds.mkString("/")}")
val channels1 = d.channels -- channelIds
if (channels1.isEmpty) {
log.info("that was the last open channel, closing the connection")
context.system.eventStream.publish(LastChannelClosed(self, remoteNodeId))
d.peerConnection ! PeerConnection.Kill(KillReason.NoRemainingChannel)
}
stay() using d.copy(channels = channels1)
} else {
stay()
}
stay() using d.copy(channels = channels1)
case Event(connectionReady: PeerConnection.ConnectionReady, d: ConnectedData) =>
log.debug(s"got new connection, killing current one and switching")
@ -843,7 +851,7 @@ class Peer(val nodeParams: NodeParams,
private def spawnChannel(): ActorRef = {
val channel = channelFactory.spawn(context, remoteNodeId)
context watch channel
context.watchWith(channel, ChannelTerminated(channel.ref))
channel
}
@ -1088,6 +1096,9 @@ object Peer {
*/
case class ConnectionDown(peerConnection: ActorRef) extends RemoteTypes
/** A child channel actor has been terminated. */
case class ChannelTerminated(channel: ActorRef) extends RemoteTypes
case class RelayOnionMessage(messageId: ByteVector32, msg: OnionMessage, replyTo_opt: Option[typed.ActorRef[Status]])
case class RelayUnknownMessage(unknownMessage: UnknownMessage)