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

lightningnetwork / lnd / 14193549836

01 Apr 2025 10:40AM UTC coverage: 69.046% (+0.007%) from 69.039%
14193549836

Pull #9665

github

web-flow
Merge e8825f209 into b01f4e514
Pull Request #9665: kvdb: bump etcd libs to v3.5.12

133439 of 193262 relevant lines covered (69.05%)

22119.45 hits per line

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

66.67
/channeldb/migration26/migration.go
1
package migration26
2

3
import (
4
        "fmt"
5

6
        mig25 "github.com/lightningnetwork/lnd/channeldb/migration25"
7
        "github.com/lightningnetwork/lnd/kvdb"
8
)
9

10
var (
11
        // openChanBucket stores all the currently open channels. This bucket
12
        // has a second, nested bucket which is keyed by a node's ID. Within
13
        // that node ID bucket, all attributes required to track, update, and
14
        // close a channel are stored.
15
        openChannelBucket = []byte("open-chan-bucket")
16

17
        // ErrNoChanDBExists is returned when a channel bucket hasn't been
18
        // created.
19
        ErrNoChanDBExists = fmt.Errorf("channel db has not yet been created")
20

21
        // ErrNoActiveChannels  is returned when there is no active (open)
22
        // channels within the database.
23
        ErrNoActiveChannels = fmt.Errorf("no active channels exist")
24

25
        // ErrChannelNotFound is returned when we attempt to locate a channel
26
        // for a specific chain, but it is not found.
27
        ErrChannelNotFound = fmt.Errorf("channel not found")
28
)
29

30
// MigrateBalancesToTlvRecords migrates the balance fields into tlv records. It
31
// does so by first reading a list of open channels, then rewriting the channel
32
// info with the updated tlv stream.
33
func MigrateBalancesToTlvRecords(tx kvdb.RwTx) error {
4✔
34
        log.Infof("Migrating local and remote balances into tlv records...")
4✔
35

4✔
36
        openChanBucket := tx.ReadWriteBucket(openChannelBucket)
4✔
37

4✔
38
        // If no bucket is found, we can exit early.
4✔
39
        if openChanBucket == nil {
4✔
40
                return nil
×
41
        }
×
42

43
        // Read a list of open channels.
44
        channels, err := findOpenChannels(openChanBucket)
4✔
45
        if err != nil {
4✔
46
                return err
×
47
        }
×
48

49
        // Migrate the balances.
50
        for _, c := range channels {
8✔
51
                if err := migrateBalances(tx, c); err != nil {
4✔
52
                        return err
×
53
                }
×
54
        }
55

56
        return err
4✔
57
}
58

59
// findOpenChannels finds all open channels.
60
func findOpenChannels(openChanBucket kvdb.RBucket) ([]*OpenChannel, error) {
4✔
61
        channels := []*OpenChannel{}
4✔
62

4✔
63
        // readChannel is a helper closure that reads the channel info from the
4✔
64
        // channel bucket.
4✔
65
        readChannel := func(chainBucket kvdb.RBucket, cp []byte) error {
8✔
66
                c := &OpenChannel{}
4✔
67

4✔
68
                // Read the sub-bucket level 3.
4✔
69
                chanBucket := chainBucket.NestedReadBucket(
4✔
70
                        cp,
4✔
71
                )
4✔
72
                if chanBucket == nil {
4✔
73
                        log.Errorf("unable to read bucket for chanPoint=%x", cp)
×
74
                        return nil
×
75
                }
×
76

77
                // Get the old channel info.
78
                if err := FetchChanInfo(chanBucket, c, true); err != nil {
4✔
79
                        return fmt.Errorf("unable to fetch chan info: %w", err)
×
80
                }
×
81

82
                channels = append(channels, c)
4✔
83

4✔
84
                return nil
4✔
85
        }
86

87
        // Iterate the root bucket.
88
        err := openChanBucket.ForEach(func(nodePub, v []byte) error {
8✔
89
                // Ensure that this is a key the same size as a pubkey, and
4✔
90
                // also that it leads directly to a bucket.
4✔
91
                if len(nodePub) != 33 || v != nil {
4✔
92
                        return nil
×
93
                }
×
94

95
                // Read the sub-bucket level 1.
96
                nodeChanBucket := openChanBucket.NestedReadBucket(nodePub)
4✔
97
                if nodeChanBucket == nil {
4✔
98
                        log.Errorf("no bucket for node %x", nodePub)
×
99
                        return nil
×
100
                }
×
101

102
                // Iterate the bucket.
103
                return nodeChanBucket.ForEach(func(chainHash, _ []byte) error {
8✔
104
                        // Read the sub-bucket level 2.
4✔
105
                        chainBucket := nodeChanBucket.NestedReadBucket(
4✔
106
                                chainHash,
4✔
107
                        )
4✔
108
                        if chainBucket == nil {
4✔
109
                                log.Errorf("unable to read bucket for chain=%x",
×
110
                                        chainHash)
×
111
                                return nil
×
112
                        }
×
113

114
                        // Iterate the bucket.
115
                        return chainBucket.ForEach(func(cp, _ []byte) error {
8✔
116
                                return readChannel(chainBucket, cp)
4✔
117
                        })
4✔
118
                })
119
        })
120

121
        if err != nil {
4✔
122
                return nil, err
×
123
        }
×
124

125
        return channels, nil
4✔
126
}
127

128
// migrateBalances creates a new tlv stream which adds two more records to hold
129
// the balances info.
130
func migrateBalances(tx kvdb.RwTx, c *OpenChannel) error {
4✔
131
        // Get the bucket.
4✔
132
        chanBucket, err := mig25.FetchChanBucket(tx, &c.OpenChannel)
4✔
133
        if err != nil {
4✔
134
                return err
×
135
        }
×
136

137
        // Update the channel info. There isn't much to do here as the
138
        // `PutChanInfo` will read the values from `c.InitialLocalBalance` and
139
        // `c.InitialRemoteBalance` then create the new tlv stream as
140
        // requested.
141
        if err := PutChanInfo(chanBucket, c, false); err != nil {
4✔
142
                return fmt.Errorf("unable to put chan info: %w", err)
×
143
        }
×
144

145
        return nil
4✔
146
}
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