Merge pull request #2018 from halseth/peer-remove-failed-chans
Mark channels borked in case of remote error
This commit is contained in:
commit
428ca37301
@ -1900,9 +1900,14 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
|
|||||||
// Error received from remote, MUST fail channel, but should
|
// Error received from remote, MUST fail channel, but should
|
||||||
// only print the contents of the error message if all
|
// only print the contents of the error message if all
|
||||||
// characters are printable ASCII.
|
// characters are printable ASCII.
|
||||||
l.fail(LinkFailureError{code: ErrRemoteError},
|
l.fail(
|
||||||
|
LinkFailureError{
|
||||||
|
code: ErrRemoteError,
|
||||||
|
PermanentFailure: true,
|
||||||
|
},
|
||||||
"ChannelPoint(%v): received error from peer: %v",
|
"ChannelPoint(%v): received error from peer: %v",
|
||||||
l.channel.ChannelPoint(), msg.Error())
|
l.channel.ChannelPoint(), msg.Error(),
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
l.log.Warnf("received unknown message of type %T", msg)
|
l.log.Warnf("received unknown message of type %T", msg)
|
||||||
}
|
}
|
||||||
|
@ -5129,6 +5129,11 @@ func TestChannelLinkFail(t *testing.T) {
|
|||||||
// force close the channel in response to the actions performed
|
// force close the channel in response to the actions performed
|
||||||
// during the linkTest.
|
// during the linkTest.
|
||||||
shouldForceClose bool
|
shouldForceClose bool
|
||||||
|
|
||||||
|
// permanentFailure indicates whether we expect the link to
|
||||||
|
// consider the failure permanent in response to the actions
|
||||||
|
// performed during the linkTest.
|
||||||
|
permanentFailure bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
// Test that we don't force close if syncing states
|
// Test that we don't force close if syncing states
|
||||||
@ -5144,6 +5149,7 @@ func TestChannelLinkFail(t *testing.T) {
|
|||||||
// Should fail at startup.
|
// Should fail at startup.
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Test that we don't force closes the channel if
|
// Test that we don't force closes the channel if
|
||||||
@ -5160,6 +5166,7 @@ func TestChannelLinkFail(t *testing.T) {
|
|||||||
// Should fail at startup.
|
// Should fail at startup.
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Test that we force close the channel if we receive
|
// Test that we force close the channel if we receive
|
||||||
@ -5176,6 +5183,7 @@ func TestChannelLinkFail(t *testing.T) {
|
|||||||
c.HandleChannelUpdate(htlcSettle)
|
c.HandleChannelUpdate(htlcSettle)
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Test that we force close the channel if we receive
|
// Test that we force close the channel if we receive
|
||||||
@ -5213,6 +5221,7 @@ func TestChannelLinkFail(t *testing.T) {
|
|||||||
c.HandleChannelUpdate(commitSig)
|
c.HandleChannelUpdate(commitSig)
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Test that we force close the channel if we receive
|
// Test that we force close the channel if we receive
|
||||||
@ -5252,6 +5261,19 @@ func TestChannelLinkFail(t *testing.T) {
|
|||||||
c.HandleChannelUpdate(commitSig)
|
c.HandleChannelUpdate(commitSig)
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Test that we consider the failure permanent if we
|
||||||
|
// receive a link error from the remote.
|
||||||
|
func(c *channelLink) {
|
||||||
|
},
|
||||||
|
func(t *testing.T, c *channelLink, remoteChannel *lnwallet.LightningChannel) {
|
||||||
|
err := &lnwire.Error{}
|
||||||
|
c.HandleChannelUpdate(err)
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5302,6 +5324,12 @@ func TestChannelLinkFail(t *testing.T) {
|
|||||||
linkErr.ForceClose)
|
linkErr.ForceClose)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if test.permanentFailure != linkErr.PermanentFailure {
|
||||||
|
t.Fatalf("%d) Expected Alice set permanent failure(%v), "+
|
||||||
|
"instead got(%v)", i, test.permanentFailure,
|
||||||
|
linkErr.PermanentFailure)
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up before starting next test case.
|
// Clean up before starting next test case.
|
||||||
cleanUp()
|
cleanUp()
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,10 @@ type LinkFailureError struct {
|
|||||||
// because of this error.
|
// because of this error.
|
||||||
ForceClose bool
|
ForceClose bool
|
||||||
|
|
||||||
|
// PermanentFailure indicates whether this failure is permanent, and
|
||||||
|
// the channel should not be attempted loaded again.
|
||||||
|
PermanentFailure bool
|
||||||
|
|
||||||
// SendData is a byte slice that will be sent to the peer. If nil a
|
// SendData is a byte slice that will be sent to the peer. If nil a
|
||||||
// generic error will be sent.
|
// generic error will be sent.
|
||||||
SendData []byte
|
SendData []byte
|
||||||
|
@ -2496,6 +2496,13 @@ type linkFailureReport struct {
|
|||||||
// force closing the channel depending on severity, and sending the error
|
// force closing the channel depending on severity, and sending the error
|
||||||
// message back to the remote party.
|
// message back to the remote party.
|
||||||
func (p *Brontide) handleLinkFailure(failure linkFailureReport) {
|
func (p *Brontide) handleLinkFailure(failure linkFailureReport) {
|
||||||
|
// Retrieve the channel from the map of active channels. We do this to
|
||||||
|
// have access to it even after WipeChannel remove it from the map.
|
||||||
|
chanID := lnwire.NewChanIDFromOutPoint(&failure.chanPoint)
|
||||||
|
p.activeChanMtx.Lock()
|
||||||
|
lnChan := p.activeChannels[chanID]
|
||||||
|
p.activeChanMtx.Unlock()
|
||||||
|
|
||||||
// We begin by wiping the link, which will remove it from the switch,
|
// We begin by wiping the link, which will remove it from the switch,
|
||||||
// such that it won't be attempted used for any more updates.
|
// such that it won't be attempted used for any more updates.
|
||||||
//
|
//
|
||||||
@ -2524,6 +2531,17 @@ func (p *Brontide) handleLinkFailure(failure linkFailureReport) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a permanent failure, we will mark the channel borked.
|
||||||
|
if failure.linkErr.PermanentFailure && lnChan != nil {
|
||||||
|
peerLog.Warnf("Marking link(%v) borked due to permanent "+
|
||||||
|
"failure", failure.shortChanID)
|
||||||
|
|
||||||
|
if err := lnChan.State().MarkBorked(); err != nil {
|
||||||
|
peerLog.Errorf("Unable to mark channel %v borked: %v",
|
||||||
|
failure.shortChanID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send an error to the peer, why we failed the channel.
|
// Send an error to the peer, why we failed the channel.
|
||||||
if failure.linkErr.ShouldSendToPeer() {
|
if failure.linkErr.ShouldSendToPeer() {
|
||||||
// If SendData is set, send it to the peer. If not, we'll use
|
// If SendData is set, send it to the peer. If not, we'll use
|
||||||
|
Loading…
Reference in New Issue
Block a user