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

lightningnetwork / lnd / 13211764208

08 Feb 2025 03:08AM UTC coverage: 49.288% (-9.5%) from 58.815%
13211764208

Pull #9489

github

calvinrzachman
itest: verify switchrpc server enforces send then track

We prevent the rpc server from allowing onion dispatches for
attempt IDs which have already been tracked by rpc clients.

This helps protect the client from leaking a duplicate onion
attempt. NOTE: This is not the only method for solving this
issue! The issue could be addressed via careful client side
programming which accounts for the uncertainty and async
nature of dispatching onions to a remote process via RPC.
This would require some lnd ChannelRouter changes for how
we intend to use these RPCs though.
Pull Request #9489: multi: add BuildOnion, SendOnion, and TrackOnion RPCs

474 of 990 new or added lines in 11 files covered. (47.88%)

27321 existing lines in 435 files now uncovered.

101192 of 205306 relevant lines covered (49.29%)

1.54 hits per line

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

0.0
/channeldb/migration21/legacy/legacy_codec.go
1
package legacy
2

3
import (
4
        "encoding/binary"
5
        "fmt"
6
        "io"
7

8
        "github.com/btcsuite/btcd/btcec/v2"
9
        "github.com/btcsuite/btcd/btcutil"
10
        "github.com/btcsuite/btcd/chaincfg/chainhash"
11
        "github.com/btcsuite/btcd/wire"
12
        lnwire "github.com/lightningnetwork/lnd/channeldb/migration/lnwire21"
13
        "github.com/lightningnetwork/lnd/channeldb/migration21/common"
14
        "github.com/lightningnetwork/lnd/keychain"
15
)
16

17
var (
18
        // Big endian is the preferred byte order, due to cursor scans over
19
        // integer keys iterating in order.
20
        byteOrder = binary.BigEndian
21
)
22

23
// writeOutpoint writes an outpoint to the passed writer using the minimal
24
// amount of bytes possible.
UNCOV
25
func writeOutpoint(w io.Writer, o *wire.OutPoint) error {
×
UNCOV
26
        if _, err := w.Write(o.Hash[:]); err != nil {
×
27
                return err
×
28
        }
×
UNCOV
29
        if err := binary.Write(w, byteOrder, o.Index); err != nil {
×
30
                return err
×
31
        }
×
32

UNCOV
33
        return nil
×
34
}
35

36
// readOutpoint reads an outpoint from the passed reader that was previously
37
// written using the writeOutpoint struct.
UNCOV
38
func readOutpoint(r io.Reader, o *wire.OutPoint) error {
×
UNCOV
39
        if _, err := io.ReadFull(r, o.Hash[:]); err != nil {
×
40
                return err
×
41
        }
×
UNCOV
42
        if err := binary.Read(r, byteOrder, &o.Index); err != nil {
×
43
                return err
×
44
        }
×
45

UNCOV
46
        return nil
×
47
}
48

49
// UnknownElementType is an error returned when the codec is unable to encode or
50
// decode a particular type.
51
type UnknownElementType struct {
52
        method  string
53
        element interface{}
54
}
55

56
// NewUnknownElementType creates a new UnknownElementType error from the passed
57
// method name and element.
58
func NewUnknownElementType(method string, el interface{}) UnknownElementType {
×
59
        return UnknownElementType{method: method, element: el}
×
60
}
×
61

62
// Error returns the name of the method that encountered the error, as well as
63
// the type that was unsupported.
64
func (e UnknownElementType) Error() string {
×
65
        return fmt.Sprintf("Unknown type in %s: %T", e.method, e.element)
×
66
}
×
67

