duplicate_payments.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package channeldb
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "io"
  7. "time"
  8. "github.com/btcsuite/btcd/btcec/v2"
  9. "github.com/lightningnetwork/lnd/kvdb"
  10. "github.com/lightningnetwork/lnd/lntypes"
  11. "github.com/lightningnetwork/lnd/lnwire"
  12. "github.com/lightningnetwork/lnd/routing/route"
  13. )
  14. var (
  15. // duplicatePaymentsBucket is the name of a optional sub-bucket within
  16. // the payment hash bucket, that is used to hold duplicate payments to a
  17. // payment hash. This is needed to support information from earlier
  18. // versions of lnd, where it was possible to pay to a payment hash more
  19. // than once.
  20. duplicatePaymentsBucket = []byte("payment-duplicate-bucket")
  21. // duplicatePaymentSettleInfoKey is a key used in the payment's
  22. // sub-bucket to store the settle info of the payment.
  23. duplicatePaymentSettleInfoKey = []byte("payment-settle-info")
  24. // duplicatePaymentAttemptInfoKey is a key used in the payment's
  25. // sub-bucket to store the info about the latest attempt that was done
  26. // for the payment in question.
  27. duplicatePaymentAttemptInfoKey = []byte("payment-attempt-info")
  28. // duplicatePaymentCreationInfoKey is a key used in the payment's
  29. // sub-bucket to store the creation info of the payment.
  30. duplicatePaymentCreationInfoKey = []byte("payment-creation-info")
  31. // duplicatePaymentFailInfoKey is a key used in the payment's sub-bucket
  32. // to store information about the reason a payment failed.
  33. duplicatePaymentFailInfoKey = []byte("payment-fail-info")
  34. // duplicatePaymentSequenceKey is a key used in the payment's sub-bucket
  35. // to store the sequence number of the payment.
  36. duplicatePaymentSequenceKey = []byte("payment-sequence-key")
  37. )
  38. // duplicateHTLCAttemptInfo contains static information about a specific HTLC
  39. // attempt for a payment. This information is used by the router to handle any
  40. // errors coming back after an attempt is made, and to query the switch about
  41. // the status of the attempt.
  42. type duplicateHTLCAttemptInfo struct {
  43. // attemptID is the unique ID used for this attempt.
  44. attemptID uint64
  45. // sessionKey is the ephemeral key used for this attempt.
  46. sessionKey [btcec.PrivKeyBytesLen]byte
  47. // route is the route attempted to send the HTLC.
  48. route route.Route
  49. }
  50. // fetchDuplicatePaymentStatus fetches the payment status of the payment. If
  51. // the payment isn't found, it will return error `ErrPaymentNotInitiated`.
  52. func fetchDuplicatePaymentStatus(bucket kvdb.RBucket) (PaymentStatus, error) {
  53. if bucket.Get(duplicatePaymentSettleInfoKey) != nil {
  54. return StatusSucceeded, nil
  55. }
  56. if bucket.Get(duplicatePaymentFailInfoKey) != nil {
  57. return StatusFailed, nil
  58. }
  59. if bucket.Get(duplicatePaymentCreationInfoKey) != nil {
  60. return StatusInFlight, nil
  61. }
  62. return 0, ErrPaymentNotInitiated
  63. }
  64. func deserializeDuplicateHTLCAttemptInfo(r io.Reader) (
  65. *duplicateHTLCAttemptInfo, error) {
  66. a := &duplicateHTLCAttemptInfo{}
  67. err := ReadElements(r, &a.attemptID, &a.sessionKey)
  68. if err != nil {
  69. return nil, err
  70. }
  71. a.route, err = DeserializeRoute(r)
  72. if err != nil {
  73. return nil, err
  74. }
  75. return a, nil
  76. }
  77. func deserializeDuplicatePaymentCreationInfo(r io.Reader) (
  78. *PaymentCreationInfo, error) {
  79. var scratch [8]byte
  80. c := &PaymentCreationInfo{}
  81. if _, err := io.ReadFull(r, c.PaymentIdentifier[:]); err != nil {
  82. return nil, err
  83. }
  84. if _, err := io.ReadFull(r, scratch[:]); err != nil {
  85. return nil, err
  86. }
  87. c.Value = lnwire.MilliSatoshi(byteOrder.Uint64(scratch[:]))
  88. if _, err := io.ReadFull(r, scratch[:]); err != nil {
  89. return nil, err
  90. }
  91. c.CreationTime = time.Unix(int64(byteOrder.Uint64(scratch[:])), 0)
  92. if _, err := io.ReadFull(r, scratch[:4]); err != nil {
  93. return nil, err
  94. }
  95. reqLen := byteOrder.Uint32(scratch[:4])
  96. payReq := make([]byte, reqLen)
  97. if reqLen > 0 {
  98. if _, err := io.ReadFull(r, payReq); err != nil {
  99. return nil, err
  100. }
  101. }
  102. c.PaymentRequest = payReq
  103. return c, nil
  104. }
  105. func fetchDuplicatePayment(bucket kvdb.RBucket) (*MPPayment, error) {
  106. seqBytes := bucket.Get(duplicatePaymentSequenceKey)
  107. if seqBytes == nil {
  108. return nil, fmt.Errorf("sequence number not found")
  109. }
  110. sequenceNum := binary.BigEndian.Uint64(seqBytes)
  111. // Get the payment status.
  112. paymentStatus, err := fetchDuplicatePaymentStatus(bucket)
  113. if err != nil {
  114. return nil, err
  115. }
  116. // Get the PaymentCreationInfo.
  117. b := bucket.Get(duplicatePaymentCreationInfoKey)
  118. if b == nil {
  119. return nil, fmt.Errorf("creation info not found")
  120. }
  121. r := bytes.NewReader(b)
  122. creationInfo, err := deserializeDuplicatePaymentCreationInfo(r)
  123. if err != nil {
  124. return nil, err
  125. }
  126. // Get failure reason if available.
  127. var failureReason *FailureReason
  128. b = bucket.Get(duplicatePaymentFailInfoKey)
  129. if b != nil {
  130. reason := FailureReason(b[0])
  131. failureReason = &reason
  132. }
  133. payment := &MPPayment{
  134. SequenceNum: sequenceNum,
  135. Info: creationInfo,
  136. FailureReason: failureReason,
  137. Status: paymentStatus,
  138. }
  139. // Get the HTLCAttemptInfo. It can be absent.
  140. b = bucket.Get(duplicatePaymentAttemptInfoKey)
  141. if b != nil {
  142. r = bytes.NewReader(b)
  143. attempt, err := deserializeDuplicateHTLCAttemptInfo(r)
  144. if err != nil {
  145. return nil, err
  146. }
  147. htlc := HTLCAttempt{
  148. HTLCAttemptInfo: HTLCAttemptInfo{
  149. AttemptID: attempt.attemptID,
  150. Route: attempt.route,
  151. sessionKey: attempt.sessionKey,
  152. },
  153. }
  154. // Get the payment preimage. This is only found for
  155. // successful payments.
  156. b = bucket.Get(duplicatePaymentSettleInfoKey)
  157. if b != nil {
  158. var preimg lntypes.Preimage
  159. copy(preimg[:], b)
  160. htlc.Settle = &HTLCSettleInfo{
  161. Preimage: preimg,
  162. SettleTime: time.Time{},
  163. }
  164. } else {
  165. // Otherwise the payment must have failed.
  166. htlc.Failure = &HTLCFailInfo{
  167. FailTime: time.Time{},
  168. }
  169. }
  170. payment.HTLCs = []HTLCAttempt{htlc}
  171. }
  172. return payment, nil
  173. }
  174. func fetchDuplicatePayments(paymentHashBucket kvdb.RBucket) ([]*MPPayment,
  175. error) {
  176. var payments []*MPPayment
  177. // For older versions of lnd, duplicate payments to a payment has was
  178. // possible. These will be found in a sub-bucket indexed by their
  179. // sequence number if available.
  180. dup := paymentHashBucket.NestedReadBucket(duplicatePaymentsBucket)
  181. if dup == nil {
  182. return nil, nil
  183. }
  184. err := dup.ForEach(func(k, v []byte) error {
  185. subBucket := dup.NestedReadBucket(k)
  186. if subBucket == nil {
  187. // We one bucket for each duplicate to be found.
  188. return fmt.Errorf("non bucket element" +
  189. "in duplicate bucket")
  190. }
  191. p, err := fetchDuplicatePayment(subBucket)
  192. if err != nil {
  193. return err
  194. }
  195. payments = append(payments, p)
  196. return nil
  197. })
  198. if err != nil {
  199. return nil, err
  200. }
  201. return payments, nil
  202. }