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

lightningnetwork / lnd / 12343072627

15 Dec 2024 11:09PM UTC coverage: 57.504% (-1.1%) from 58.636%
12343072627

Pull #9315

github

yyforyongyu
contractcourt: offer outgoing htlc one block earlier before its expiry

We need to offer the outgoing htlc one block earlier to make sure when
the expiry height hits, the sweeper will not miss sweeping it in the
same block. This also means the outgoing contest resolver now only does
one thing - watch for preimage spend till height expiry-1, which can
easily be moved into the timeout resolver instead in the future.
Pull Request #9315: Implement `blockbeat`

1445 of 2007 new or added lines in 26 files covered. (72.0%)

19246 existing lines in 249 files now uncovered.

102342 of 177975 relevant lines covered (57.5%)

24772.24 hits per line

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

54.93
/contractcourt/breach_resolver.go
1
package contractcourt
2

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

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

11
// breachResolver is a resolver that will handle breached closes. In the
12
// future, this will likely take over the duties the current BreachArbitrator
13
// has.
14
type breachResolver struct {
15
        // subscribed denotes whether or not the breach resolver has subscribed
16
        // to the BreachArbitrator for breach resolution.
17
        subscribed bool
18

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

23
        contractResolverKit
24
}
25

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

2✔
33
        r.initLogger(fmt.Sprintf("%T(%v)", r, r.ChanPoint))
2✔
34

2✔
35
        return r
2✔
36
}
2✔
37

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

44
// Resolve queries the BreachArbitrator to see if the justice transaction has
45
// been broadcast.
46
//
47
// NOTE: Part of the ContractResolver interface.
48
//
49
// TODO(yy): let sweeper handle the breach inputs.
50
func (b *breachResolver) Resolve() (ContractResolver, error) {
2✔
51
        if !b.subscribed {
4✔
52
                complete, err := b.SubscribeBreachComplete(
2✔
53
                        &b.ChanPoint, b.replyChan,
2✔
54
                )
2✔
55
                if err != nil {
2✔
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 {
2✔
NEW
62
                        b.markResolved()
×
63
                        return nil, b.Checkpoint(b)
×
64
                }
×
65

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

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

UNCOV
78
        case <-b.quit:
×
79
        }
80

UNCOV
81
        return nil, errResolverShuttingDown
×
82
}
83

84
// Stop signals the breachResolver to stop.
85
func (b *breachResolver) Stop() {
2✔
86
        b.log.Debugf("stopping...")
2✔
87
        close(b.quit)
2✔
88
}
2✔
89

90
// SupplementState adds additional state to the breachResolver.
UNCOV
91
func (b *breachResolver) SupplementState(_ *channeldb.OpenChannel) {
×
UNCOV
92
}
×
93

94
// Encode encodes the breachResolver to the passed writer.
UNCOV
95
func (b *breachResolver) Encode(w io.Writer) error {
×
NEW
96
        return binary.Write(w, endian, b.IsResolved())
×
UNCOV
97
}
×
98

99
// newBreachResolverFromReader attempts to decode an encoded breachResolver
100
// from the passed Reader instance, returning an active breachResolver.
101
func newBreachResolverFromReader(r io.Reader, resCfg ResolverConfig) (
UNCOV
102
        *breachResolver, error) {
×
UNCOV
103

×
UNCOV
104
        b := &breachResolver{
×
UNCOV
105
                contractResolverKit: *newContractResolverKit(resCfg),
×
UNCOV
106
                replyChan:           make(chan struct{}),
×
UNCOV
107
        }
×
UNCOV
108

×
NEW
109
        var resolved bool
×
NEW
110
        if err := binary.Read(r, endian, &resolved); err != nil {
×
111
                return nil, err
×
112
        }
×
NEW
113
        if resolved {
×
NEW
114
                b.markResolved()
×
NEW
115
        }
×
116

NEW
117
        b.initLogger(fmt.Sprintf("%T(%v)", b, b.ChanPoint))
×
UNCOV
118

×
UNCOV
119
        return b, nil
×
120
}
121

122
// A compile time assertion to ensure breachResolver meets the ContractResolver
123
// interface.
124
var _ ContractResolver = (*breachResolver)(nil)
125

126
// Launch offers the breach outputs to the sweeper - currently it's a NOOP as
127
// the outputs here are not offered to the sweeper.
128
//
129
// NOTE: Part of the ContractResolver interface.
130
//
131
// TODO(yy): implement it once the outputs are offered to the sweeper.
132
func (b *breachResolver) Launch() error {
2✔
133
        if b.isLaunched() {
2✔
NEW
134
                b.log.Tracef("already launched")
×
NEW
135
                return nil
×
NEW
136
        }
×
137

138
        b.log.Debugf("launching resolver...")
2✔
139
        b.markLaunched()
2✔
140

2✔
141
        return nil
2✔
142
}
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