• 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

86.96
/watchtower/wtclient/stats.go
1
package wtclient
2

3
import (
4
        "fmt"
5
        "sync"
6
)
7

8
// ClientStats is a collection of in-memory statistics of the actions the client
9
// has performed since its creation.
10
type ClientStats struct {
11
        // NumTasksPending is the total number of backups that are pending to
12
        // be acknowledged by all active and exhausted watchtower sessions.
13
        NumTasksPending int
14

15
        // NumTasksAccepted is the total number of backups made to all active
16
        // and exhausted watchtower sessions.
17
        NumTasksAccepted int
18

19
        // NumTasksIneligible is the total number of backups that all active and
20
        // exhausted watchtower sessions have failed to acknowledge.
21
        NumTasksIneligible int
22

23
        // NumSessionsAcquired is the total number of new sessions made to
24
        // watchtowers.
25
        NumSessionsAcquired int
26

27
        // NumSessionsExhausted is the total number of watchtower sessions that
28
        // have been exhausted.
29
        NumSessionsExhausted int
30
}
31

32
// clientStats wraps ClientStats with a mutex so that it's members can be
33
// accessed in a thread safe manner.
34
type clientStats struct {
35
        mu sync.Mutex
36

37
        ClientStats
38
}
39

40
// taskReceived increments the number of backup requests the client has received
41
// from active channels.
42
func (s *clientStats) taskReceived() {
3✔
43
        s.mu.Lock()
3✔
44
        defer s.mu.Unlock()
3✔
45

3✔
46
        s.NumTasksPending++
3✔
47
}
3✔
48

49
// taskAccepted increments the number of tasks that have been assigned to active
50
// session queues, and are awaiting upload to a tower.
51
func (s *clientStats) taskAccepted() {
3✔
52
        s.mu.Lock()
3✔
53
        defer s.mu.Unlock()
3✔
54

3✔
55
        s.NumTasksAccepted++
3✔
56
        s.NumTasksPending--
3✔
57
}
3✔
58

59
// getStatsCopy returns a copy of the ClientStats.
60
func (s *clientStats) getStatsCopy() ClientStats {
3✔
61
        s.mu.Lock()
3✔
62
        defer s.mu.Unlock()
3✔
63

3✔
64
        return s.ClientStats
3✔
65
}
3✔
66

67
// taskIneligible increments the number of tasks that were unable to satisfy the
68
// active session queue's policy. These can potentially be retried later, but
69
// typically this means that the balance created dust outputs, so it may not be
70
// worth backing up at all.
UNCOV
71
func (s *clientStats) taskIneligible() {
×
UNCOV
72
        s.mu.Lock()
×
UNCOV
73
        defer s.mu.Unlock()
×
UNCOV
74

×
UNCOV
75
        s.NumTasksIneligible++
×
UNCOV
76
}
×
77

78
// sessionAcquired increments the number of sessions that have been successfully
79
// negotiated by the client during this execution.
80
func (s *clientStats) sessionAcquired() {
3✔
81
        s.mu.Lock()
3✔
82
        defer s.mu.Unlock()
3✔
83

3✔
84
        s.NumSessionsAcquired++
3✔
85
}
3✔
86

87
// sessionExhausted increments the number of session that have become full as a
88
// result of accepting backup tasks.
89
func (s *clientStats) sessionExhausted() {
3✔
90
        s.mu.Lock()
3✔
91
        defer s.mu.Unlock()
3✔
92

3✔
93
        s.NumSessionsExhausted++
3✔
94
}
3✔
95

96
// String returns a human-readable summary of the client's metrics.
97
func (s *clientStats) String() string {
3✔
98
        s.mu.Lock()
3✔
99
        defer s.mu.Unlock()
3✔
100

3✔
101
        return fmt.Sprintf("tasks(received=%d accepted=%d ineligible=%d) "+
3✔
102
                "sessions(acquired=%d exhausted=%d)", s.NumTasksPending,
3✔
103
                s.NumTasksAccepted, s.NumTasksIneligible, s.NumSessionsAcquired,
3✔
104
                s.NumSessionsExhausted)
3✔
105
}
3✔
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