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

lightningnetwork / lnd / 13035292482

29 Jan 2025 03:59PM UTC coverage: 49.3% (-9.5%) from 58.777%
13035292482

Pull #9456

github

mohamedawnallah
docs: update release-notes-0.19.0.md

In this commit, we warn users about the removal
of RPCs `SendToRoute`, `SendToRouteSync`, `SendPayment`,
and `SendPaymentSync` in the next release 0.20.
Pull Request #9456: lnrpc+docs: deprecate warning `SendToRoute`, `SendToRouteSync`, `SendPayment`, and `SendPaymentSync` in Release 0.19

100634 of 204126 relevant lines covered (49.3%)

1.54 hits per line

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

0.0
/channeldb/migration16/migration.go
1
package migration16
2

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

9
        "github.com/btcsuite/btcd/wire"
10
        "github.com/lightningnetwork/lnd/kvdb"
11
)
12

13
var (
14
        paymentsRootBucket = []byte("payments-root-bucket")
15

16
        paymentSequenceKey = []byte("payment-sequence-key")
17

18
        duplicatePaymentsBucket = []byte("payment-duplicate-bucket")
19

20
        paymentsIndexBucket = []byte("payments-index-bucket")
21

22
        byteOrder = binary.BigEndian
23
)
24

25
// paymentIndexType indicates the type of index we have recorded in the payment
26
// indexes bucket.
27
type paymentIndexType uint8
28

29
// paymentIndexTypeHash is a payment index type which indicates that we have
30
// created an index of payment sequence number to payment hash.
31
const paymentIndexTypeHash paymentIndexType = 0
32

33
// paymentIndex stores all the information we require to create an index by
34
// sequence number for a payment.
35
type paymentIndex struct {
36
        // paymentHash is the hash of the payment, which is its key in the
37
        // payment root bucket.
38
        paymentHash []byte
39

40
        // sequenceNumbers is the set of sequence numbers associated with this
41
        // payment hash. There will be more than one sequence number in the
42
        // case where duplicate payments are present.
43
        sequenceNumbers [][]byte
44
}
45

46
// MigrateSequenceIndex migrates the payments db to contain a new bucket which
47
// provides an index from sequence number to payment hash. This is required
48
// for more efficient sequential lookup of payments, which are keyed by payment
49
// hash before this migration.
50
func MigrateSequenceIndex(tx kvdb.RwTx) error {
×
51
        log.Infof("Migrating payments to add sequence number index")
×
52

×
53
        // Get a list of indices we need to write.
×
54
        indexList, err := getPaymentIndexList(tx)
×
55
        if err != nil {
×
56
                return err
×
57
        }
×
58

59
        // Create the top level bucket that we will use to index payments in.
60
        bucket, err := tx.CreateTopLevelBucket(paymentsIndexBucket)
×
61
        if err != nil {
×
62
                return err
×
63
        }
×
64

65
        // Write an index for each of our payments.
66
        for _, index := range indexList {
×
67
                // Write indexes for each of our sequence numbers.
×
68
                for _, seqNr := range index.sequenceNumbers {
×
69
                        err := putIndex(bucket, seqNr, index.paymentHash)
×
70
                        if err != nil {
×
71
                                return err
×
72
                        }
×
73
                }
74
        }
75

76
        return nil
×
77
}
78

79
// putIndex performs a sanity check that ensures we are not writing duplicate
80
// indexes to disk then creates the index provided.
81
func putIndex(bucket kvdb.RwBucket, sequenceNr, paymentHash []byte) error {
×
82
        // Add a sanity check that we do not already have an entry with
×
83
        // this sequence number.
×
84
        existingEntry := bucket.Get(sequenceNr)
×
85
        if existingEntry != nil {
×
86
                return fmt.Errorf("sequence number: %x duplicated",
×
87
                        sequenceNr)
×
88
        }
×
89

90
        bytes, err := serializePaymentIndexEntry(paymentHash)
×
91
        if err != nil {
×
92
                return err
×
93
        }
×
94

95
        return bucket.Put(sequenceNr, bytes)
×
96
}
97

