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

lightningnetwork / lnd / 12280337084

11 Dec 2024 04:09PM UTC coverage: 49.495% (-0.05%) from 49.54%
12280337084

Pull #9343

github

ellemouton
fn: rework the ContextGuard and add tests

In this commit, the ContextGuard struct is re-worked such that the
context that its new main WithCtx method provides is cancelled in sync
with a parent context being cancelled or with it's quit channel being
cancelled. Tests are added to assert the behaviour. In order for the
close of the quit channel to be consistent with the cancelling of the
derived context, the quit channel _must_ be contained internal to the
ContextGuard so that callers are only able to close the channel via the
exposed Quit method which will then take care to first cancel any
derived context that depend on the quit channel before returning.
Pull Request #9343: fn: expand the ContextGuard and add tests

100285 of 202617 relevant lines covered (49.49%)

1.54 hits per line

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

88.33
/contractcourt/breach_resolver.go
1
package contractcourt
2

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

7
        "github.com/lightningnetwork/lnd/channeldb"
8
)
9

10
// breachResolver is a resolver that will handle breached closes. In the
11
// future, this will likely take over the duties the current BreachArbitrator
12
// has.
13
type breachResolver struct {
14
        // resolved reflects if the contract has been fully resolved or not.
15
        resolved bool
16

17
        // subscribed denotes whether or not the breach resolver has subscribed
18
        // to the BreachArbitrator for breach resolution.
19
        subscribed bool
20

21
        // replyChan is closed when the breach arbiter has completed serving
22
        // justice.
23
        replyChan chan struct{}
24

25
        contractResolverKit
26
}
27

28
// newBreachResolver instantiates a new breach resolver.
29
func newBreachResolver(resCfg ResolverConfig) *breachResolver {
3✔
30
        r := &breachResolver{
3✔
31
                contractResolverKit: *newContractResolverKit(resCfg),
3✔
32
                replyChan:           make(chan struct{}),
3✔
33
        }
3✔
34

3✔
35
        r.initLogger(r)
3✔
36

3✔
37
        return r
3✔
38
}
3✔
39

40
// ResolverKey returns the unique identifier for this resolver.
41
func (b *breachResolver) ResolverKey() []byte {
3✔
42
        key := newResolverID(b.ChanPoint)
3✔
43
        return key[:]
3✔
44
}
3✔
45

46
// Resolve queries the BreachArbitrator to see if the justice transaction has
47
// been broadcast.
48
//
49
// TODO(yy): let sweeper handle the breach inputs.
50
func (b *breachResolver) Resolve(_ bool) (ContractResolver, error) {
3✔
51
        if !b.subscribed {
6✔
52
                complete, err := b.SubscribeBreachComplete(
3✔
53
                        &b.ChanPoint, b.replyChan,
3✔
54
                )
3✔
55
                if err != nil {
3✔
56
                        return nil, err
×
57
                }
×
58

59
                // If the breach resolution process is already complete, then
60
                // we can cleanup and checkpoint the resolved state.
61
                if complete {
3✔
62
                        b.resolved = true
×
63
                        return nil, b.Checkpoint(b)
×
64
                }
×
65

66
                // Prevent duplicate subscriptions.
67
                b.subscribed = true
3✔
68
        }
69

70
        select {
3✔
71
        case <-b.replyChan:
3✔
72
                // The replyChan has been closed, signalling that the breach
3✔
73
                // has been fully resolved. Checkpoint the resolved state and
3✔
74
                // exit.
3✔
75
                b.resolved = true
3✔
76
                return nil, b.Checkpoint(b)
3✔
77
        case <-b.quit:
3✔
78
        }
79

80
        return nil, errResolverShuttingDown
3✔
81
}
82

83
// Stop signals the breachResolver to stop.
84
func (b *breachResolver) Stop() {
3✔
85
        close(b.quit)
3✔
86
}
3✔
87

88
// IsResolved returns true if the breachResolver is fully resolved and cleanup
89
// can occur.
90
func (b *breachResolver) IsResolved() bool {
3✔
91
        return b.resolved
3✔
92
}
3✔
93

94
// SupplementState adds additional state to the breachResolver.
95
func (b *breachResolver) SupplementState(_ *channeldb.OpenChannel) {
3✔
96
}
3✔
97

98
// Encode encodes the breachResolver to the passed writer.
99
func (b *breachResolver) Encode(w io.Writer) error {
3✔
100
        return binary.Write(w, endian, b.resolved)
3✔
101
}
3✔
102

103
// newBreachResolverFromReader attempts to decode an encoded breachResolver
104
// from the passed Reader instance, returning an active breachResolver.
105
func newBreachResolverFromReader(r io.Reader, resCfg ResolverConfig) (
106
        *breachResolver, error) {
3✔
107

3✔
108
        b := &breachResolver{
3✔
109
                contractResolverKit: *newContractResolverKit(resCfg),
3✔
110
                replyChan:           make(chan struct{}),
3✔
111
        }
3✔
112

3✔
113
        if err := binary.Read(r, endian, &b.resolved); err != nil {
3✔
114
                return nil, err
×
115
        }
×
116

117
        b.initLogger(b)
3✔
118

3✔
119
        return b, nil
3✔
120
}
121

122
// A compile time assertion to ensure breachResolver meets the ContractResolver
123
// interface.
124
var _ ContractResolver = (*breachResolver)(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