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

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

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

0.0
/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.
UNCOV
33
func MigrateBalancesToTlvRecords(tx kvdb.RwTx) error {
×
UNCOV
34
        log.Infof("Migrating local and remote balances into tlv records...")
×
UNCOV
35

×
UNCOV
36
        openChanBucket := tx.ReadWriteBucket(openChannelBucket)
×
UNCOV
37

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

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

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

UNCOV
56
        return err
×
57
}
58

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

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

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

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

UNCOV
82
                channels = append(channels, c)
×
UNCOV
83

×
UNCOV
84
                return nil
×
85
        }
86

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

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

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

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

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

UNCOV
125
        return channels, nil
×
126
}
127

128
// migrateBalances creates a new tlv stream which adds two more records to hold
129
// the balances info.
UNCOV
130
func migrateBalances(tx kvdb.RwTx, c *OpenChannel) error {
×
UNCOV
131
        // Get the bucket.
×
UNCOV
132
        chanBucket, err := mig25.FetchChanBucket(tx, &c.OpenChannel)
×
UNCOV
133
        if err != nil {
×
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.
UNCOV
141
        if err := PutChanInfo(chanBucket, c, false); err != nil {
×
142
                return fmt.Errorf("unable to put chan info: %w", err)
×
143
        }
×
144

UNCOV
145
        return nil
×
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