From 19e3a194fad37a3d1e4c1453b87474c77841de8d Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Wed, 22 Aug 2018 09:32:44 +0200 Subject: [PATCH] peer+server: make fetchLastChanUpdate _always_ fetch our own update This commit fixes a bug that would cause us to fetch our peer's ChannelUpdate in some cases, where we really wanted to fetch our own. The reason this happened was that we passed the peer's pubkey to fetchLastChanUpdate, making us match on their policy. This would lead to ChannelUpdates being sent during routing which would have no effect on the attempted path. We fix this by always use our own pubkey in fetchLastChanUpdate, and also uses the common methods within the server to be able to extract the update even when only one policy is known. --- peer.go | 60 +++++++++++++------------------------------------------ server.go | 17 +++++++++++++++- 2 files changed, 30 insertions(+), 47 deletions(-) diff --git a/peer.go b/peer.go index db06a493b..df8529cf6 100644 --- a/peer.go +++ b/peer.go @@ -539,22 +539,20 @@ func (p *peer) addLink(chanPoint *wire.OutPoint, } linkCfg := htlcswitch.ChannelLinkConfig{ - Peer: p, - DecodeHopIterators: p.server.sphinx.DecodeHopIterators, - ExtractErrorEncrypter: p.server.sphinx.ExtractErrorEncrypter, - FetchLastChannelUpdate: fetchLastChanUpdate( - p.server, p.PubKey(), - ), - DebugHTLC: cfg.DebugHTLC, - HodlMask: cfg.Hodl.Mask(), - Registry: p.server.invoices, - Switch: p.server.htlcSwitch, - Circuits: p.server.htlcSwitch.CircuitModifier(), - ForwardPackets: p.server.htlcSwitch.ForwardPackets, - FwrdingPolicy: *forwardingPolicy, - FeeEstimator: p.server.cc.feeEstimator, - PreimageCache: p.server.witnessBeacon, - ChainEvents: chainEvents, + Peer: p, + DecodeHopIterators: p.server.sphinx.DecodeHopIterators, + ExtractErrorEncrypter: p.server.sphinx.ExtractErrorEncrypter, + FetchLastChannelUpdate: p.server.fetchLastChanUpdate(), + DebugHTLC: cfg.DebugHTLC, + HodlMask: cfg.Hodl.Mask(), + Registry: p.server.invoices, + Switch: p.server.htlcSwitch, + Circuits: p.server.htlcSwitch.CircuitModifier(), + ForwardPackets: p.server.htlcSwitch.ForwardPackets, + FwrdingPolicy: *forwardingPolicy, + FeeEstimator: p.server.cc.feeEstimator, + PreimageCache: p.server.witnessBeacon, + ChainEvents: chainEvents, UpdateContractSignals: func(signals *contractcourt.ContractSignals) error { return p.server.chainArb.UpdateContractSignals( *chanPoint, signals, @@ -2112,33 +2110,3 @@ func (p *peer) StartTime() time.Time { } // TODO(roasbeef): make all start/stop mutexes a CAS - -// fetchLastChanUpdate returns a function which is able to retrieve the last -// channel update for a target channel. -func fetchLastChanUpdate(s *server, - pubKey [33]byte) func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) { - - return func(cid lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) { - info, edge1, edge2, err := s.chanRouter.GetChannelByID(cid) - if err != nil { - return nil, err - } - - if edge1 == nil || edge2 == nil { - return nil, fmt.Errorf("unable to find channel by "+ - "ShortChannelID(%v)", cid) - } - - // If we're the outgoing node on the first edge, then that - // means the second edge is our policy. Otherwise, the first - // edge is our policy. - var local *channeldb.ChannelEdgePolicy - if bytes.Equal(edge1.Node.PubKeyBytes[:], pubKey[:]) { - local = edge2 - } else { - local = edge1 - } - - return extractChannelUpdate(pubKey[:], info, local) - } -} diff --git a/server.go b/server.go index b820c494a..9424eedc7 100644 --- a/server.go +++ b/server.go @@ -336,7 +336,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl, FwdingLog: chanDB.ForwardingLog(), SwitchPackager: channeldb.NewSwitchPackager(), ExtractErrorEncrypter: s.sphinx.ExtractErrorEncrypter, - FetchLastChannelUpdate: fetchLastChanUpdate(s, serializedPubKey), + FetchLastChannelUpdate: s.fetchLastChanUpdate(), Notifier: s.cc.chainNotifier, FwdEventTicker: ticker.New( htlcswitch.DefaultFwdEventInterval), @@ -2957,6 +2957,21 @@ func (s *server) fetchLastChanUpdateByOutPoint(op wire.OutPoint) ( return extractChannelUpdate(pubKey, info, edge1, edge2) } +// fetchLastChanUpdate returns a function which is able to retrieve our latest +// channel update for a target channel. +func (s *server) fetchLastChanUpdate() func(lnwire.ShortChannelID) ( + *lnwire.ChannelUpdate, error) { + + ourPubKey := s.identityPriv.PubKey().SerializeCompressed() + return func(cid lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) { + info, edge1, edge2, err := s.chanRouter.GetChannelByID(cid) + if err != nil { + return nil, err + } + return extractChannelUpdate(ourPubKey[:], info, edge1, edge2) + } +} + // extractChannelUpdate attempts to retrieve a lnwire.ChannelUpdate message // from an edge's info and a set of routing policies. // NOTE: the passed policies can be nil.