• 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
/lntest/wait/wait.go
1
package wait
2

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

8
// PollInterval is a constant specifying a 200 ms interval.
9
const PollInterval = 200 * time.Millisecond
10

11
// Predicate is a helper test function that will wait for a timeout period of
12
// time until the passed predicate returns true. This function is helpful as
13
// timing doesn't always line up well when running integration tests with
14
// several running lnd nodes. This function gives callers a way to assert that
15
// some property is upheld within a particular time frame.
16
//
17
// TODO(yy): build a counter here so we know how many times we've tried the
18
// `pred`.
UNCOV
19
func Predicate(pred func() bool, timeout time.Duration) error {
×
UNCOV
20
        exitTimer := time.After(timeout)
×
UNCOV
21
        result := make(chan bool, 1)
×
UNCOV
22

×
UNCOV
23
        for {
×
UNCOV
24
                <-time.After(PollInterval)
×
UNCOV
25

×
UNCOV
26
                go func() {
×
UNCOV
27
                        result <- pred()
×
UNCOV
28
                }()
×
29

30
                // Each time we call the pred(), we expect a result to be
31
                // returned otherwise it will timeout.
UNCOV
32
                select {
×
33
                case <-exitTimer:
×
34
                        return fmt.Errorf("predicate not satisfied after " +
×
35
                                "time out")
×
36

UNCOV
37
                case succeed := <-result:
×
UNCOV
38
                        if succeed {
×
UNCOV
39
                                return nil
×
UNCOV
40
                        }
×
41
                }
42
        }
43
}
44

45
// NoError is a wrapper around Predicate that waits for the passed method f to
46
// execute without error, and returns the last error encountered if this doesn't
47
// happen within the timeout.
UNCOV
48
func NoError(f func() error, timeout time.Duration) error {
×
UNCOV
49
        var predErr error
×
UNCOV
50
        pred := func() bool {
×
UNCOV
51
                if err := f(); err != nil {
×
UNCOV
52
                        predErr = err
×
UNCOV
53
                        return false
×
UNCOV
54
                }
×
UNCOV
55
                return true
×
56
        }
57

58
        // If f() doesn't succeed within the timeout, return the last
59
        // encountered error.
UNCOV
60
        if err := Predicate(pred, timeout); err != nil {
×
61
                // Handle the case where the passed in method, f, hangs for the
×
62
                // full timeout
×
63
                if predErr == nil {
×
64
                        return fmt.Errorf("method did not return within the " +
×
65
                                "timeout")
×
66
                }
×
67

68
                return predErr
×
69
        }
70

UNCOV
71
        return nil
×
72
}
73

74
// Invariant is a helper test function that will wait for a timeout period of
75
// time, verifying that a statement remains true for the entire duration.  This
76
// function is helpful as timing doesn't always line up well when running
77
// integration tests with several running lnd nodes. This function gives callers
78
// a way to assert that some property is maintained over a particular time
79
// frame.
80
func Invariant(statement func() bool, timeout time.Duration) error {
×
81
        const pollInterval = 20 * time.Millisecond
×
82

×
83
        exitTimer := time.After(timeout)
×
84
        for {
×
85
                <-time.After(pollInterval)
×
86

×
87
                // Fail if the invariant is broken while polling.
×
88
                if !statement() {
×
89
                        return fmt.Errorf("invariant broken before time out")
×
90
                }
×
91

92
                select {
×
93
                case <-exitTimer:
×
94
                        return nil
×
95
                default:
×
96
                }
97
        }
98
}
99

100
// InvariantNoError is a wrapper around Invariant that waits out the duration
101
// specified by timeout. It fails if the predicate ever returns an error during
102
// that time.
103
func InvariantNoError(f func() error, timeout time.Duration) error {
×
104
        var predErr error
×
105
        pred := func() bool {
×
106
                if err := f(); err != nil {
×
107
                        predErr = err
×
108
                        return false
×
109
                }
×
110
                return true
×
111
        }
112

113
        if err := Invariant(pred, timeout); err != nil {
×
114
                return predErr
×
115
        }
×
116

117
        return nil
×
118
}
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