@@ -45,6 +45,9 @@ import fr.acinq.eclair.router.Router
4545import fr .acinq .eclair .wire .protocol
4646import fr .acinq .eclair .wire .protocol .FailureMessageCodecs .createBadOnionFailure
4747import fr .acinq .eclair .wire .protocol .{AddFeeCredit , ChannelTlv , CurrentFeeCredit , Error , HasChannelId , HasTemporaryChannelId , LightningMessage , LiquidityAds , NodeAddress , OnTheFlyFundingFailureMessage , OnionMessage , OnionRoutingPacket , RoutingMessage , SpliceInit , TlvStream , UnknownMessage , Warning , WillAddHtlc , WillFailHtlc , WillFailMalformedHtlc }
48+ import fr .acinq .eclair .wire .protocol .LiquidityAds .PaymentDetails
49+ import fr .acinq .eclair .wire .protocol .{Error , HasChannelId , HasTemporaryChannelId , LightningMessage , LiquidityAds , NodeAddress , OnTheFlyFundingFailureMessage , OnionMessage , OnionRoutingPacket , PeerStorageRetrieval , PeerStorageStore , RoutingMessage , SpliceInit , UnknownMessage , Warning , WillAddHtlc , WillFailHtlc , WillFailMalformedHtlc }
50+ import scodec .bits .ByteVector
4851
4952/**
5053 * This actor represents a logical peer. There is one [[Peer ]] per unique remote node id at all time.
@@ -84,7 +87,7 @@ class Peer(val nodeParams: NodeParams,
8487 FinalChannelId (state.channelId) -> channel
8588 }.toMap
8689 context.system.eventStream.publish(PeerCreated (self, remoteNodeId))
87- goto(DISCONNECTED ) using DisconnectedData (channels) // when we restart, we will attempt to reconnect right away, but then we'll wait
90+ goto(DISCONNECTED ) using DisconnectedData (channels, None ) // when we restart, we will attempt to reconnect right away, but then we'll wait
8891 }
8992
9093 when(DISCONNECTED ) {
@@ -93,7 +96,7 @@ class Peer(val nodeParams: NodeParams,
9396 stay()
9497
9598 case Event (connectionReady : PeerConnection .ConnectionReady , d : DisconnectedData ) =>
96- gotoConnected(connectionReady, d.channels.map { case (k : ChannelId , v) => (k, v) })
99+ gotoConnected(connectionReady, d.channels.map { case (k : ChannelId , v) => (k, v) }, d.peerStorage )
97100
98101 case Event (Terminated (actor), d : DisconnectedData ) if d.channels.values.toSet.contains(actor) =>
99102 // we have at most 2 ids: a TemporaryChannelId and a FinalChannelId
@@ -454,7 +457,7 @@ class Peer(val nodeParams: NodeParams,
454457 stopPeer()
455458 } else {
456459 d.channels.values.toSet[ActorRef ].foreach(_ ! INPUT_DISCONNECTED ) // we deduplicate with toSet because there might be two entries per channel (tmp id and final id)
457- goto(DISCONNECTED ) using DisconnectedData (d.channels.collect { case (k : FinalChannelId , v) => (k, v) })
460+ goto(DISCONNECTED ) using DisconnectedData (d.channels.collect { case (k : FinalChannelId , v) => (k, v) }, d.peerStorage )
458461 }
459462
460463 case Event (Terminated (actor), d : ConnectedData ) if d.channels.values.toSet.contains(actor) =>
@@ -473,7 +476,7 @@ class Peer(val nodeParams: NodeParams,
473476 log.debug(s " got new connection, killing current one and switching " )
474477 d.peerConnection ! PeerConnection .Kill (KillReason .ConnectionReplaced )
475478 d.channels.values.toSet[ActorRef ].foreach(_ ! INPUT_DISCONNECTED ) // we deduplicate with toSet because there might be two entries per channel (tmp id and final id)
476- gotoConnected(connectionReady, d.channels)
479+ gotoConnected(connectionReady, d.channels, d.peerStorage )
477480
478481 case Event (msg : OnionMessage , _ : ConnectedData ) =>
479482 OnionMessages .process(nodeParams.privateKey, msg) match {
@@ -506,6 +509,9 @@ class Peer(val nodeParams: NodeParams,
506509 d.peerConnection forward unknownMsg
507510 stay()
508511
512+ case Event (store : PeerStorageStore , d : ConnectedData ) if nodeParams.features.hasFeature(Features .ProvideStorage ) && d.channels.nonEmpty =>
513+ stay() using d.copy(peerStorage = Some (store.blob))
514+
509515 case Event (unhandledMsg : LightningMessage , _) =>
510516 log.warning(" ignoring message {}" , unhandledMsg)
511517 stay()
@@ -716,7 +722,7 @@ class Peer(val nodeParams: NodeParams,
716722 context.system.eventStream.publish(PeerDisconnected (self, remoteNodeId))
717723 }
718724
719- private def gotoConnected (connectionReady : PeerConnection .ConnectionReady , channels : Map [ChannelId , ActorRef ]): State = {
725+ private def gotoConnected (connectionReady : PeerConnection .ConnectionReady , channels : Map [ChannelId , ActorRef ], peerStorage : Option [ ByteVector ] ): State = {
720726 require(remoteNodeId == connectionReady.remoteNodeId, s " invalid nodeId: $remoteNodeId != ${connectionReady.remoteNodeId}" )
721727 log.debug(" got authenticated connection to address {}" , connectionReady.address)
722728
@@ -726,6 +732,9 @@ class Peer(val nodeParams: NodeParams,
726732 nodeParams.db.peers.addOrUpdatePeer(remoteNodeId, connectionReady.address)
727733 }
728734
735+ // If we have some data stored from our peer, we send it to them before doing anything else.
736+ peerStorage.foreach(connectionReady.peerConnection ! PeerStorageRetrieval (_))
737+
729738 // let's bring existing/requested channels online
730739 channels.values.toSet[ActorRef ].foreach(_ ! INPUT_RECONNECTED (connectionReady.peerConnection, connectionReady.localInit, connectionReady.remoteInit)) // we deduplicate with toSet because there might be two entries per channel (tmp id and final id)
731740
@@ -742,7 +751,7 @@ class Peer(val nodeParams: NodeParams,
742751 connectionReady.peerConnection ! CurrentFeeCredit (nodeParams.chainHash, feeCredit.getOrElse(0 msat))
743752 }
744753
745- goto(CONNECTED ) using ConnectedData (connectionReady.address, connectionReady.peerConnection, connectionReady.localInit, connectionReady.remoteInit, channels)
754+ goto(CONNECTED ) using ConnectedData (connectionReady.address, connectionReady.peerConnection, connectionReady.localInit, connectionReady.remoteInit, channels, peerStorage )
746755 }
747756
748757 /**
@@ -879,10 +888,14 @@ object Peer {
879888
880889 sealed trait Data {
881890 def channels : Map [_ <: ChannelId , ActorRef ] // will be overridden by Map[FinalChannelId, ActorRef] or Map[ChannelId, ActorRef]
891+ def peerStorage : Option [ByteVector ]
892+ }
893+ case object Nothing extends Data {
894+ override def channels = Map .empty
895+ override def peerStorage : Option [ByteVector ] = None
882896 }
883- case object Nothing extends Data { override def channels = Map .empty }
884- case class DisconnectedData (channels : Map [FinalChannelId , ActorRef ]) extends Data
885- case class ConnectedData (address : NodeAddress , peerConnection : ActorRef , localInit : protocol.Init , remoteInit : protocol.Init , channels : Map [ChannelId , ActorRef ]) extends Data {
897+ case class DisconnectedData (channels : Map [FinalChannelId , ActorRef ], peerStorage : Option [ByteVector ]) extends Data
898+ case class ConnectedData (address : NodeAddress , peerConnection : ActorRef , localInit : protocol.Init , remoteInit : protocol.Init , channels : Map [ChannelId , ActorRef ], peerStorage : Option [ByteVector ]) extends Data {
886899 val connectionInfo : ConnectionInfo = ConnectionInfo (address, peerConnection, localInit, remoteInit)
887900 def localFeatures : Features [InitFeature ] = localInit.features
888901 def remoteFeatures : Features [InitFeature ] = remoteInit.features
0 commit comments