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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

0.0
/channel_notifier.go
1
package lnd
2

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

7
        "github.com/btcsuite/btcd/btcec/v2"
8
        "github.com/btcsuite/btcd/wire"
9
        "github.com/lightningnetwork/lnd/chanbackup"
10
        "github.com/lightningnetwork/lnd/channeldb"
11
        "github.com/lightningnetwork/lnd/channelnotifier"
12
)
13

14
// addrSource is an interface that allow us to get the addresses for a target
15
// node. We'll need this in order to be able to properly proxy the
16
// notifications to create SCBs.
17
type addrSource interface {
18
        // AddrsForNode returns all known addresses for the target node public
19
        // key.
20
        AddrsForNode(nodePub *btcec.PublicKey) ([]net.Addr, error)
21
}
22

23
// channelNotifier is an implementation of the chanbackup.ChannelNotifier
24
// interface using the existing channelnotifier.ChannelNotifier struct. This
25
// implementation allows us to satisfy all the dependencies of the
26
// chanbackup.SubSwapper struct.
27
type channelNotifier struct {
28
        // chanNotifier is the based channel notifier that we'll proxy requests
29
        // from.
30
        chanNotifier *channelnotifier.ChannelNotifier
31

32
        // addrs is an implementation of the addrSource interface that allows
33
        // us to get the latest set of addresses for a given node. We'll need
34
        // this to be able to create an SCB for new channels.
35
        addrs addrSource
36
}
37

