htlcswitch+router+server: handle payment error topology updates

In previous commits we have intoduced the onion errors. Some of this
errors include lnwire.ChannelUpdate message. In order to change
topology accordingly to the received error, from nodes where failure
have occured, we have to propogate the update to the router subsystem.
This commit is contained in:
Andrey Samokhvalov 2017-06-29 17:03:42 +03:00 committed by Olaoluwa Osuntokun
parent 6bbb7cbfc3
commit 79b8d26b1a
4 changed files with 64 additions and 11 deletions

@ -51,13 +51,17 @@ func newMockServer(t *testing.T, name string) *mockServer {
copy(id[:], h[:])
return &mockServer{
t: t,
id: id,
name: name,
messages: make(chan lnwire.Message, 3000),
quit: make(chan bool),
registry: newMockRegistry(),
htlcSwitch: New(Config{}),
t: t,
id: id,
name: name,
messages: make(chan lnwire.Message, 3000),
quit: make(chan bool),
registry: newMockRegistry(),
htlcSwitch: New(Config{
UpdateTopology: func(msg *lnwire.ChannelUpdate) error {
return nil
},
}),
recordFuncs: make([]func(lnwire.Message), 0),
}
}

@ -88,6 +88,10 @@ type Config struct {
// or forced unilateral closure of the channel initiated by a local
// subsystem.
LocalChannelClose func(pubKey []byte, request *ChanClose)
// UpdateTopology sends the onion error failure topology update to router
// subsystem.
UpdateTopology func(msg *lnwire.ChannelUpdate) error
}
// Switch is the central messaging bus for all incoming/outgoing HTLCs.
@ -313,6 +317,31 @@ func (s *Switch) handleLocalDispatch(payment *pendingPayment, packet *htlcPacket
err)
log.Error(userErr)
} else {
// Process payment failure by updating the lightning network
// topology by using router subsystem handler.
var update *lnwire.ChannelUpdate
switch failure := failure.(type) {
case *lnwire.FailTemporaryChannelFailure:
update = failure.Update
case *lnwire.FailAmountBelowMinimum:
update = &failure.Update
case *lnwire.FailFeeInsufficient:
update = &failure.Update
case *lnwire.FailIncorrectCltvExpiry:
update = &failure.Update
case *lnwire.FailExpiryTooSoon:
update = &failure.Update
case *lnwire.FailChannelDisabled:
update = &failure.Update
}
if update != nil {
log.Info("Received payment failure(%v), applying lightning "+
"network topology update", failure.Code())
s.cfg.UpdateTopology(update)
}
userErr = errors.New(failure.Code())
}

@ -40,7 +40,11 @@ func TestSwitchForward(t *testing.T) {
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
bobChannelLink := newMockChannelLink(chanID2, bobChanID, bobPeer)
s := New(Config{})
s := New(Config{
UpdateTopology: func(msg *lnwire.ChannelUpdate) error {
return nil
},
})
s.Start()
if err := s.AddLink(aliceChannelLink); err != nil {
t.Fatalf("unable to add alice link: %v", err)
@ -118,7 +122,11 @@ func TestSwitchCancel(t *testing.T) {
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
bobChannelLink := newMockChannelLink(chanID2, bobChanID, bobPeer)
s := New(Config{})
s := New(Config{
UpdateTopology: func(msg *lnwire.ChannelUpdate) error {
return nil
},
})
s.Start()
if err := s.AddLink(aliceChannelLink); err != nil {
t.Fatalf("unable to add alice link: %v", err)
@ -194,7 +202,11 @@ func TestSwitchAddSamePayment(t *testing.T) {
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
bobChannelLink := newMockChannelLink(chanID2, bobChanID, bobPeer)
s := New(Config{})
s := New(Config{
UpdateTopology: func(msg *lnwire.ChannelUpdate) error {
return nil
},
})
s.Start()
if err := s.AddLink(aliceChannelLink); err != nil {
t.Fatalf("unable to add alice link: %v", err)
@ -290,7 +302,11 @@ func TestSwitchSendPayment(t *testing.T) {
alicePeer := newMockServer(t, "alice")
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
s := New(Config{})
s := New(Config{
UpdateTopology: func(msg *lnwire.ChannelUpdate) error {
return nil
},
})
s.Start()
if err := s.AddLink(aliceChannelLink); err != nil {
t.Fatalf("unable to add link: %v", err)

@ -176,6 +176,10 @@ func newServer(listenAddrs []string, chanDB *channeldb.DB, cc *chainControl,
peer.localCloseChanReqs <- request
},
UpdateTopology: func(msg *lnwire.ChannelUpdate) error {
s.discoverSrv.ProcessRemoteAnnouncement(msg, nil)
return nil
},
})
// If external IP addresses have been specified, add those to the list