• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 12312390362

13 Dec 2024 08:44AM UTC coverage: 57.458% (+8.5%) from 48.92%
12312390362

Pull #9343

github

ellemouton
fn: rework the ContextGuard and add tests

In this commit, the ContextGuard struct is re-worked such that the
context that its new main WithCtx method provides is cancelled in sync
with a parent context being cancelled or with it's quit channel being
cancelled. Tests are added to assert the behaviour. In order for the
close of the quit channel to be consistent with the cancelling of the
derived context, the quit channel _must_ be contained internal to the
ContextGuard so that callers are only able to close the channel via the
exposed Quit method which will then take care to first cancel any
derived context that depend on the quit channel before returning.
Pull Request #9343: fn: expand the ContextGuard and add tests

101853 of 177264 relevant lines covered (57.46%)

24972.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/htlcswitch/linkfailure.go
1
package htlcswitch
2

3
import "github.com/go-errors/errors"
4

5
var (
6
        // ErrLinkShuttingDown signals that the link is shutting down.
7
        ErrLinkShuttingDown = errors.New("link shutting down")
8

9
        // ErrLinkFailedShutdown signals that a requested shutdown failed.
10
        ErrLinkFailedShutdown = errors.New("link failed to shutdown")
11
)
12

13
// errorCode encodes the possible types of errors that will make us fail the
14
// current link.
15
type errorCode uint8
16

17
const (
18
        // ErrInternalError indicates that something internal in the link
19
        // failed. In this case we will send a generic error to our peer.
20
        ErrInternalError errorCode = iota
21

22
        // ErrRemoteError indicates that our peer sent an error, prompting up
23
        // to fail the link.
24
        ErrRemoteError
25

26
        // ErrRemoteUnresponsive indicates that our peer took too long to
27
        // complete a commitment dance.
28
        ErrRemoteUnresponsive
29

30
        // ErrSyncError indicates that we failed synchronizing the state of the
31
        // channel with our peer.
32
        ErrSyncError
33

34
        // ErrInvalidUpdate indicates that the peer send us an invalid update.
35
        ErrInvalidUpdate
36

37
        // ErrInvalidCommitment indicates that the remote peer sent us an
38
        // invalid commitment signature.
39
        ErrInvalidCommitment
40

41
        // ErrInvalidRevocation indicates that the remote peer send us an
42
        // invalid revocation message.
43
        ErrInvalidRevocation
44

45
        // ErrRecoveryError the channel was unable to be resumed, we need the
46
        // remote party to force close the channel out on chain now as a
47
        // result.
48
        ErrRecoveryError
49

50
        // ErrCircuitError indicates a duplicate keystone error was hit in the
51
        // circuit map. This is non-fatal and will resolve itself (usually
52
        // within several minutes).
53
        ErrCircuitError
54

55
        // ErrStfuViolation indicates that the quiescence protocol has been
56
        // violated, either because Stfu has been sent/received at an invalid
57
        // time, or that an update has been sent/received while the channel is
58
        // quiesced.
59
        ErrStfuViolation
60
)
61

62
// LinkFailureAction is an enum-like type that describes the action that should
63
// be taken in response to a link failure.
64
type LinkFailureAction uint8
65

66
const (
67
        // LinkFailureForceNone indicates no action is to be taken.
68
        LinkFailureForceNone LinkFailureAction = iota
69

70
        // LinkFailureForceClose indicates that the channel should be force
71
        // closed.
72
        LinkFailureForceClose
73

74
        // LinkFailureDisconnect indicates that we should disconnect in an
75
        // attempt to recycle the connection. This can be useful if we think a
76
        // TCP connection or state machine is stalled.
77
        LinkFailureDisconnect
78
)
79

80
// LinkFailureError encapsulates an error that will make us fail the current
81
// link. It contains the necessary information needed to determine if we should
82
// force close the channel in the process, and if any error data should be sent
83
// to the peer.
84
type LinkFailureError struct {
85
        // code is the type of error this LinkFailureError encapsulates.
86
        code errorCode
87

88
        // FailureAction describes what we should do to fail the channel.
89
        FailureAction LinkFailureAction
90

91
        // PermanentFailure indicates whether this failure is permanent, and
92
        // the channel should not be attempted loaded again.
93
        PermanentFailure bool
94

95
        // Warning denotes if this is a non-terminal error that doesn't warrant
96
        // failing the channel all together.
97
        Warning bool
98

99
        // SendData is a byte slice that will be sent to the peer. If nil a
100
        // generic error will be sent.
101
        SendData []byte
102
}
103

104
// A compile time check to ensure LinkFailureError implements the error
105
// interface.
106
var _ error = (*LinkFailureError)(nil)
107

108
// Error returns a generic error for the LinkFailureError.
109
//
110
// NOTE: Part of the error interface.
111
func (e LinkFailureError) Error() string {
×
112
        switch e.code {
×
113
        case ErrInternalError:
×
114
                return "internal error"
×
115
        case ErrRemoteError:
×
116
                return "remote error"
×
117
        case ErrRemoteUnresponsive:
×
118
                return "remote unresponsive"
×
119
        case ErrSyncError:
×
120
                return "sync error"
×
121
        case ErrInvalidUpdate:
×
122
                return "invalid update"
×
123
        case ErrInvalidCommitment:
×
124
                return "invalid commitment"
×
125
        case ErrInvalidRevocation:
×
126
                return "invalid revocation"
×
127
        case ErrRecoveryError:
×
128
                return "unable to resume channel, recovery required"
×
129
        case ErrCircuitError:
×
130
                return "non-fatal circuit map error"
×
131
        case ErrStfuViolation:
×
132
                return "quiescence protocol executed improperly"
×
133
        default:
×
134
                return "unknown error"
×
135
        }
136
}
137

138
// ShouldSendToPeer indicates whether we should send an error to the peer if
139
// the link fails with this LinkFailureError.
140
func (e LinkFailureError) ShouldSendToPeer() bool {
×
141
        switch e.code {
×
142

143
        // Since sending an error can lead some nodes to force close the
144
        // channel, create a whitelist of the failures we want to send so that
145
        // newly added error codes aren't automatically sent to the remote peer.
146
        case
147
                ErrInternalError,
148
                ErrRemoteError,
149
                ErrSyncError,
150
                ErrInvalidUpdate,
151
                ErrInvalidCommitment,
152
                ErrInvalidRevocation,
153
                ErrRecoveryError:
×
154

×
155
                return true
×
156

157
        // In all other cases we will not attempt to send our peer an error.
158
        default:
×
159
                return false
×
160
        }
161
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc