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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

85.45
/htlcswitch/failure.go
1
package htlcswitch
2

3
import (
4
        "bytes"
5
        "fmt"
6

7
        sphinx "github.com/lightningnetwork/lightning-onion"
8
        "github.com/lightningnetwork/lnd/htlcswitch/hop"
9
        "github.com/lightningnetwork/lnd/lnwire"
10
)
11

12
// ClearTextError is an interface which is implemented by errors that occur
13
// when we know the underlying wire failure message. These errors are the
14
// opposite to opaque errors which are onion-encrypted blobs only understandable
15
// to the initiating node. ClearTextErrors are used when we fail a htlc at our
16
// node, or one of our initiated payments failed and we can decrypt the onion
17
// encrypted error fully.
18
type ClearTextError interface {
19
        error
20

21
        // WireMessage extracts a valid wire failure message from an internal
22
        // error which may contain additional metadata (which should not be
23
        // exposed to the network). This value may be nil in the case where
24
        // an unknown wire error is returned by one of our peers.
25
        WireMessage() lnwire.FailureMessage
26
}
27

28
// LinkError is an implementation of the ClearTextError interface which
29
// represents failures that occur on our incoming or outgoing link.
30
type LinkError struct {
31
        // msg returns the wire failure associated with the error.
32
        // This value should *not* be nil, because we should always
33
        // know the failure type for failures which occur at our own
34
        // node.
35
        msg lnwire.FailureMessage
36

37
        // FailureDetail enriches the wire error with additional information.
38
        FailureDetail
39
}
40

41
// NewLinkError returns a LinkError with the failure message provided.
42
// The failure message provided should *not* be nil, because we should
43
// always know the failure type for failures which occur at our own node.
44
func NewLinkError(msg lnwire.FailureMessage) *LinkError {
135✔
45
        return &LinkError{msg: msg}
135✔
46
}
135✔
47

48
// NewDetailedLinkError returns a link error that enriches a wire message with
49
// a failure detail.
50
func NewDetailedLinkError(msg lnwire.FailureMessage,
51
        detail FailureDetail) *LinkError {
77✔
52

77✔
53
        return &LinkError{
77✔
54
                msg:           msg,
77✔
55
                FailureDetail: detail,
77✔
56
        }
77✔
57
}
77✔
58

59
// WireMessage extracts a valid wire failure message from an internal
60
// error which may contain additional metadata (which should not be
61
// exposed to the network). This value should never be nil for LinkErrors,
62
// because we are the ones failing the htlc.
63
//
64
// Note this is part of the ClearTextError interface.
65
func (l *LinkError) WireMessage() lnwire.FailureMessage {
148✔
66
        return l.msg
148✔
67
}
148✔
68

69
// Error returns the string representation of a link error.
70
//
71
// Note this is part of the ClearTextError interface.
72
func (l *LinkError) Error() string {
26✔
73
        // If the link error has no failure detail, return the wire message's
26✔
74
        // error.
26✔
75
        if l.FailureDetail == nil {
43✔
76
                return l.msg.Error()
17✔
77
        }
17✔
78

79
        return l.FailureDetail.FailureString()
9✔
80
}
81

82
// ForwardingError wraps an lnwire.FailureMessage in a struct that also
83
// includes the source of the error.
84
type ForwardingError struct {
85
        // FailureSourceIdx is the index of the node that sent the failure. With
86
        // this information, the dispatcher of a payment can modify their set of
87
        // candidate routes in response to the type of failure extracted. Index
88
        // zero is the self node.
89
        FailureSourceIdx int
90

91
        // msg is the wire message associated with the error. This value may
92
        // be nil in the case where we fail to decode failure message sent by
93
        // a peer.
94
        msg lnwire.FailureMessage
95
}
96

97
// WireMessage extracts a valid wire failure message from an internal
98
// error which may contain additional metadata (which should not be
99
// exposed to the network). This value may be nil in the case where
100
// an unknown wire error is returned by one of our peers.
101
//
102
// Note this is part of the ClearTextError interface.
103
func (f *ForwardingError) WireMessage() lnwire.FailureMessage {
160✔
104
        return f.msg
160✔
105
}
160✔
106

