• 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/migration_01_to_11/migration_10_route_tlv_records.go
1
package migration_01_to_11
2

3
import (
4
        "bytes"
5
        "io"
6

7
        "github.com/lightningnetwork/lnd/kvdb"
8
)
9

10
// MigrateRouteSerialization migrates the way we serialize routes across the
11
// entire database. At the time of writing of this migration, this includes our
12
// payment attempts, as well as the payment results in mission control.
13
func MigrateRouteSerialization(tx kvdb.RwTx) error {
×
14
        // First, we'll do all the payment attempts.
×
15
        rootPaymentBucket := tx.ReadWriteBucket(paymentsRootBucket)
×
16
        if rootPaymentBucket == nil {
×
17
                return nil
×
18
        }
×
19

20
        // As we can't mutate a bucket while we're iterating over it with
21
        // ForEach, we'll need to collect all the known payment hashes in
22
        // memory first.
23
        var payHashes [][]byte
×
24
        err := rootPaymentBucket.ForEach(func(k, v []byte) error {
×
25
                if v != nil {
×
26
                        return nil
×
27
                }
×
28

29
                payHashes = append(payHashes, k)
×
30
                return nil
×
31
        })
32
        if err != nil {
×
33
                return err
×
34
        }
×
35

36
        // Now that we have all the payment hashes, we can carry out the
37
        // migration itself.
38
        for _, payHash := range payHashes {
×
39
                payHashBucket := rootPaymentBucket.NestedReadWriteBucket(payHash)
×
40

×
41
                // First, we'll migrate the main (non duplicate) payment to
×
42
                // this hash.
×
43
                err := migrateAttemptEncoding(tx, payHashBucket)
×
44
                if err != nil {
×
45
                        return err
×
46
                }
×
47

48
                // Now that we've migrated the main payment, we'll also check
49
                // for any duplicate payments to the same payment hash.
50
                dupBucket := payHashBucket.NestedReadWriteBucket(paymentDuplicateBucket)
×
51

×
52
                // If there's no dup bucket, then we can move on to the next
×
53
                // payment.
×
54
                if dupBucket == nil {
×
55
                        continue
×
56
                }
57

58
                // Otherwise, we'll now iterate through all the duplicate pay
59
                // hashes and migrate those.
60
                var dupSeqNos [][]byte
×
61
                err = dupBucket.ForEach(func(k, v []byte) error {
×
62
                        dupSeqNos = append(dupSeqNos, k)
×
63
                        return nil
×
64
                })
×
65
                if err != nil {
×
66
                        return err
×
67
                }
×
68

69
                // Now in this second pass, we'll re-serialize their duplicate
70
                // payment attempts under the new encoding.
71
                for _, seqNo := range dupSeqNos {
×
72
                        dupPayHashBucket := dupBucket.NestedReadWriteBucket(seqNo)
×
73
                        err := migrateAttemptEncoding(tx, dupPayHashBucket)
×
74
                        if err != nil {
×
75
                                return err
×
76
                        }
×
77
                }
78
        }
79

80
        log.Infof("Migration of route/hop serialization complete!")
×
81

×
82
        log.Infof("Migrating to new mission control store by clearing " +
×
83
                "existing data")
×
84

×
85
        resultsKey := []byte("missioncontrol-results")
×
86
        err = tx.DeleteTopLevelBucket(resultsKey)
×
87
        if err != nil && err != kvdb.ErrBucketNotFound {
×
88
                return err
×
89
        }
×
90

91
        log.Infof("Migration to new mission control completed!")
×
92

×
93
        return nil
×
94
}
95

96
// migrateAttemptEncoding migrates payment attempts using the legacy format to
97
// the new format.
98
func migrateAttemptEncoding(tx kvdb.RwTx, payHashBucket kvdb.RwBucket) error {
×
99
        payAttemptBytes := payHashBucket.Get(paymentAttemptInfoKey)
×
100
        if payAttemptBytes == nil {
×
101
                return nil
×
102
        }
×
103

104
        // For our migration, we'll first read out the existing payment attempt
105
        // using the legacy serialization of the attempt.
106
        payAttemptReader := bytes.NewReader(payAttemptBytes)
×
107
        payAttempt, err := deserializePaymentAttemptInfoLegacy(
×
108
                payAttemptReader,
×
109
        )
×
110
        if err != nil {
×
111
                return err
×
112
        }
×
113

114
        // Now that we have the old attempts, we'll explicitly mark this as
115
        // needing a legacy payload, since after this migration, the modern
116
        // payload will be the default if signalled.
117
        for _, hop := range payAttempt.Route.Hops {
×
118
                hop.LegacyPayload = true
×
119
        }
×
120

121
        // Finally, we'll write out the payment attempt using the new encoding.
122
        var b bytes.Buffer
×
123
        err = serializePaymentAttemptInfo(&b, payAttempt)
×
124
        if err != nil {
×
125
                return err
×
126
        }
×
127

128
        return payHashBucket.Put(paymentAttemptInfoKey, b.Bytes())
×
129
}
130

