@@ -44,7 +44,8 @@ import fr.acinq.eclair.remote.EclairInternalsSerializer.RemoteTypes
4444import fr .acinq .eclair .router .Router
4545import fr .acinq .eclair .wire .protocol
4646import fr .acinq .eclair .wire .protocol .FailureMessageCodecs .createBadOnionFailure
47- import fr .acinq .eclair .wire .protocol .{AddFeeCredit , ChannelTlv , CurrentFeeCredit , Error , HasChannelId , HasTemporaryChannelId , LightningMessage , LiquidityAds , NodeAddress , OnTheFlyFundingFailureMessage , OnionMessage , OnionRoutingPacket , RecommendedFeerates , RoutingMessage , SpliceInit , TlvStream , TxAbort , UnknownMessage , Warning , WillAddHtlc , WillFailHtlc , WillFailMalformedHtlc }
47+ import fr .acinq .eclair .wire .protocol .{AddFeeCredit , ChannelTlv , CurrentFeeCredit , Error , HasChannelId , HasTemporaryChannelId , LightningMessage , LiquidityAds , NodeAddress , OnTheFlyFundingFailureMessage , OnionMessage , OnionRoutingPacket , PeerStorageRetrieval , PeerStorageStore , RecommendedFeerates , RoutingMessage , SpliceInit , TlvStream , TxAbort , UnknownMessage , Warning , WillAddHtlc , WillFailHtlc , WillFailMalformedHtlc }
48+ import scodec .bits .ByteVector
4849
4950/**
5051 * This actor represents a logical peer. There is one [[Peer ]] per unique remote node id at all time.
@@ -84,7 +85,7 @@ class Peer(val nodeParams: NodeParams,
8485 FinalChannelId (state.channelId) -> channel
8586 }.toMap
8687 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
88+ goto(DISCONNECTED ) using DisconnectedData (channels, None ) // when we restart, we will attempt to reconnect right away, but then we'll wait
8889 }
8990
9091 when(DISCONNECTED ) {
@@ -93,7 +94,7 @@ class Peer(val nodeParams: NodeParams,
9394 stay()
9495
9596 case Event (connectionReady : PeerConnection .ConnectionReady , d : DisconnectedData ) =>
96- gotoConnected(connectionReady, d.channels.map { case (k : ChannelId , v) => (k, v) })
97+ gotoConnected(connectionReady, d.channels.map { case (k : ChannelId , v) => (k, v) }, d.peerStorage )
9798
9899 case Event (Terminated (actor), d : DisconnectedData ) if d.channels.values.toSet.contains(actor) =>
99100 // we have at most 2 ids: a TemporaryChannelId and a FinalChannelId
@@ -461,7 +462,7 @@ class Peer(val nodeParams: NodeParams,
461462 stopPeer()
462463 } else {
463464 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)
464- goto(DISCONNECTED ) using DisconnectedData (d.channels.collect { case (k : FinalChannelId , v) => (k, v) })
465+ goto(DISCONNECTED ) using DisconnectedData (d.channels.collect { case (k : FinalChannelId , v) => (k, v) }, d.peerStorage )
465466 }
466467
467468 case Event (Terminated (actor), d : ConnectedData ) if d.channels.values.toSet.contains(actor) =>
@@ -480,7 +481,7 @@ class Peer(val nodeParams: NodeParams,
480481 log.debug(s " got new connection, killing current one and switching " )
481482 d.peerConnection ! PeerConnection .Kill (KillReason .ConnectionReplaced )
482483 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)
483- gotoConnected(connectionReady, d.channels)
484+ gotoConnected(connectionReady, d.channels, d.peerStorage )
484485
485486 case Event (msg : OnionMessage , _ : ConnectedData ) =>
486487 OnionMessages .process(nodeParams.privateKey, msg) match {
@@ -513,6 +514,9 @@ class Peer(val nodeParams: NodeParams,
513514 d.peerConnection forward unknownMsg
514515 stay()
515516
517+ case Event (store : PeerStorageStore , d : ConnectedData ) if nodeParams.features.hasFeature(Features .ProvideStorage ) && d.channels.nonEmpty =>
518+ stay() using d.copy(peerStorage = Some (store.blob))
519+
516520 case Event (unhandledMsg : LightningMessage , _) =>
517521 log.warning(" ignoring message {}" , unhandledMsg)
518522 stay()
@@ -744,7 +748,7 @@ class Peer(val nodeParams: NodeParams,
744748 context.system.eventStream.publish(PeerDisconnected (self, remoteNodeId))
745749 }
746750
747- private def gotoConnected (connectionReady : PeerConnection .ConnectionReady , channels : Map [ChannelId , ActorRef ]): State = {
751+ private def gotoConnected (connectionReady : PeerConnection .ConnectionReady , channels : Map [ChannelId , ActorRef ], peerStorage : Option [ ByteVector ] ): State = {
748752 require(remoteNodeId == connectionReady.remoteNodeId, s " invalid nodeId: $remoteNodeId != ${connectionReady.remoteNodeId}" )
749753 log.debug(" got authenticated connection to address {}" , connectionReady.address)
750754
@@ -754,6 +758,9 @@ class Peer(val nodeParams: NodeParams,
754758 nodeParams.db.peers.addOrUpdatePeer(remoteNodeId, connectionReady.address)
755759 }
756760
761+ // If we have some data stored from our peer, we send it to them before doing anything else.
762+ peerStorage.foreach(connectionReady.peerConnection ! PeerStorageRetrieval (_))
763+
757764 // let's bring existing/requested channels online
758765 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)
759766
@@ -771,7 +778,7 @@ class Peer(val nodeParams: NodeParams,
771778 connectionReady.peerConnection ! CurrentFeeCredit (nodeParams.chainHash, feeCredit.getOrElse(0 msat))
772779 }
773780
774- goto(CONNECTED ) using ConnectedData (connectionReady.address, connectionReady.peerConnection, connectionReady.localInit, connectionReady.remoteInit, channels, feerates, None )
781+ goto(CONNECTED ) using ConnectedData (connectionReady.address, connectionReady.peerConnection, connectionReady.localInit, connectionReady.remoteInit, channels, feerates, None , peerStorage )
775782 }
776783
777784 /**
@@ -908,10 +915,14 @@ object Peer {
908915
909916 sealed trait Data {
910917 def channels : Map [_ <: ChannelId , ActorRef ] // will be overridden by Map[FinalChannelId, ActorRef] or Map[ChannelId, ActorRef]
918+ def peerStorage : Option [ByteVector ]
919+ }
920+ case object Nothing extends Data {
921+ override def channels = Map .empty
922+ override def peerStorage : Option [ByteVector ] = None
911923 }
912- case object Nothing extends Data { override def channels = Map .empty }
913- case class DisconnectedData (channels : Map [FinalChannelId , ActorRef ]) extends Data
914- case class ConnectedData (address : NodeAddress , peerConnection : ActorRef , localInit : protocol.Init , remoteInit : protocol.Init , channels : Map [ChannelId , ActorRef ], currentFeerates : RecommendedFeerates , previousFeerates_opt : Option [RecommendedFeerates ]) extends Data {
924+ case class DisconnectedData (channels : Map [FinalChannelId , ActorRef ], peerStorage : Option [ByteVector ]) extends Data
925+ case class ConnectedData (address : NodeAddress , peerConnection : ActorRef , localInit : protocol.Init , remoteInit : protocol.Init , channels : Map [ChannelId , ActorRef ], currentFeerates : RecommendedFeerates , previousFeerates_opt : Option [RecommendedFeerates ], peerStorage : Option [ByteVector ]) extends Data {
915926 val connectionInfo : ConnectionInfo = ConnectionInfo (address, peerConnection, localInit, remoteInit)
916927 def localFeatures : Features [InitFeature ] = localInit.features
917928 def remoteFeatures : Features [InitFeature ] = remoteInit.features
0 commit comments