98
// serializePaymentIndexEntry serializes a payment hash typed index. The value
99
// produced contains a payment index type (which can be used in future to
100
// signal different payment index types) and the payment hash.
101
func serializePaymentIndexEntry(hash []byte) ([]byte, error) {
×
102
        var b bytes.Buffer
×
103

×
104
        err := binary.Write(&b, byteOrder, paymentIndexTypeHash)
×
105
        if err != nil {
×
106
                return nil, err
×
107
        }
×
108

109
        if err := wire.WriteVarBytes(&b, 0, hash); err != nil {
×
110
                return nil, err
×
111
        }
×
112

113
        return b.Bytes(), nil
×
114
}
115

116
// getPaymentIndexList gets a list of indices we need to write for our current
117
// set of payments.
118
func getPaymentIndexList(tx kvdb.RTx) ([]paymentIndex, error) {
×
119
        // Iterate over all payments and store their indexing keys. This is
×
120
        // needed, because no modifications are allowed inside a Bucket.ForEach
×
121
        // loop.
×
122
        paymentsBucket := tx.ReadBucket(paymentsRootBucket)
×
123
        if paymentsBucket == nil {
×
124
                return nil, nil
×
125
        }
×
126

127
        var indexList []paymentIndex
×
128
        err := paymentsBucket.ForEach(func(k, v []byte) error {
×
129
                // Get the bucket which contains the payment, fail if the key
×
130
                // does not have a bucket.
×
131
                bucket := paymentsBucket.NestedReadBucket(k)
×
132
                if bucket == nil {
×
133
                        return fmt.Errorf("non bucket element in " +
×
134
                                "payments bucket")
×
135
                }
×
136
                seqBytes := bucket.Get(paymentSequenceKey)
×
137
                if seqBytes == nil {
×
138
                        return fmt.Errorf("nil sequence number bytes")
×
139
                }
×
140

141
                seqNrs, err := fetchSequenceNumbers(bucket)
×
142
                if err != nil {
×
143
                        return err
×
144
                }
×
145

146
                // Create an index object with our payment hash and sequence
147
                // numbers and append it to our set of indexes.
148
                index := paymentIndex{
×
149
                        paymentHash:     k,
×
150
                        sequenceNumbers: seqNrs,
×
151
                }
×
152

×
153
                indexList = append(indexList, index)
×
154
                return nil
×
155
        })
156
        if err != nil {
×
157
                return nil, err
×
158
        }
×
159

160
        return indexList, nil
×
161
}
162

163
// fetchSequenceNumbers fetches all the sequence numbers associated with a
164
// payment, including those belonging to any duplicate payments.
165
func fetchSequenceNumbers(paymentBucket kvdb.RBucket) ([][]byte, error) {
×
166
        seqNum := paymentBucket.Get(paymentSequenceKey)
×
167
        if seqNum == nil {
×
168
                return nil, errors.New("expected sequence number")
×
169
        }
×
170

171
        sequenceNumbers := [][]byte{seqNum}
×
172

×
173
        // Get the duplicate payments bucket, if it has no duplicates, just
×
174
        // return early with the payment sequence number.
×
175
        duplicates := paymentBucket.NestedReadBucket(duplicatePaymentsBucket)
×
176
        if duplicates == nil {
×
177
                return sequenceNumbers, nil
×
178
        }
×
179

180
        // If we do have duplicated, they are keyed by sequence number, so we
181
        // iterate through the duplicates bucket and add them to our set of
182
        // sequence numbers.
183
        if err := duplicates.ForEach(func(k, v []byte) error {
×
184
                sequenceNumbers = append(sequenceNumbers, k)
×
185
                return nil
×
186
        }); err != nil {
×
187
                return nil, err
×
188
        }
×
189

190
        return sequenceNumbers, nil
×
191
}
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