131
func deserializePaymentAttemptInfoLegacy(r io.Reader) (*PaymentAttemptInfo, error) {
×
132
        a := &PaymentAttemptInfo{}
×
133
        err := ReadElements(r, &a.PaymentID, &a.SessionKey)
×
134
        if err != nil {
×
135
                return nil, err
×
136
        }
×
137
        a.Route, err = deserializeRouteLegacy(r)
×
138
        if err != nil {
×
139
                return nil, err
×
140
        }
×
141
        return a, nil
×
142
}
143

144
func serializePaymentAttemptInfoLegacy(w io.Writer, a *PaymentAttemptInfo) error {
×
145
        if err := WriteElements(w, a.PaymentID, a.SessionKey); err != nil {
×
146
                return err
×
147
        }
×
148

149
        if err := serializeRouteLegacy(w, a.Route); err != nil {
×
150
                return err
×
151
        }
×
152

153
        return nil
×
154
}
155

156
func deserializeHopLegacy(r io.Reader) (*Hop, error) {
×
157
        h := &Hop{}
×
158

×
159
        var pub []byte
×
160
        if err := ReadElements(r, &pub); err != nil {
×
161
                return nil, err
×
162
        }
×
163
        copy(h.PubKeyBytes[:], pub)
×
164

×
165
        if err := ReadElements(r,
×
166
                &h.ChannelID, &h.OutgoingTimeLock, &h.AmtToForward,
×
167
        ); err != nil {
×
168
                return nil, err
×
169
        }
×
170

171
        return h, nil
×
172
}
173

174
func serializeHopLegacy(w io.Writer, h *Hop) error {
×
175
        if err := WriteElements(w,
×
176
                h.PubKeyBytes[:], h.ChannelID, h.OutgoingTimeLock,
×
177
                h.AmtToForward,
×
178
        ); err != nil {
×
179
                return err
×
180
        }
×
181

182
        return nil
×
183
}
184

185
func deserializeRouteLegacy(r io.Reader) (Route, error) {
×
186
        rt := Route{}
×
187
        if err := ReadElements(r,
×
188
                &rt.TotalTimeLock, &rt.TotalAmount,
×
189
        ); err != nil {
×
190
                return rt, err
×
191
        }
×
192

193
        var pub []byte
×
194
        if err := ReadElements(r, &pub); err != nil {
×
195
                return rt, err
×
196
        }
×
197
        copy(rt.SourcePubKey[:], pub)
×
198

×
199
        var numHops uint32
×
200
        if err := ReadElements(r, &numHops); err != nil {
×
201
                return rt, err
×
202
        }
×
203

204
        var hops []*Hop
×
205
        for i := uint32(0); i < numHops; i++ {
×
206
                hop, err := deserializeHopLegacy(r)
×
207
                if err != nil {
×
208
                        return rt, err
×
209
                }
×
210
                hops = append(hops, hop)
×
211
        }
212
        rt.Hops = hops
×
213

×
214
        return rt, nil
×
215
}
216

217
func serializeRouteLegacy(w io.Writer, r Route) error {
×
218
        if err := WriteElements(w,
×
219
                r.TotalTimeLock, r.TotalAmount, r.SourcePubKey[:],
×
220
        ); err != nil {
×
221
                return err
×
222
        }
×
223

224
        if err := WriteElements(w, uint32(len(r.Hops))); err != nil {
×
225
                return err
×
226
        }
×
227

228
        for _, h := range r.Hops {
×
229
                if err := serializeHopLegacy(w, h); err != nil {
×
230
                        return err
×
231
                }
×
232
        }
233

234
        return nil
×
235
}
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