• 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/duplicate_payments.go
1
package channeldb
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "fmt"
7
        "io"
8
        "time"
9

10
        "github.com/btcsuite/btcd/btcec/v2"
11
        "github.com/lightningnetwork/lnd/kvdb"
12
        "github.com/lightningnetwork/lnd/lntypes"
13
        "github.com/lightningnetwork/lnd/lnwire"
14
        "github.com/lightningnetwork/lnd/routing/route"
15
)
16

17
var (
18
        // duplicatePaymentsBucket is the name of a optional sub-bucket within
19
        // the payment hash bucket, that is used to hold duplicate payments to a
20
        // payment hash. This is needed to support information from earlier
21
        // versions of lnd, where it was possible to pay to a payment hash more
22
        // than once.
23
        duplicatePaymentsBucket = []byte("payment-duplicate-bucket")
24

25
        // duplicatePaymentSettleInfoKey is a key used in the payment's
26
        // sub-bucket to store the settle info of the payment.
27
        duplicatePaymentSettleInfoKey = []byte("payment-settle-info")
28

29
        // duplicatePaymentAttemptInfoKey is a key used in the payment's
30
        // sub-bucket to store the info about the latest attempt that was done
31
        // for the payment in question.
32
        duplicatePaymentAttemptInfoKey = []byte("payment-attempt-info")
33

34
        // duplicatePaymentCreationInfoKey is a key used in the payment's
35
        // sub-bucket to store the creation info of the payment.
36
        duplicatePaymentCreationInfoKey = []byte("payment-creation-info")
37

38
        // duplicatePaymentFailInfoKey is a key used in the payment's sub-bucket
39
        // to store information about the reason a payment failed.
40
        duplicatePaymentFailInfoKey = []byte("payment-fail-info")
41

42
        // duplicatePaymentSequenceKey is a key used in the payment's sub-bucket
43
        // to store the sequence number of the payment.
44
        duplicatePaymentSequenceKey = []byte("payment-sequence-key")
45
)
46

47
// duplicateHTLCAttemptInfo contains static information about a specific HTLC
48
// attempt for a payment. This information is used by the router to handle any
49
// errors coming back after an attempt is made, and to query the switch about
50
// the status of the attempt.
51
type duplicateHTLCAttemptInfo struct {
52
        // attemptID is the unique ID used for this attempt.
53
        attemptID uint64
54

55
        // sessionKey is the ephemeral key used for this attempt.
56
        sessionKey [btcec.PrivKeyBytesLen]byte
57

58
        // route is the route attempted to send the HTLC.
59
        route route.Route
60
}
61

62
// fetchDuplicatePaymentStatus fetches the payment status of the payment. If
63
// the payment isn't found, it will return error `ErrPaymentNotInitiated`.
64
func fetchDuplicatePaymentStatus(bucket kvdb.RBucket) (PaymentStatus, error) {
×
65
        if bucket.Get(duplicatePaymentSettleInfoKey) != nil {
×
66
                return StatusSucceeded, nil
×
67
        }
×
68

69
        if bucket.Get(duplicatePaymentFailInfoKey) != nil {
×
70
                return StatusFailed, nil
×
71
        }
×
72

73
        if bucket.Get(duplicatePaymentCreationInfoKey) != nil {
×
74
                return StatusInFlight, nil
×
75
        }
×
76

77
        return 0, ErrPaymentNotInitiated
×
78
}
79

80
func deserializeDuplicateHTLCAttemptInfo(r io.Reader) (
81
        *duplicateHTLCAttemptInfo, error) {
×
82

×
83
        a := &duplicateHTLCAttemptInfo{}
×
84
        err := ReadElements(r, &a.attemptID, &a.sessionKey)
×
85
        if err != nil {
×
86
                return nil, err
×
87
        }
×
88
        a.route, err = DeserializeRoute(r)
×
89
        if err != nil {
×
90
                return nil, err
×
91
        }
×
92
        return a, nil
×
93
}
94

95
func deserializeDuplicatePaymentCreationInfo(r io.Reader) (
96
        *PaymentCreationInfo, error) {
×
97

×
98
        var scratch [8]byte
×
99

×
100
        c := &PaymentCreationInfo{}
×
101

×
102
        if _, err := io.ReadFull(r, c.PaymentIdentifier[:]); err != nil {
×
103
                return nil, err
×
104
        }
×
105

106
        if _, err := io.ReadFull(r, scratch[:]); err != nil {
×
107
                return nil, err
×
108
        }
×
109
        c.Value = lnwire.MilliSatoshi(byteOrder.Uint64(scratch[:]))
×
110

×
111
        if _, err := io.ReadFull(r, scratch[:]); err != nil {
×
112
                return nil, err
×
113
        }
×
114
        c.CreationTime = time.Unix(int64(byteOrder.Uint64(scratch[:])), 0)
×
115

×
116
        if _, err := io.ReadFull(r, scratch[:4]); err != nil {
×
117
                return nil, err
×
118
        }
×
119

120
        reqLen := byteOrder.Uint32(scratch[:4])
×
121
        payReq := make([]byte, reqLen)
×
122
        if reqLen > 0 {
×
123
                if _, err := io.ReadFull(r, payReq); err != nil {
×
124
                        return nil, err
×
125
                }
×
126
        }
127
        c.PaymentRequest = payReq
×
128

×
129
        return c, nil
×
130
}
131

