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

lightningnetwork / lnd / 11965896165

22 Nov 2024 03:26AM UTC coverage: 49.579% (-9.4%) from 58.98%
11965896165

Pull #8512

github

Roasbeef
lnwallet/chancloser: add unit tests for new rbf coop close
Pull Request #8512: [3/4] - lnwallet/chancloser: add new protofsm based RBF chan closer

30 of 1081 new or added lines in 8 files covered. (2.78%)

25859 existing lines in 424 files now uncovered.

99910 of 201515 relevant lines covered (49.58%)

2.06 hits per line

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

80.82
/chanbackup/backup.go
1
package chanbackup
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/channeldb"
10
        "github.com/lightningnetwork/lnd/fn"
11
        "github.com/lightningnetwork/lnd/kvdb"
12
)
13

14
// LiveChannelSource is an interface that allows us to query for the set of
15
// live channels. A live channel is one that is open, and has not had a
16
// commitment transaction broadcast.
17
type LiveChannelSource interface {
18
        // FetchAllChannels returns all known live channels.
19
        FetchAllChannels() ([]*channeldb.OpenChannel, error)
20

21
        // FetchChannel attempts to locate a live channel identified by the
22
        // passed chanPoint. Optionally an existing db tx can be supplied.
23
        FetchChannel(tx kvdb.RTx, chanPoint wire.OutPoint) (
24
                *channeldb.OpenChannel, error)
25
}
26

27
// AddressSource is an interface that allows us to query for the set of
28
// addresses a node can be connected to.
29
type AddressSource interface {
30
        // AddrsForNode returns all known addresses for the target node public
31
        // key.
32
        AddrsForNode(nodePub *btcec.PublicKey) ([]net.Addr, error)
33
}
34

35
// assembleChanBackup attempts to assemble a static channel backup for the
36
// passed open channel. The backup includes all information required to restore
37
// the channel, as well as addressing information so we can find the peer and
38
// reconnect to them to initiate the protocol.
39
func assembleChanBackup(addrSource AddressSource,
40
        openChan *channeldb.OpenChannel) (*Single, error) {
4✔
41

4✔
42
        log.Debugf("Crafting backup for ChannelPoint(%v)",
4✔
43
                openChan.FundingOutpoint)
4✔
44

4✔
45
        // First, we'll query the channel source to obtain all the addresses
4✔
46
        // that are associated with the peer for this channel.
4✔
47
        nodeAddrs, err := addrSource.AddrsForNode(openChan.IdentityPub)
4✔
48
        if err != nil {
4✔
UNCOV
49
                return nil, err
×
UNCOV
50
        }
×
51

52
        single := NewSingle(openChan, nodeAddrs)
4✔
53

4✔
54
        return &single, nil
4✔
55
}
56

57
// buildCloseTxInputs generates inputs needed to force close a channel from
58
// an open channel. Anyone having these inputs and the signer, can sign the
59
// force closure transaction. Warning! If the channel state updates, an attempt
60
// to close the channel using this method with outdated CloseTxInputs can result
61
// in loss of funds! This may happen if an outdated channel backup is attempted
62
// to be used to force close the channel.
63
func buildCloseTxInputs(
64
        targetChan *channeldb.OpenChannel) fn.Option[CloseTxInputs] {
4✔
65

4✔
66
        log.Debugf("Crafting CloseTxInputs for ChannelPoint(%v)",
4✔
67
                targetChan.FundingOutpoint)
4✔
68

4✔
69
        localCommit := targetChan.LocalCommitment
4✔
70

4✔
71
        if localCommit.CommitTx == nil {
8✔
72
                log.Infof("CommitTx is nil for ChannelPoint(%v), "+
4✔
73
                        "skipping CloseTxInputs. This is possible when "+
4✔
74
                        "DLP is active.", targetChan.FundingOutpoint)
4✔
75

4✔
76
                return fn.None[CloseTxInputs]()
4✔
77
        }
4✔
78

79
        // We need unsigned force close tx and the counterparty's signature.
80
        inputs := CloseTxInputs{
4✔
81
                CommitTx:  localCommit.CommitTx,
4✔
82
                CommitSig: localCommit.CommitSig,
4✔
83
        }
4✔
84

4✔
85
        // In case of a taproot channel, commit height is needed as well to
4✔
86
        // produce verification nonce for the taproot channel using shachain.
4✔
87
        if targetChan.ChanType.IsTaproot() {
8✔
88
                inputs.CommitHeight = localCommit.CommitHeight
4✔
89
        }
4✔
90

91
        // In case of a custom taproot channel, TapscriptRoot is needed as well.
92
        if targetChan.ChanType.HasTapscriptRoot() {
4✔
UNCOV
93
                inputs.TapscriptRoot = targetChan.TapscriptRoot
×
UNCOV
94
        }
×
95

96
        return fn.Some(inputs)
4✔
97
}
98

99
// FetchBackupForChan attempts to create a plaintext static channel backup for
100
// the target channel identified by its channel point. If we're unable to find
101
// the target channel, then an error will be returned.
102
func FetchBackupForChan(chanPoint wire.OutPoint, chanSource LiveChannelSource,
103
        addrSource AddressSource) (*Single, error) {
4✔
104

4✔
105
        // First, we'll query the channel source to see if the channel is known
4✔
106
        // and open within the database.
4✔
107
        targetChan, err := chanSource.FetchChannel(nil, chanPoint)
4✔
108
        if err != nil {
4✔
UNCOV
109
                // If we can't find the channel, then we return with an error,
×
UNCOV
110
                // as we have nothing to  backup.
×
UNCOV
111
                return nil, fmt.Errorf("unable to find target channel")
×
UNCOV
112
        }
×
113

114
        // Once we have the target channel, we can assemble the backup using
115
        // the source to obtain any extra information that we may need.
116
        staticChanBackup, err := assembleChanBackup(addrSource, targetChan)
4✔
117
        if err != nil {
4✔
UNCOV
118
                return nil, fmt.Errorf("unable to create chan backup: %w", err)
×
UNCOV
119
        }
×
120

121
        return staticChanBackup, nil
4✔
122
}
123

124
// FetchStaticChanBackups will return a plaintext static channel back up for
125
// all known active/open channels within the passed channel source.
126
func FetchStaticChanBackups(chanSource LiveChannelSource,
127
        addrSource AddressSource) ([]Single, error) {
4✔
128

4✔
129
        // First, we'll query the backup source for information concerning all
4✔
130
        // currently open and available channels.
4✔
131
        openChans, err := chanSource.FetchAllChannels()
4✔
132
        if err != nil {
4✔
UNCOV
133
                return nil, err
×
UNCOV
134
        }
×
135

136
        // Now that we have all the channels, we'll use the chanSource to
137
        // obtain any auxiliary information we need to craft a backup for each
138
        // channel.
139
        staticChanBackups := make([]Single, 0, len(openChans))
4✔
140
        for _, openChan := range openChans {
8✔
141
                chanBackup, err := assembleChanBackup(addrSource, openChan)
4✔
142
                if err != nil {
4✔
UNCOV
143
                        return nil, err
×
UNCOV
144
                }
×
145

146
                staticChanBackups = append(staticChanBackups, *chanBackup)
4✔
147
        }
148

149
        return staticChanBackups, nil
4✔
150
}
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