diff --git a/htlcswitch/interfaces.go b/htlcswitch/interfaces.go index 95db848cf..d2d93232d 100644 --- a/htlcswitch/interfaces.go +++ b/htlcswitch/interfaces.go @@ -57,6 +57,39 @@ type packetHandler interface { handleLocalAddPacket(*htlcPacket) error } +// ChannelUpdateHandler is an interface that provides methods that allow +// sending lnwire.Message to the underlying link as well as querying state. +type ChannelUpdateHandler interface { + // HandleChannelUpdate handles the htlc requests as settle/add/fail + // which sent to us from remote peer we have a channel with. + // + // NOTE: This function MUST be non-blocking (or block as little as + // possible). + HandleChannelUpdate(lnwire.Message) + + // ChanID returns the channel ID for the channel link. The channel ID + // is a more compact representation of a channel's full outpoint. + ChanID() lnwire.ChannelID + + // Bandwidth returns the amount of milli-satoshis which current link + // might pass through channel link. The value returned from this method + // represents the up to date available flow through the channel. This + // takes into account any forwarded but un-cleared HTLC's, and any + // HTLC's which have been set to the over flow queue. + Bandwidth() lnwire.MilliSatoshi + + // EligibleToForward returns a bool indicating if the channel is able + // to actively accept requests to forward HTLC's. A channel may be + // active, but not able to forward HTLC's if it hasn't yet finalized + // the pre-channel operation protocol with the remote peer. The switch + // will use this function in forwarding decisions accordingly. + EligibleToForward() bool + + // MayAddOutgoingHtlc returns an error if we may not add an outgoing + // htlc to the channel. + MayAddOutgoingHtlc() error +} + // ChannelLink is an interface which represents the subsystem for managing the // incoming htlc requests, applying the changes to the channel, and also // propagating/forwarding it to htlc switch. @@ -81,20 +114,12 @@ type ChannelLink interface { // Embed the packetHandler interface. packetHandler - // HandleChannelUpdate handles the htlc requests as settle/add/fail - // which sent to us from remote peer we have a channel with. - // - // NOTE: This function MUST be non-blocking (or block as little as - // possible). - HandleChannelUpdate(lnwire.Message) + // Embed the ChannelUpdateHandler interface. + ChannelUpdateHandler // ChannelPoint returns the channel outpoint for the channel link. ChannelPoint() *wire.OutPoint - // ChanID returns the channel ID for the channel link. The channel ID - // is a more compact representation of a channel's full outpoint. - ChanID() lnwire.ChannelID - // ShortChanID returns the short channel ID for the channel link. The // short channel ID encodes the exact location in the main chain that // the original funding output can be found. @@ -129,13 +154,6 @@ type ChannelLink interface { CheckHtlcTransit(payHash [32]byte, amt lnwire.MilliSatoshi, timeout uint32, heightNow uint32) *LinkError - // Bandwidth returns the amount of milli-satoshis which current link - // might pass through channel link. The value returned from this method - // represents the up to date available flow through the channel. This - // takes into account any forwarded but un-cleared HTLC's, and any - // HTLC's which have been set to the over flow queue. - Bandwidth() lnwire.MilliSatoshi - // Stats return the statistics of channel link. Number of updates, // total sent/received milli-satoshis. Stats() (uint64, lnwire.MilliSatoshi, lnwire.MilliSatoshi) @@ -144,17 +162,6 @@ type ChannelLink interface { // the channel link opened. Peer() lnpeer.Peer - // EligibleToForward returns a bool indicating if the channel is able - // to actively accept requests to forward HTLC's. A channel may be - // active, but not able to forward HTLC's if it hasn't yet finalized - // the pre-channel operation protocol with the remote peer. The switch - // will use this function in forwarding decisions accordingly. - EligibleToForward() bool - - // MayAddOutgoingHtlc returns an error if we may not add an outgoing - // htlc to the channel. - MayAddOutgoingHtlc() error - // AttachMailBox delivers an active MailBox to the link. The MailBox may // have buffered messages. AttachMailBox(MailBox) diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go index 964ef8405..32832d854 100644 --- a/htlcswitch/switch.go +++ b/htlcswitch/switch.go @@ -2022,7 +2022,9 @@ func (s *Switch) addLiveLink(link ChannelLink) { // GetLink is used to initiate the handling of the get link command. The // request will be propagated/handled to/in the main goroutine. -func (s *Switch) GetLink(chanID lnwire.ChannelID) (ChannelLink, error) { +func (s *Switch) GetLink(chanID lnwire.ChannelID) (ChannelUpdateHandler, + error) { + s.indexMtx.RLock() defer s.indexMtx.RUnlock() @@ -2164,11 +2166,26 @@ func (s *Switch) UpdateShortChanID(chanID lnwire.ChannelID) error { // GetLinksByInterface fetches all the links connected to a particular node // identified by the serialized compressed form of its public key. -func (s *Switch) GetLinksByInterface(hop [33]byte) ([]ChannelLink, error) { +func (s *Switch) GetLinksByInterface(hop [33]byte) ([]ChannelUpdateHandler, + error) { + s.indexMtx.RLock() defer s.indexMtx.RUnlock() - return s.getLinks(hop) + var handlers []ChannelUpdateHandler + + links, err := s.getLinks(hop) + if err != nil { + return nil, err + } + + // Range over the returned []ChannelLink to convert them into + // []ChannelUpdateHandler. + for _, link := range links { + handlers = append(handlers, link) + } + + return handlers, nil } // getLinks is function which returns the channel links of the peer by hop diff --git a/peer/brontide.go b/peer/brontide.go index b54eac4be..843b93a26 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -1142,7 +1142,7 @@ func (ms *msgStream) AddMsg(msg lnwire.Message) { // ChannelLink to pass messages to. It accomplishes this by subscribing to // an ActiveLinkEvent which is emitted by the link when it first starts up. func waitUntilLinkActive(p *Brontide, - cid lnwire.ChannelID) htlcswitch.ChannelLink { + cid lnwire.ChannelID) htlcswitch.ChannelUpdateHandler { // Subscribe to receive channel events. // @@ -1164,9 +1164,11 @@ func waitUntilLinkActive(p *Brontide, // The link may already be active by this point, and we may have missed the // ActiveLinkEvent. Check if the link exists. - link, _ := p.cfg.Switch.GetLink(cid) - if link != nil { - return link + links, _ := p.cfg.Switch.GetLinksByInterface(p.cfg.PubKeyBytes) + for _, link := range links { + if link.ChanID() == cid { + return link + } } // If the link is nil, we must wait for it to be active. @@ -1194,8 +1196,16 @@ func waitUntilLinkActive(p *Brontide, // The link shouldn't be nil as we received an // ActiveLinkEvent. If it is nil, we return nil and the // calling function should catch it. - link, _ = p.cfg.Switch.GetLink(cid) - return link + links, _ = p.cfg.Switch.GetLinksByInterface( + p.cfg.PubKeyBytes, + ) + for _, link := range links { + if link.ChanID() == cid { + return link + } + } + + return nil case <-p.quit: return nil @@ -1211,7 +1221,7 @@ func waitUntilLinkActive(p *Brontide, // lookups. func newChanMsgStream(p *Brontide, cid lnwire.ChannelID) *msgStream { - var chanLink htlcswitch.ChannelLink + var chanLink htlcswitch.ChannelUpdateHandler apply := func(msg lnwire.Message) { // This check is fine because if the link no longer exists, it will