• 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
/watchtower/wtdb/migration6/client_db.go
1
package migration6
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "errors"
7

8
        "github.com/lightningnetwork/lnd/kvdb"
9
        "github.com/lightningnetwork/lnd/tlv"
10
)
11

12
var (
13
        // cSessionBkt is a top-level bucket storing:
14
        //   session-id => cSessionBody -> encoded ClientSessionBody
15
        //                 => cSessionDBID -> db-assigned-id
16
        //              => cSessionCommits => seqnum -> encoded CommittedUpdate
17
        //              => cSessionAcks => seqnum -> encoded BackupID
18
        cSessionBkt = []byte("client-session-bucket")
19

20
        // cSessionDBID is a key used in the cSessionBkt to store the
21
        // db-assigned-id of a session.
22
        cSessionDBID = []byte("client-session-db-id")
23

24
        // cSessionIDIndexBkt is a top-level bucket storing:
25
        //    db-assigned-id -> session-id
26
        cSessionIDIndexBkt = []byte("client-session-id-index")
27

28
        // cSessionBody is a sub-bucket of cSessionBkt storing only the body of
29
        // the ClientSession.
30
        cSessionBody = []byte("client-session-body")
31

32
        // ErrUninitializedDB signals that top-level buckets for the database
33
        // have not been initialized.
34
        ErrUninitializedDB = errors.New("db not initialized")
35

36
        // ErrCorruptClientSession signals that the client session's on-disk
37
        // structure deviates from what is expected.
38
        ErrCorruptClientSession = errors.New("client session corrupted")
39

40
        byteOrder = binary.BigEndian
41
)
42

43
// MigrateSessionIDIndex adds a new session ID index to the tower client db.
44
// This index is a mapping from db-assigned ID (a uint64 encoded using BigSize)
45
// to real session ID (33 bytes). This mapping will allow us to persist session
46
// pointers with fewer bytes in the future.
UNCOV
47
func MigrateSessionIDIndex(tx kvdb.RwTx) error {
×
UNCOV
48
        log.Infof("Migrating the tower client db to add a new session ID " +
×
UNCOV
49
                "index which stores a mapping from db-assigned ID to real " +
×
UNCOV
50
                "session ID")
×
UNCOV
51

×
UNCOV
52
        // Create a new top-level bucket for the index.
×
UNCOV
53
        indexBkt, err := tx.CreateTopLevelBucket(cSessionIDIndexBkt)
×
UNCOV
54
        if err != nil {
×
55
                return err
×
56
        }
×
57

58
        // Get the existing top-level sessions bucket.
UNCOV
59
        sessionsBkt := tx.ReadWriteBucket(cSessionBkt)
×
UNCOV
60
        if sessionsBkt == nil {
×
61
                return ErrUninitializedDB
×
62
        }
×
63

64
        // Iterate over the sessions bucket where each key is a session-ID.
UNCOV
65
        return sessionsBkt.ForEach(func(sessionID, _ []byte) error {
×
UNCOV
66
                // Ask the DB for a new, unique, id for the index bucket.
×
UNCOV
67
                nextSeq, err := indexBkt.NextSequence()
×
UNCOV
68
                if err != nil {
×
69
                        return err
×
70
                }
×
71

UNCOV
72
                newIndex, err := writeBigSize(nextSeq)
×
UNCOV
73
                if err != nil {
×
74
                        return err
×
75
                }
×
76

77
                // Add the new db-assigned-ID to real-session-ID pair to the
78
                // new index bucket.
UNCOV
79
                err = indexBkt.Put(newIndex, sessionID)
×
UNCOV
80
                if err != nil {
×
81
                        return err
×
82
                }
×
83

84
                // Get the sub-bucket for this specific session ID.
UNCOV
85
                sessionBkt := sessionsBkt.NestedReadWriteBucket(sessionID)
×
UNCOV
86
                if sessionBkt == nil {
×
UNCOV
87
                        return ErrCorruptClientSession
×
UNCOV
88
                }
×
89

90
                // Here we ensure that the session bucket includes a session
91
                // body. The only reason we do this is so that we can simulate
92
                // a migration fail in a test to ensure that a migration fail
93
                // results in an untouched db.
UNCOV
94
                sessionBodyBytes := sessionBkt.Get(cSessionBody)
×
UNCOV
95
                if sessionBodyBytes == nil {
×
96
                        return ErrCorruptClientSession
×
97
                }
×
98

99
                // Add the db-assigned ID of the session to the session under
100
                // the cSessionDBID key.
UNCOV
101
                return sessionBkt.Put(cSessionDBID, newIndex)
×
102
        })
103
}
104

105
// writeBigSize will encode the given uint64 as a BigSize byte slice.
UNCOV
106
func writeBigSize(i uint64) ([]byte, error) {
×
UNCOV
107
        var b bytes.Buffer
×
UNCOV
108
        err := tlv.WriteVarInt(&b, i, &[8]byte{})
×
UNCOV
109
        if err != nil {
×
110
                return nil, err
×
111
        }
×
112

UNCOV
113
        return b.Bytes(), nil
×
114
}
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