107
// Error implements the built-in error interface. We use this method to allow
108
// the switch or any callers to insert additional context to the error message
109
// returned.
UNCOV
110
func (f *ForwardingError) Error() string {
×
UNCOV
111
        return fmt.Sprintf(
×
UNCOV
112
                "%v@%v", f.msg, f.FailureSourceIdx,
×
UNCOV
113
        )
×
UNCOV
114
}
×
115

116
// NewForwardingError creates a new payment error which wraps a wire error
117
// with additional metadata.
118
func NewForwardingError(failure lnwire.FailureMessage,
119
        index int) *ForwardingError {
139✔
120

139✔
121
        return &ForwardingError{
139✔
122
                FailureSourceIdx: index,
139✔
123
                msg:              failure,
139✔
124
        }
139✔
125
}
139✔
126

127
// NewUnknownForwardingError returns a forwarding error which has a nil failure
128
// message. This constructor should only be used in the case where we cannot
129
// decode the failure we have received from a peer.
130
func NewUnknownForwardingError(index int) *ForwardingError {
2✔
131
        return &ForwardingError{
2✔
132
                FailureSourceIdx: index,
2✔
133
        }
2✔
134
}
2✔
135

136
// ErrorDecrypter is an interface that is used to decrypt the onion encrypted
137
// failure reason an extra out a well formed error.
138
type ErrorDecrypter interface {
139
        // DecryptError peels off each layer of onion encryption from the first
140
        // hop, to the source of the error. A fully populated
141
        // lnwire.FailureMessage is returned along with the source of the
142
        // error.
143
        DecryptError(lnwire.OpaqueReason) (*ForwardingError, error)
144
}
145

146
// UnknownEncrypterType is an error message used to signal that an unexpected
147
// EncrypterType was encountered during decoding.
148
type UnknownEncrypterType hop.EncrypterType
149

150
// Error returns a formatted error indicating the invalid EncrypterType.
151
func (e UnknownEncrypterType) Error() string {
×
152
        return fmt.Sprintf("unknown error encrypter type: %d", e)
×
153
}
×
154

155
// OnionErrorDecrypter is the interface that provides onion level error
156
// decryption.
157
type OnionErrorDecrypter interface {
158
        // DecryptError attempts to decrypt the passed encrypted error response.
159
        // The onion failure is encrypted in backward manner, starting from the
160
        // node where error have occurred. As a result, in order to decrypt the
161
        // error we need get all shared secret and apply decryption in the
162
        // reverse order.
163
        DecryptError(encryptedData []byte) (*sphinx.DecryptedError, error)
164
}
165

166
// SphinxErrorDecrypter wraps the sphinx data SphinxErrorDecrypter and maps the
167
// returned errors to concrete lnwire.FailureMessage instances.
168
type SphinxErrorDecrypter struct {
169
        OnionErrorDecrypter
170
}
171

172
// DecryptError peels off each layer of onion encryption from the first hop, to
173
// the source of the error. A fully populated lnwire.FailureMessage is returned
174
// along with the source of the error.
175
//
176
// NOTE: Part of the ErrorDecrypter interface.
177
func (s *SphinxErrorDecrypter) DecryptError(reason lnwire.OpaqueReason) (
178
        *ForwardingError, error) {
3✔
179

3✔
180
        failure, err := s.OnionErrorDecrypter.DecryptError(reason)
3✔
181
        if err != nil {
4✔
182
                return nil, err
1✔
183
        }
1✔
184

185
        // Decode the failure. If an error occurs, we leave the failure message
186
        // field nil.
187
        r := bytes.NewReader(failure.Message)
2✔
188
        failureMsg, err := lnwire.DecodeFailure(r, 0)
2✔
189
        if err != nil {
3✔
190
                return NewUnknownForwardingError(failure.SenderIdx), nil
1✔
191
        }
1✔
192

193
        return NewForwardingError(failureMsg, failure.SenderIdx), nil
1✔
194
}
195

196
// A compile time check to ensure ErrorDecrypter implements the Deobfuscator
197
// interface.
198
var _ ErrorDecrypter = (*SphinxErrorDecrypter)(nil)
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