38
// SubscribeChans requests a new channel subscription relative to the initial
39
// set of known channels. We use the knownChans as a synchronization point to
40
// ensure that the chanbackup.SubSwapper does not miss any channel open or
41
// close events in the period between when it's created, and when it requests
42
// the channel subscription.
43
//
44
// NOTE: This is part of the chanbackup.ChannelNotifier interface.
45
func (c *channelNotifier) SubscribeChans(startingChans map[wire.OutPoint]struct{}) (
UNCOV
46
        *chanbackup.ChannelSubscription, error) {
×
UNCOV
47

×
UNCOV
48
        ltndLog.Infof("Channel backup proxy channel notifier starting")
×
UNCOV
49

×
UNCOV
50
        // TODO(roasbeef): read existing set of chans and diff
×
UNCOV
51

×
UNCOV
52
        quit := make(chan struct{})
×
UNCOV
53
        chanUpdates := make(chan chanbackup.ChannelEvent, 1)
×
UNCOV
54

×
UNCOV
55
        // sendChanOpenUpdate is a closure that sends a ChannelEvent to the
×
UNCOV
56
        // chanUpdates channel to inform subscribers about new pending or
×
UNCOV
57
        // confirmed channels.
×
UNCOV
58
        sendChanOpenUpdate := func(newOrPendingChan *channeldb.OpenChannel) {
×
UNCOV
59
                nodeAddrs, err := c.addrs.AddrsForNode(
×
UNCOV
60
                        newOrPendingChan.IdentityPub,
×
UNCOV
61
                )
×
UNCOV
62
                if err != nil {
×
63
                        pub := newOrPendingChan.IdentityPub
×
64
                        ltndLog.Errorf("unable to fetch addrs for %x: %v",
×
65
                                pub.SerializeCompressed(), err)
×
66
                }
×
67

UNCOV
68
                chanEvent := chanbackup.ChannelEvent{
×
UNCOV
69
                        NewChans: []chanbackup.ChannelWithAddrs{
×
UNCOV
70
                                {
×
UNCOV
71
                                        OpenChannel: newOrPendingChan,
×
UNCOV
72
                                        Addrs:       nodeAddrs,
×
UNCOV
73
                                },
×
UNCOV
74
                        },
×
UNCOV
75
                }
×
UNCOV
76

×
UNCOV
77
                select {
×
UNCOV
78
                case chanUpdates <- chanEvent:
×
79
                case <-quit:
×
80
                        return
×
81
                }
82
        }
83

84
        // In order to adhere to the interface, we'll proxy the events from the
85
        // channel notifier to the sub-swapper in a format it understands.
UNCOV
86
        go func() {
×
UNCOV
87
                // First, we'll subscribe to the primary channel notifier so we can
×
UNCOV
88
                // obtain events for new opened/closed channels.
×
UNCOV
89
                chanSubscription, err := c.chanNotifier.SubscribeChannelEvents()
×
UNCOV
90
                if err != nil {
×
91
                        panic(fmt.Sprintf("unable to subscribe to chans: %v",
×
92
                                err))
×
93
                }
94

UNCOV
95
                defer chanSubscription.Cancel()
×
UNCOV
96

×
UNCOV
97
                for {
×
UNCOV
98
                        select {
×
99

100
                        // A new event has been sent by the chanNotifier, we'll
101
                        // filter out the events we actually care about and
102
                        // send them to the sub-swapper.
UNCOV
103
                        case e := <-chanSubscription.Updates():
×
UNCOV
104
                                // TODO(roasbeef): batch dispatch ntnfs
×
UNCOV
105

×
UNCOV
106
                                switch event := e.(type) {
×
107
                                // A new channel has been opened and is still
108
                                // pending. We can still create a backup, even
109
                                // if the final channel ID is not yet available.
UNCOV
110
                                case channelnotifier.PendingOpenChannelEvent:
×
UNCOV
111
                                        pendingChan := event.PendingChannel
×
UNCOV
112
                                        sendChanOpenUpdate(pendingChan)
×
113

114
                                // A new channel has been confirmed, we'll
115
                                // obtain the node address, then send to the
116
                                // sub-swapper.
UNCOV
117
                                case channelnotifier.OpenChannelEvent:
×
UNCOV
118
                                        sendChanOpenUpdate(event.Channel)
×
119

120
                                // An existing channel has been closed, we'll
121
                                // send only the chanPoint of the closed
122
                                // channel to the sub-swapper.
UNCOV
123
                                case channelnotifier.ClosedChannelEvent:
×
UNCOV
124
                                        chanPoint := event.CloseSummary.ChanPoint
×
UNCOV
125
                                        closeType := event.CloseSummary.CloseType
×
UNCOV
126

×
UNCOV
127
                                        // Because we see the contract as closed
×
UNCOV
128
                                        // once our local force close TX
×
UNCOV
129
                                        // confirms, the channel arbitrator
×
UNCOV
130
                                        // already fires on this event. But
×
UNCOV
131
                                        // because our funds can be in limbo for
×
UNCOV
132
                                        // up to 2 weeks worst case we don't
×
UNCOV
133
                                        // want to remove the crucial info we
×
UNCOV
134
                                        // need for sweeping that time locked
×
UNCOV
135
                                        // output before we've actually done so.
×
UNCOV
136
                                        if closeType == channeldb.LocalForceClose {
×
UNCOV
137
                                                ltndLog.Debugf("Channel %v "+
×
UNCOV
138
                                                        "was force closed by "+
×
UNCOV
139
                                                        "us, not removing "+
×
UNCOV
140
                                                        "from channel backup "+
×
UNCOV
141
                                                        "until fully resolved",
×
UNCOV
142
                                                        chanPoint)
×
UNCOV
143

×
UNCOV
144
                                                continue
×
145
                                        }
146

UNCOV
147
                                        chanEvent := chanbackup.ChannelEvent{
×
UNCOV
148
                                                ClosedChans: []wire.OutPoint{
×
UNCOV
149
                                                        chanPoint,
×
UNCOV
150
                                                },
×
UNCOV
151
                                        }
×
UNCOV
152

×
UNCOV
153
                                        select {
×
UNCOV
154
                                        case chanUpdates <- chanEvent:
×
155
                                        case <-quit:
×
156
                                                return
×
157
                                        }
158

159
                                // A channel was fully resolved on chain. This
160
                                // should only really interest us if it was a
161
                                // locally force closed channel where we didn't
162
                                // remove the channel already when the close
163
                                // event was fired.
UNCOV
164
                                case channelnotifier.FullyResolvedChannelEvent:
×
UNCOV
165
                                        chanEvent := chanbackup.ChannelEvent{
×
UNCOV
166
                                                ClosedChans: []wire.OutPoint{
×
UNCOV
167
                                                        *event.ChannelPoint,
×
UNCOV
168
                                                },
×
UNCOV
169
                                        }
×
UNCOV
170

×
UNCOV
171
                                        select {
×
UNCOV
172
                                        case chanUpdates <- chanEvent:
×
173
                                        case <-quit:
×
174
                                                return
×
175
                                        }
176
                                }
177

178
                        // The cancel method has been called, signalling us to
179
                        // exit
UNCOV
180
                        case <-quit:
×
UNCOV
181
                                return
×
182
                        }
183
                }
184
        }()
185

UNCOV
186
        return &chanbackup.ChannelSubscription{
×
UNCOV
187
                ChanUpdates: chanUpdates,
×
UNCOV
188
                Cancel: func() {
×
UNCOV
189
                        close(quit)
×
UNCOV
190
                },
×
191
        }, nil
192
}
193

194
// A compile-time constraint to ensure channelNotifier implements
195
// chanbackup.ChannelNotifier.
196
var _ chanbackup.ChannelNotifier = (*channelNotifier)(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