68
// WriteElement is a one-stop shop to write the big endian representation of
69
// any element which is to be serialized for storage on disk. The passed
70
// io.Writer should be backed by an appropriately sized byte slice, or be able
71
// to dynamically expand to accommodate additional data.
UNCOV
72
func WriteElement(w io.Writer, element interface{}) error {
×
UNCOV
73
        switch e := element.(type) {
×
UNCOV
74
        case keychain.KeyDescriptor:
×
UNCOV
75
                if err := binary.Write(w, byteOrder, e.Family); err != nil {
×
76
                        return err
×
77
                }
×
UNCOV
78
                if err := binary.Write(w, byteOrder, e.Index); err != nil {
×
79
                        return err
×
80
                }
×
81

UNCOV
82
                if e.PubKey != nil {
×
83
                        if err := binary.Write(w, byteOrder, true); err != nil {
×
84
                                return fmt.Errorf("error writing serialized "+
×
85
                                        "element: %w", err)
×
86
                        }
×
87

88
                        return WriteElement(w, e.PubKey)
×
89
                }
90

UNCOV
91
                return binary.Write(w, byteOrder, false)
×
92

UNCOV
93
        case chainhash.Hash:
×
UNCOV
94
                if _, err := w.Write(e[:]); err != nil {
×
95
                        return err
×
96
                }
×
97

UNCOV
98
        case common.ClosureType:
×
UNCOV
99
                if err := binary.Write(w, byteOrder, e); err != nil {
×
100
                        return err
×
101
                }
×
102

UNCOV
103
        case wire.OutPoint:
×
UNCOV
104
                return writeOutpoint(w, &e)
×
105

UNCOV
106
        case lnwire.ShortChannelID:
×
UNCOV
107
                if err := binary.Write(w, byteOrder, e.ToUint64()); err != nil {
×
108
                        return err
×
109
                }
×
110

111
        case lnwire.ChannelID:
×
112
                if _, err := w.Write(e[:]); err != nil {
×
113
                        return err
×
114
                }
×
115

UNCOV
116
        case int64, uint64:
×
UNCOV
117
                if err := binary.Write(w, byteOrder, e); err != nil {
×
118
                        return err
×
119
                }
×
120

UNCOV
121
        case uint32:
×
UNCOV
122
                if err := binary.Write(w, byteOrder, e); err != nil {
×
123
                        return err
×
124
                }
×
125

126
        case int32:
×
127
                if err := binary.Write(w, byteOrder, e); err != nil {
×
128
                        return err
×
129
                }
×
130

UNCOV
131
        case uint16:
×
UNCOV
132
                if err := binary.Write(w, byteOrder, e); err != nil {
×
133
                        return err
×
134
                }
×
135

136
        case uint8:
×
137
                if err := binary.Write(w, byteOrder, e); err != nil {
×
138
                        return err
×
139
                }
×
140

UNCOV
141
        case bool:
×
UNCOV
142
                if err := binary.Write(w, byteOrder, e); err != nil {
×
143
                        return err
×
144
                }
×
145

UNCOV
146
        case btcutil.Amount:
×
UNCOV
147
                if err := binary.Write(w, byteOrder, uint64(e)); err != nil {
×
148
                        return err
×
149
                }
×
150

UNCOV
151
        case lnwire.MilliSatoshi:
×
UNCOV
152
                if err := binary.Write(w, byteOrder, uint64(e)); err != nil {
×
153
                        return err
×
154
                }
×
155

UNCOV
156
        case *btcec.PublicKey:
×
UNCOV
157
                b := e.SerializeCompressed()
×
UNCOV
158
                if _, err := w.Write(b); err != nil {
×
159
                        return err
×
160
                }
×
161

UNCOV
162
        case *wire.MsgTx:
×
UNCOV
163
                return e.Serialize(w)
×
164

165
        case [32]byte:
×
166
                if _, err := w.Write(e[:]); err != nil {
×
167
                        return err
×
168
                }
×
169

UNCOV
170
        case []byte:
×
UNCOV
171
                if err := wire.WriteVarBytes(w, 0, e); err != nil {
×
172
                        return err
×
173
                }
×
174

UNCOV
175
        case lnwire.Message:
×
UNCOV
176
                if _, err := lnwire.WriteMessage(w, e, 0); err != nil {
×
177
                        return err
×
178
                }
×
179

180
        case lnwire.FundingFlag:
×
181
                if err := binary.Write(w, byteOrder, e); err != nil {
×
182
                        return err
×
183
                }
×
184

185
        default:
×
186
                return UnknownElementType{"WriteElement", e}
×
187
        }
188

UNCOV
189
        return nil
×
190
}
191

192
// WriteElements is writes each element in the elements slice to the passed
193
// io.Writer using WriteElement.
UNCOV
194
func WriteElements(w io.Writer, elements ...interface{}) error {
×
UNCOV
195
        for _, element := range elements {
×
UNCOV
196
                err := WriteElement(w, element)
×
UNCOV
197
                if err != nil {
×
198
                        return err
×
199
                }
×
200
        }
UNCOV
201
        return nil
×
202
}
203

204
// ReadElement is a one-stop utility function to deserialize any datastructure
205
// encoded using the serialization format of the database.
UNCOV
206
func ReadElement(r io.Reader, element interface{}) error {
×
UNCOV
207
        switch e := element.(type) {
×
UNCOV
208
        case *chainhash.Hash:
×
UNCOV
209
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
210
                        return err
×
211
                }
×
212

UNCOV
213
        case *wire.OutPoint:
×
UNCOV
214
                return readOutpoint(r, e)
×
215

UNCOV
216
        case *lnwire.ShortChannelID:
×
UNCOV
217
                var a uint64
×
UNCOV
218
                if err := binary.Read(r, byteOrder, &a); err != nil {
×
219
                        return err
×
220
                }
×
UNCOV
221
                *e = lnwire.NewShortChanIDFromInt(a)
×
222

223
        case *lnwire.ChannelID:
×
224
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
225
                        return err
×
226
                }
×
227

UNCOV
228
        case *int64, *uint64:
×
UNCOV
229
                if err := binary.Read(r, byteOrder, e); err != nil {
×
230
                        return err
×
231
                }
×
232

UNCOV
233
        case *uint32:
×
UNCOV
234
                if err := binary.Read(r, byteOrder, e); err != nil {
×
235
                        return err
×
236
                }
×
237

238
        case *int32:
×
239
                if err := binary.Read(r, byteOrder, e); err != nil {
×
240
                        return err
×
241
                }
×
242

UNCOV
243
        case *uint16:
×
UNCOV
244
                if err := binary.Read(r, byteOrder, e); err != nil {
×
245
                        return err
×
246
                }
×
247

248
        case *uint8:
×
249
                if err := binary.Read(r, byteOrder, e); err != nil {
×
250
                        return err
×
251
                }
×
252

UNCOV
253
        case *bool:
×
UNCOV
254
                if err := binary.Read(r, byteOrder, e); err != nil {
×
255
                        return err
×
256
                }
×
257

UNCOV
258
        case *btcutil.Amount:
×
UNCOV
259
                var a uint64
×
UNCOV
260
                if err := binary.Read(r, byteOrder, &a); err != nil {
×
261
                        return err
×
262
                }
×
263

UNCOV
264
                *e = btcutil.Amount(a)
×
265

UNCOV
266
        case *lnwire.MilliSatoshi:
×
UNCOV
267
                var a uint64
×
UNCOV
268
                if err := binary.Read(r, byteOrder, &a); err != nil {
×
269
                        return err
×
270
                }
×
271

UNCOV
272
                *e = lnwire.MilliSatoshi(a)
×
273

UNCOV
274
        case **btcec.PublicKey:
×
UNCOV
275
                var b [btcec.PubKeyBytesLenCompressed]byte
×
UNCOV
276
                if _, err := io.ReadFull(r, b[:]); err != nil {
×
277
                        return err
×
278
                }
×
279

UNCOV
280
                pubKey, err := btcec.ParsePubKey(b[:])
×
UNCOV
281
                if err != nil {
×
282
                        return err
×
283
                }
×
UNCOV
284
                *e = pubKey
×
285

UNCOV
286
        case **wire.MsgTx:
×
UNCOV
287
                tx := wire.NewMsgTx(2)
×
UNCOV
288
                if err := tx.Deserialize(r); err != nil {
×
289
                        return err
×
290
                }
×
291

UNCOV
292
                *e = tx
×
293

294
        case *[32]byte:
×
295
                if _, err := io.ReadFull(r, e[:]); err != nil {
×
296
                        return err
×
297
                }
×
298

UNCOV
299
        case *[]byte:
×
UNCOV
300
                bytes, err := wire.ReadVarBytes(r, 0, 66000, "[]byte")
×
UNCOV
301
                if err != nil {
×
302
                        return err
×
303
                }
×
304

UNCOV
305
                *e = bytes
×
306

UNCOV
307
        case *lnwire.Message:
×
UNCOV
308
                msg, err := lnwire.ReadMessage(r, 0)
×
UNCOV
309
                if err != nil {
×
310
                        return err
×
311
                }
×
312

UNCOV
313
                *e = msg
×
314

315
        case *lnwire.FundingFlag:
×
316
                if err := binary.Read(r, byteOrder, e); err != nil {
×
317
                        return err
×
318
                }
×
319

UNCOV
320
        case *common.ClosureType:
×
UNCOV
321
                if err := binary.Read(r, byteOrder, e); err != nil {
×
322
                        return err
×
323
                }
×
324

UNCOV
325
        case *keychain.KeyDescriptor:
×
UNCOV
326
                if err := binary.Read(r, byteOrder, &e.Family); err != nil {
×
327
                        return err
×
328
                }
×
UNCOV
329
                if err := binary.Read(r, byteOrder, &e.Index); err != nil {
×
330
                        return err
×
331
                }
×
332

UNCOV
333
                var hasPubKey bool
×
UNCOV
334
                if err := binary.Read(r, byteOrder, &hasPubKey); err != nil {
×
335
                        return err
×
336
                }
×
337

UNCOV
338
                if hasPubKey {
×
339
                        return ReadElement(r, &e.PubKey)
×
340
                }
×
341

342
        default:
×
343
                return UnknownElementType{"ReadElement", e}
×
344
        }
345

UNCOV
346
        return nil
×
347
}
348

349
// ReadElements deserializes a variable number of elements into the passed
350
// io.Reader, with each element being deserialized according to the ReadElement
351
// function.
UNCOV
352
func ReadElements(r io.Reader, elements ...interface{}) error {
×
UNCOV
353
        for _, element := range elements {
×
UNCOV
354
                err := ReadElement(r, element)
×
UNCOV
355
                if err != nil {
×
356
                        return err
×
357
                }
×
358
        }
UNCOV
359
        return nil
×
360
}
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