132
func fetchDuplicatePayment(bucket kvdb.RBucket) (*MPPayment, error) {
×
133
        seqBytes := bucket.Get(duplicatePaymentSequenceKey)
×
134
        if seqBytes == nil {
×
135
                return nil, fmt.Errorf("sequence number not found")
×
136
        }
×
137

138
        sequenceNum := binary.BigEndian.Uint64(seqBytes)
×
139

×
140
        // Get the payment status.
×
141
        paymentStatus, err := fetchDuplicatePaymentStatus(bucket)
×
142
        if err != nil {
×
143
                return nil, err
×
144
        }
×
145

146
        // Get the PaymentCreationInfo.
147
        b := bucket.Get(duplicatePaymentCreationInfoKey)
×
148
        if b == nil {
×
149
                return nil, fmt.Errorf("creation info not found")
×
150
        }
×
151

152
        r := bytes.NewReader(b)
×
153
        creationInfo, err := deserializeDuplicatePaymentCreationInfo(r)
×
154
        if err != nil {
×
155
                return nil, err
×
156
        }
×
157

158
        // Get failure reason if available.
159
        var failureReason *FailureReason
×
160
        b = bucket.Get(duplicatePaymentFailInfoKey)
×
161
        if b != nil {
×
162
                reason := FailureReason(b[0])
×
163
                failureReason = &reason
×
164
        }
×
165

166
        payment := &MPPayment{
×
167
                SequenceNum:   sequenceNum,
×
168
                Info:          creationInfo,
×
169
                FailureReason: failureReason,
×
170
                Status:        paymentStatus,
×
171
        }
×
172

×
173
        // Get the HTLCAttemptInfo. It can be absent.
×
174
        b = bucket.Get(duplicatePaymentAttemptInfoKey)
×
175
        if b != nil {
×
176
                r = bytes.NewReader(b)
×
177
                attempt, err := deserializeDuplicateHTLCAttemptInfo(r)
×
178
                if err != nil {
×
179
                        return nil, err
×
180
                }
×
181

182
                htlc := HTLCAttempt{
×
183
                        HTLCAttemptInfo: HTLCAttemptInfo{
×
184
                                AttemptID:  attempt.attemptID,
×
185
                                Route:      attempt.route,
×
186
                                sessionKey: attempt.sessionKey,
×
187
                        },
×
188
                }
×
189

×
190
                // Get the payment preimage. This is only found for
×
191
                // successful payments.
×
192
                b = bucket.Get(duplicatePaymentSettleInfoKey)
×
193
                if b != nil {
×
194
                        var preimg lntypes.Preimage
×
195
                        copy(preimg[:], b)
×
196

×
197
                        htlc.Settle = &HTLCSettleInfo{
×
198
                                Preimage:   preimg,
×
199
                                SettleTime: time.Time{},
×
200
                        }
×
201
                } else {
×
202
                        // Otherwise the payment must have failed.
×
203
                        htlc.Failure = &HTLCFailInfo{
×
204
                                FailTime: time.Time{},
×
205
                        }
×
206
                }
×
207

208
                payment.HTLCs = []HTLCAttempt{htlc}
×
209
        }
210

211
        return payment, nil
×
212
}
213

214
func fetchDuplicatePayments(paymentHashBucket kvdb.RBucket) ([]*MPPayment,
215
        error) {
×
216

×
217
        var payments []*MPPayment
×
218

×
219
        // For older versions of lnd, duplicate payments to a payment has was
×
220
        // possible. These will be found in a sub-bucket indexed by their
×
221
        // sequence number if available.
×
222
        dup := paymentHashBucket.NestedReadBucket(duplicatePaymentsBucket)
×
223
        if dup == nil {
×
224
                return nil, nil
×
225
        }
×
226

227
        err := dup.ForEach(func(k, v []byte) error {
×
228
                subBucket := dup.NestedReadBucket(k)
×
229
                if subBucket == nil {
×
230
                        // We one bucket for each duplicate to be found.
×
231
                        return fmt.Errorf("non bucket element" +
×
232
                                "in duplicate bucket")
×
233
                }
×
234

235
                p, err := fetchDuplicatePayment(subBucket)
×
236
                if err != nil {
×
237
                        return err
×
238
                }
×
239

240
                payments = append(payments, p)
×
241
                return nil
×
242
        })
243
        if err != nil {
×
244
                return nil, err
×
245
        }
×
246

247
        return payments, nil
×
248
}
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