• 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

84.44
/htlcswitch/held_htlc_set.go
1
package htlcswitch
2

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

7
        "github.com/lightningnetwork/lnd/graph/db/models"
8
)
9

10
// heldHtlcSet keeps track of outstanding intercepted forwards. It exposes
11
// several methods to manipulate the underlying map structure in a consistent
12
// way.
13
type heldHtlcSet struct {
14
        set map[models.CircuitKey]InterceptedForward
15
}
16

17
func newHeldHtlcSet() *heldHtlcSet {
3✔
18
        return &heldHtlcSet{
3✔
19
                set: make(map[models.CircuitKey]InterceptedForward),
3✔
20
        }
3✔
21
}
3✔
22

23
// forEach iterates over all held forwards and calls the given callback for each
24
// of them.
25
func (h *heldHtlcSet) forEach(cb func(InterceptedForward)) {
3✔
26
        for _, fwd := range h.set {
6✔
27
                cb(fwd)
3✔
28
        }
3✔
29
}
30

31
// popAll calls the callback for each forward and removes them from the set.
32
func (h *heldHtlcSet) popAll(cb func(InterceptedForward)) {
3✔
33
        for _, fwd := range h.set {
6✔
34
                cb(fwd)
3✔
35
        }
3✔
36

37
        h.set = make(map[models.CircuitKey]InterceptedForward)
3✔
38
}
39

40
// popAutoFails calls the callback for each forward that has an auto-fail height
41
// equal or less then the specified pop height and removes them from the set.
42
func (h *heldHtlcSet) popAutoFails(height uint32, cb func(InterceptedForward)) {
3✔
43
        for key, fwd := range h.set {
6✔
44
                if uint32(fwd.Packet().AutoFailHeight) > height {
6✔
45
                        continue
3✔
46
                }
47

UNCOV
48
                cb(fwd)
×
UNCOV
49

×
UNCOV
50
                delete(h.set, key)
×
51
        }
52
}
53

54
// pop returns the specified forward and removes it from the set.
55
func (h *heldHtlcSet) pop(key models.CircuitKey) (InterceptedForward, error) {
3✔
56
        intercepted, ok := h.set[key]
3✔
57
        if !ok {
6✔
58
                return nil, fmt.Errorf("fwd %v not found", key)
3✔
59
        }
3✔
60

61
        delete(h.set, key)
3✔
62

3✔
63
        return intercepted, nil
3✔
64
}
65

66
// exists tests whether the specified forward is part of the set.
67
func (h *heldHtlcSet) exists(key models.CircuitKey) bool {
3✔
68
        _, ok := h.set[key]
3✔
69

3✔
70
        return ok
3✔
71
}
3✔
72

73
// push adds the specified forward to the set. An error is returned if the
74
// forward exists already.
75
func (h *heldHtlcSet) push(key models.CircuitKey,
76
        fwd InterceptedForward) error {
3✔
77

3✔
78
        if fwd == nil {
3✔
UNCOV
79
                return errors.New("nil fwd pushed")
×
UNCOV
80
        }
×
81

82
        if h.exists(key) {
3✔
UNCOV
83
                return errors.New("htlc already exists in set")
×
UNCOV
84
        }
×
85

86
        h.set[key] = fwd
3✔
87

3✔
88
        return nil
3✔
89
}
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