github.com/decred/dcrlnd@v0.7.6/channeldb/payments.go (about) 1 package channeldb 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "errors" 7 "fmt" 8 "io" 9 "sort" 10 "time" 11 12 "github.com/decred/dcrd/wire" 13 "github.com/decred/dcrlnd/kvdb" 14 "github.com/decred/dcrlnd/lntypes" 15 "github.com/decred/dcrlnd/lnwire" 16 "github.com/decred/dcrlnd/record" 17 "github.com/decred/dcrlnd/routing/route" 18 "github.com/decred/dcrlnd/tlv" 19 ) 20 21 var ( 22 // paymentsRootBucket is the name of the top-level bucket within the 23 // database that stores all data related to payments. Within this 24 // bucket, each payment hash its own sub-bucket keyed by its payment 25 // hash. 26 // 27 // Bucket hierarchy: 28 // 29 // root-bucket 30 // | 31 // |-- <paymenthash> 32 // | |--sequence-key: <sequence number> 33 // | |--creation-info-key: <creation info> 34 // | |--fail-info-key: <(optional) fail info> 35 // | | 36 // | |--payment-htlcs-bucket (shard-bucket) 37 // | | | 38 // | | |-- ai<htlc attempt ID>: <htlc attempt info> 39 // | | |-- si<htlc attempt ID>: <(optional) settle info> 40 // | | |-- fi<htlc attempt ID>: <(optional) fail info> 41 // | | | 42 // | | ... 43 // | | 44 // | | 45 // | |--duplicate-bucket (only for old, completed payments) 46 // | | 47 // | |-- <seq-num> 48 // | | |--sequence-key: <sequence number> 49 // | | |--creation-info-key: <creation info> 50 // | | |--ai: <attempt info> 51 // | | |--si: <settle info> 52 // | | |--fi: <fail info> 53 // | | 54 // | |-- <seq-num> 55 // | | | 56 // | ... ... 57 // | 58 // |-- <paymenthash> 59 // | | 60 // | ... 61 // ... 62 // 63 paymentsRootBucket = []byte("payments-root-bucket") 64 65 // paymentSequenceKey is a key used in the payment's sub-bucket to 66 // store the sequence number of the payment. 67 paymentSequenceKey = []byte("payment-sequence-key") 68 69 // paymentCreationInfoKey is a key used in the payment's sub-bucket to 70 // store the creation info of the payment. 71 paymentCreationInfoKey = []byte("payment-creation-info") 72 73 // paymentHtlcsBucket is a bucket where we'll store the information 74 // about the HTLCs that were attempted for a payment. 75 paymentHtlcsBucket = []byte("payment-htlcs-bucket") 76 77 // htlcAttemptInfoKey is the key used as the prefix of an HTLC attempt 78 // to store the info about the attempt that was done for the HTLC in 79 // question. The HTLC attempt ID is concatenated at the end. 80 htlcAttemptInfoKey = []byte("ai") 81 82 // htlcSettleInfoKey is the key used as the prefix of an HTLC attempt 83 // settle info, if any. The HTLC attempt ID is concatenated at the end. 84 htlcSettleInfoKey = []byte("si") 85 86 // htlcFailInfoKey is the key used as the prefix of an HTLC attempt 87 // failure information, if any.The HTLC attempt ID is concatenated at 88 // the end. 89 htlcFailInfoKey = []byte("fi") 90 91 // paymentFailInfoKey is a key used in the payment's sub-bucket to 92 // store information about the reason a payment failed. 93 paymentFailInfoKey = []byte("payment-fail-info") 94 95 // paymentsIndexBucket is the name of the top-level bucket within the 96 // database that stores an index of payment sequence numbers to its 97 // payment hash. 98 // payments-sequence-index-bucket 99 // |--<sequence-number>: <payment hash> 100 // |--... 101 // |--<sequence-number>: <payment hash> 102 paymentsIndexBucket = []byte("payments-index-bucket") 103 ) 104 105 var ( 106 // ErrNoSequenceNumber is returned if we lookup a payment which does 107 // not have a sequence number. 108 ErrNoSequenceNumber = errors.New("sequence number not found") 109 110 // ErrDuplicateNotFound is returned when we lookup a payment by its 111 // index and cannot find a payment with a matching sequence number. 112 ErrDuplicateNotFound = errors.New("duplicate payment not found") 113 114 // ErrNoDuplicateBucket is returned when we expect to find duplicates 115 // when looking up a payment from its index, but the payment does not 116 // have any. 117 ErrNoDuplicateBucket = errors.New("expected duplicate bucket") 118 119 // ErrNoDuplicateNestedBucket is returned if we do not find duplicate 120 // payments in their own sub-bucket. 121 ErrNoDuplicateNestedBucket = errors.New("nested duplicate bucket not " + 122 "found") 123 ) 124 125 // FailureReason encodes the reason a payment ultimately failed. 126 type FailureReason byte 127 128 const ( 129 // FailureReasonTimeout indicates that the payment did timeout before a 130 // successful payment attempt was made. 131 FailureReasonTimeout FailureReason = 0 132 133 // FailureReasonNoRoute indicates no successful route to the 134 // destination was found during path finding. 135 FailureReasonNoRoute FailureReason = 1 136 137 // FailureReasonError indicates that an unexpected error happened during 138 // payment. 139 FailureReasonError FailureReason = 2 140 141 // FailureReasonPaymentDetails indicates that either the hash is unknown 142 // or the final cltv delta or amount is incorrect. 143 FailureReasonPaymentDetails FailureReason = 3 144 145 // FailureReasonInsufficientBalance indicates that we didn't have enough 146 // balance to complete the payment. 147 FailureReasonInsufficientBalance FailureReason = 4 148 149 // TODO(halseth): cancel state. 150 151 // TODO(joostjager): Add failure reasons for: 152 // LocalLiquidityInsufficient, RemoteCapacityInsufficient. 153 ) 154 155 // Error returns a human readable error string for the FailureReason. 156 func (r FailureReason) Error() string { 157 return r.String() 158 } 159 160 // String returns a human readable FailureReason. 161 func (r FailureReason) String() string { 162 switch r { 163 case FailureReasonTimeout: 164 return "timeout" 165 case FailureReasonNoRoute: 166 return "no_route" 167 case FailureReasonError: 168 return "error" 169 case FailureReasonPaymentDetails: 170 return "incorrect_payment_details" 171 case FailureReasonInsufficientBalance: 172 return "insufficient_balance" 173 } 174 175 return "unknown" 176 } 177 178 // PaymentStatus represent current status of payment 179 type PaymentStatus byte 180 181 const ( 182 // StatusUnknown is the status where a payment has never been initiated 183 // and hence is unknown. 184 StatusUnknown PaymentStatus = 0 185 186 // StatusInFlight is the status where a payment has been initiated, but 187 // a response has not been received. 188 StatusInFlight PaymentStatus = 1 189 190 // StatusSucceeded is the status where a payment has been initiated and 191 // the payment was completed successfully. 192 StatusSucceeded PaymentStatus = 2 193 194 // StatusFailed is the status where a payment has been initiated and a 195 // failure result has come back. 196 StatusFailed PaymentStatus = 3 197 ) 198 199 // String returns readable representation of payment status. 200 func (ps PaymentStatus) String() string { 201 switch ps { 202 case StatusUnknown: 203 return "Unknown" 204 case StatusInFlight: 205 return "In Flight" 206 case StatusSucceeded: 207 return "Succeeded" 208 case StatusFailed: 209 return "Failed" 210 default: 211 return "Unknown" 212 } 213 } 214 215 // PaymentCreationInfo is the information necessary to have ready when 216 // initiating a payment, moving it into state InFlight. 217 type PaymentCreationInfo struct { 218 // PaymentIdentifier is the hash this payment is paying to in case of 219 // non-AMP payments, and the SetID for AMP payments. 220 PaymentIdentifier lntypes.Hash 221 222 // Value is the amount we are paying. 223 Value lnwire.MilliAtom 224 225 // CreationTime is the time when this payment was initiated. 226 CreationTime time.Time 227 228 // PaymentRequest is the full payment request, if any. 229 PaymentRequest []byte 230 } 231 232 // htlcBucketKey creates a composite key from prefix and id where the result is 233 // simply the two concatenated. 234 func htlcBucketKey(prefix, id []byte) []byte { 235 key := make([]byte, len(prefix)+len(id)) 236 copy(key, prefix) 237 copy(key[len(prefix):], id) 238 return key 239 } 240 241 // FetchPayments returns all sent payments found in the DB. 242 // 243 // nolint: dupl 244 func (d *DB) FetchPayments() ([]*MPPayment, error) { 245 var payments []*MPPayment 246 247 err := kvdb.View(d, func(tx kvdb.RTx) error { 248 paymentsBucket := tx.ReadBucket(paymentsRootBucket) 249 if paymentsBucket == nil { 250 return nil 251 } 252 253 return paymentsBucket.ForEach(func(k, v []byte) error { 254 bucket := paymentsBucket.NestedReadBucket(k) 255 if bucket == nil { 256 // We only expect sub-buckets to be found in 257 // this top-level bucket. 258 return fmt.Errorf("non bucket element in " + 259 "payments bucket") 260 } 261 262 p, err := fetchPayment(bucket) 263 if err != nil { 264 return err 265 } 266 267 payments = append(payments, p) 268 269 // For older versions of lnd, duplicate payments to a 270 // payment has was possible. These will be found in a 271 // sub-bucket indexed by their sequence number if 272 // available. 273 duplicatePayments, err := fetchDuplicatePayments(bucket) 274 if err != nil { 275 return err 276 } 277 278 payments = append(payments, duplicatePayments...) 279 return nil 280 }) 281 }, func() { 282 payments = nil 283 }) 284 if err != nil { 285 return nil, err 286 } 287 288 // Before returning, sort the payments by their sequence number. 289 sort.Slice(payments, func(i, j int) bool { 290 return payments[i].SequenceNum < payments[j].SequenceNum 291 }) 292 293 return payments, nil 294 } 295 296 func fetchCreationInfo(bucket kvdb.RBucket) (*PaymentCreationInfo, error) { 297 b := bucket.Get(paymentCreationInfoKey) 298 if b == nil { 299 return nil, fmt.Errorf("creation info not found") 300 } 301 302 r := bytes.NewReader(b) 303 return deserializePaymentCreationInfo(r) 304 } 305 306 func fetchPayment(bucket kvdb.RBucket) (*MPPayment, error) { 307 seqBytes := bucket.Get(paymentSequenceKey) 308 if seqBytes == nil { 309 return nil, fmt.Errorf("sequence number not found") 310 } 311 312 sequenceNum := binary.BigEndian.Uint64(seqBytes) 313 314 // Get the PaymentCreationInfo. 315 creationInfo, err := fetchCreationInfo(bucket) 316 if err != nil { 317 return nil, err 318 319 } 320 321 var htlcs []HTLCAttempt 322 htlcsBucket := bucket.NestedReadBucket(paymentHtlcsBucket) 323 if htlcsBucket != nil { 324 // Get the payment attempts. This can be empty. 325 htlcs, err = fetchHtlcAttempts(htlcsBucket) 326 if err != nil { 327 return nil, err 328 } 329 } 330 331 // Get failure reason if available. 332 var failureReason *FailureReason 333 b := bucket.Get(paymentFailInfoKey) 334 if b != nil { 335 reason := FailureReason(b[0]) 336 failureReason = &reason 337 } 338 339 // Go through all HTLCs for this payment, noting whether we have any 340 // settled HTLC, and any still in-flight. 341 var inflight, settled bool 342 for _, h := range htlcs { 343 if h.Failure != nil { 344 continue 345 } 346 347 if h.Settle != nil { 348 settled = true 349 continue 350 } 351 352 // If any of the HTLCs are not failed nor settled, we 353 // still have inflight HTLCs. 354 inflight = true 355 } 356 357 // Use the DB state to determine the status of the payment. 358 var paymentStatus PaymentStatus 359 360 switch { 361 362 // If any of the the HTLCs did succeed and there are no HTLCs in 363 // flight, the payment succeeded. 364 case !inflight && settled: 365 paymentStatus = StatusSucceeded 366 367 // If we have no in-flight HTLCs, and the payment failure is set, the 368 // payment is considered failed. 369 case !inflight && failureReason != nil: 370 paymentStatus = StatusFailed 371 372 // Otherwise it is still in flight. 373 default: 374 paymentStatus = StatusInFlight 375 } 376 377 return &MPPayment{ 378 SequenceNum: sequenceNum, 379 Info: creationInfo, 380 HTLCs: htlcs, 381 FailureReason: failureReason, 382 Status: paymentStatus, 383 }, nil 384 } 385 386 // fetchHtlcAttempts retrives all htlc attempts made for the payment found in 387 // the given bucket. 388 func fetchHtlcAttempts(bucket kvdb.RBucket) ([]HTLCAttempt, error) { 389 htlcsMap := make(map[uint64]*HTLCAttempt) 390 391 attemptInfoCount := 0 392 err := bucket.ForEach(func(k, v []byte) error { 393 aid := byteOrder.Uint64(k[len(k)-8:]) 394 395 if _, ok := htlcsMap[aid]; !ok { 396 htlcsMap[aid] = &HTLCAttempt{} 397 } 398 399 var err error 400 switch { 401 case bytes.HasPrefix(k, htlcAttemptInfoKey): 402 attemptInfo, err := readHtlcAttemptInfo(v) 403 if err != nil { 404 return err 405 } 406 407 attemptInfo.AttemptID = aid 408 htlcsMap[aid].HTLCAttemptInfo = *attemptInfo 409 attemptInfoCount++ 410 411 case bytes.HasPrefix(k, htlcSettleInfoKey): 412 htlcsMap[aid].Settle, err = readHtlcSettleInfo(v) 413 if err != nil { 414 return err 415 } 416 417 case bytes.HasPrefix(k, htlcFailInfoKey): 418 htlcsMap[aid].Failure, err = readHtlcFailInfo(v) 419 if err != nil { 420 return err 421 } 422 423 default: 424 return fmt.Errorf("unknown htlc attempt key") 425 } 426 427 return nil 428 }) 429 if err != nil { 430 return nil, err 431 } 432 433 // Sanity check that all htlcs have an attempt info. 434 if attemptInfoCount != len(htlcsMap) { 435 return nil, errNoAttemptInfo 436 } 437 438 keys := make([]uint64, len(htlcsMap)) 439 i := 0 440 for k := range htlcsMap { 441 keys[i] = k 442 i++ 443 } 444 445 // Sort HTLC attempts by their attempt ID. This is needed because in the 446 // DB we store the attempts with keys prefixed by their status which 447 // changes order (groups them together by status). 448 sort.Slice(keys, func(i, j int) bool { 449 return keys[i] < keys[j] 450 }) 451 452 htlcs := make([]HTLCAttempt, len(htlcsMap)) 453 for i, key := range keys { 454 htlcs[i] = *htlcsMap[key] 455 } 456 457 return htlcs, nil 458 } 459 460 // readHtlcAttemptInfo reads the payment attempt info for this htlc. 461 func readHtlcAttemptInfo(b []byte) (*HTLCAttemptInfo, error) { 462 r := bytes.NewReader(b) 463 return deserializeHTLCAttemptInfo(r) 464 } 465 466 // readHtlcSettleInfo reads the settle info for the htlc. If the htlc isn't 467 // settled, nil is returned. 468 func readHtlcSettleInfo(b []byte) (*HTLCSettleInfo, error) { 469 r := bytes.NewReader(b) 470 return deserializeHTLCSettleInfo(r) 471 } 472 473 // readHtlcFailInfo reads the failure info for the htlc. If the htlc hasn't 474 // failed, nil is returned. 475 func readHtlcFailInfo(b []byte) (*HTLCFailInfo, error) { 476 r := bytes.NewReader(b) 477 return deserializeHTLCFailInfo(r) 478 } 479 480 // fetchFailedHtlcKeys retrieves the bucket keys of all failed HTLCs of a 481 // payment bucket. 482 func fetchFailedHtlcKeys(bucket kvdb.RBucket) ([][]byte, error) { 483 htlcsBucket := bucket.NestedReadBucket(paymentHtlcsBucket) 484 485 var htlcs []HTLCAttempt 486 var err error 487 if htlcsBucket != nil { 488 htlcs, err = fetchHtlcAttempts(htlcsBucket) 489 if err != nil { 490 return nil, err 491 } 492 } 493 494 // Now iterate though them and save the bucket keys for the failed 495 // HTLCs. 496 var htlcKeys [][]byte 497 for _, h := range htlcs { 498 if h.Failure == nil { 499 continue 500 } 501 502 htlcKeyBytes := make([]byte, 8) 503 binary.BigEndian.PutUint64(htlcKeyBytes, h.AttemptID) 504 505 htlcKeys = append(htlcKeys, htlcKeyBytes) 506 } 507 508 return htlcKeys, nil 509 } 510 511 // PaymentsQuery represents a query to the payments database starting or ending 512 // at a certain offset index. The number of retrieved records can be limited. 513 type PaymentsQuery struct { 514 // IndexOffset determines the starting point of the payments query and 515 // is always exclusive. In normal order, the query starts at the next 516 // higher (available) index compared to IndexOffset. In reversed order, 517 // the query ends at the next lower (available) index compared to the 518 // IndexOffset. In the case of a zero index_offset, the query will start 519 // with the oldest payment when paginating forwards, or will end with 520 // the most recent payment when paginating backwards. 521 IndexOffset uint64 522 523 // MaxPayments is the maximal number of payments returned in the 524 // payments query. 525 MaxPayments uint64 526 527 // Reversed gives a meaning to the IndexOffset. If reversed is set to 528 // true, the query will fetch payments with indices lower than the 529 // IndexOffset, otherwise, it will return payments with indices greater 530 // than the IndexOffset. 531 Reversed bool 532 533 // If IncludeIncomplete is true, then return payments that have not yet 534 // fully completed. This means that pending payments, as well as failed 535 // payments will show up if this field is set to true. 536 IncludeIncomplete bool 537 } 538 539 // PaymentsResponse contains the result of a query to the payments database. 540 // It includes the set of payments that match the query and integers which 541 // represent the index of the first and last item returned in the series of 542 // payments. These integers allow callers to resume their query in the event 543 // that the query's response exceeds the max number of returnable events. 544 type PaymentsResponse struct { 545 // Payments is the set of payments returned from the database for the 546 // PaymentsQuery. 547 Payments []*MPPayment 548 549 // FirstIndexOffset is the index of the first element in the set of 550 // returned MPPayments. Callers can use this to resume their query 551 // in the event that the slice has too many events to fit into a single 552 // response. The offset can be used to continue reverse pagination. 553 FirstIndexOffset uint64 554 555 // LastIndexOffset is the index of the last element in the set of 556 // returned MPPayments. Callers can use this to resume their query 557 // in the event that the slice has too many events to fit into a single 558 // response. The offset can be used to continue forward pagination. 559 LastIndexOffset uint64 560 } 561 562 // QueryPayments is a query to the payments database which is restricted 563 // to a subset of payments by the payments query, containing an offset 564 // index and a maximum number of returned payments. 565 func (d *DB) QueryPayments(query PaymentsQuery) (PaymentsResponse, error) { 566 var resp PaymentsResponse 567 568 if err := kvdb.View(d, func(tx kvdb.RTx) error { 569 // Get the root payments bucket. 570 paymentsBucket := tx.ReadBucket(paymentsRootBucket) 571 if paymentsBucket == nil { 572 return nil 573 } 574 575 // Get the index bucket which maps sequence number -> payment 576 // hash and duplicate bool. If we have a payments bucket, we 577 // should have an indexes bucket as well. 578 indexes := tx.ReadBucket(paymentsIndexBucket) 579 if indexes == nil { 580 return fmt.Errorf("index bucket does not exist") 581 } 582 583 // accumulatePayments gets payments with the sequence number 584 // and hash provided and adds them to our list of payments if 585 // they meet the criteria of our query. It returns the number 586 // of payments that were added. 587 accumulatePayments := func(sequenceKey, hash []byte) (bool, 588 error) { 589 590 r := bytes.NewReader(hash) 591 paymentHash, err := deserializePaymentIndex(r) 592 if err != nil { 593 return false, err 594 } 595 596 payment, err := fetchPaymentWithSequenceNumber( 597 tx, paymentHash, sequenceKey, 598 ) 599 if err != nil { 600 return false, err 601 } 602 603 // To keep compatibility with the old API, we only 604 // return non-succeeded payments if requested. 605 if payment.Status != StatusSucceeded && 606 !query.IncludeIncomplete { 607 608 return false, err 609 } 610 611 // At this point, we've exhausted the offset, so we'll 612 // begin collecting invoices found within the range. 613 resp.Payments = append(resp.Payments, payment) 614 return true, nil 615 } 616 617 // Create a paginator which reads from our sequence index bucket 618 // with the parameters provided by the payments query. 619 paginator := newPaginator( 620 indexes.ReadCursor(), query.Reversed, query.IndexOffset, 621 query.MaxPayments, 622 ) 623 624 // Run a paginated query, adding payments to our response. 625 if err := paginator.query(accumulatePayments); err != nil { 626 return err 627 } 628 629 return nil 630 }, func() { 631 resp = PaymentsResponse{} 632 }); err != nil { 633 return resp, err 634 } 635 636 // Need to swap the payments slice order if reversed order. 637 if query.Reversed { 638 for l, r := 0, len(resp.Payments)-1; l < r; l, r = l+1, r-1 { 639 resp.Payments[l], resp.Payments[r] = 640 resp.Payments[r], resp.Payments[l] 641 } 642 } 643 644 // Set the first and last index of the returned payments so that the 645 // caller can resume from this point later on. 646 if len(resp.Payments) > 0 { 647 resp.FirstIndexOffset = resp.Payments[0].SequenceNum 648 resp.LastIndexOffset = 649 resp.Payments[len(resp.Payments)-1].SequenceNum 650 } 651 652 return resp, nil 653 } 654 655 // fetchPaymentWithSequenceNumber get the payment which matches the payment hash 656 // *and* sequence number provided from the database. This is required because 657 // we previously had more than one payment per hash, so we have multiple indexes 658 // pointing to a single payment; we want to retrieve the correct one. 659 func fetchPaymentWithSequenceNumber(tx kvdb.RTx, paymentHash lntypes.Hash, 660 sequenceNumber []byte) (*MPPayment, error) { 661 662 // We can now lookup the payment keyed by its hash in 663 // the payments root bucket. 664 bucket, err := fetchPaymentBucket(tx, paymentHash) 665 if err != nil { 666 return nil, err 667 } 668 669 // A single payment hash can have multiple payments associated with it. 670 // We lookup our sequence number first, to determine whether this is 671 // the payment we are actually looking for. 672 seqBytes := bucket.Get(paymentSequenceKey) 673 if seqBytes == nil { 674 return nil, ErrNoSequenceNumber 675 } 676 677 // If this top level payment has the sequence number we are looking for, 678 // return it. 679 if bytes.Equal(seqBytes, sequenceNumber) { 680 return fetchPayment(bucket) 681 } 682 683 // If we were not looking for the top level payment, we are looking for 684 // one of our duplicate payments. We need to iterate through the seq 685 // numbers in this bucket to find the correct payments. If we do not 686 // find a duplicate payments bucket here, something is wrong. 687 dup := bucket.NestedReadBucket(duplicatePaymentsBucket) 688 if dup == nil { 689 return nil, ErrNoDuplicateBucket 690 } 691 692 var duplicatePayment *MPPayment 693 err = dup.ForEach(func(k, v []byte) error { 694 subBucket := dup.NestedReadBucket(k) 695 if subBucket == nil { 696 // We one bucket for each duplicate to be found. 697 return ErrNoDuplicateNestedBucket 698 } 699 700 seqBytes := subBucket.Get(duplicatePaymentSequenceKey) 701 if seqBytes == nil { 702 return err 703 } 704 705 // If this duplicate payment is not the sequence number we are 706 // looking for, we can continue. 707 if !bytes.Equal(seqBytes, sequenceNumber) { 708 return nil 709 } 710 711 duplicatePayment, err = fetchDuplicatePayment(subBucket) 712 if err != nil { 713 return err 714 } 715 716 return nil 717 }) 718 if err != nil { 719 return nil, err 720 } 721 722 // If none of the duplicate payments matched our sequence number, we 723 // failed to find the payment with this sequence number; something is 724 // wrong. 725 if duplicatePayment == nil { 726 return nil, ErrDuplicateNotFound 727 } 728 729 return duplicatePayment, nil 730 } 731 732 // DeletePayment deletes a payment from the DB given its payment hash. If 733 // failedHtlcsOnly is set, only failed HTLC attempts of the payment will be 734 // deleted. 735 func (d *DB) DeletePayment(paymentHash lntypes.Hash, failedHtlcsOnly bool) error { // nolint:interfacer 736 return kvdb.Update(d, func(tx kvdb.RwTx) error { 737 payments := tx.ReadWriteBucket(paymentsRootBucket) 738 if payments == nil { 739 return nil 740 } 741 742 bucket := payments.NestedReadWriteBucket(paymentHash[:]) 743 if bucket == nil { 744 return fmt.Errorf("non bucket element in payments " + 745 "bucket") 746 } 747 748 // If the status is InFlight, we cannot safely delete 749 // the payment information, so we return early. 750 paymentStatus, err := fetchPaymentStatus(bucket) 751 if err != nil { 752 return err 753 } 754 755 // If the status is InFlight, we cannot safely delete 756 // the payment information, so we return an error. 757 if paymentStatus == StatusInFlight { 758 return fmt.Errorf("payment '%v' has status InFlight "+ 759 "and therefore cannot be deleted", 760 paymentHash.String()) 761 } 762 763 // Delete the failed HTLC attempts we found. 764 if failedHtlcsOnly { 765 toDelete, err := fetchFailedHtlcKeys(bucket) 766 if err != nil { 767 return err 768 } 769 770 htlcsBucket := bucket.NestedReadWriteBucket( 771 paymentHtlcsBucket, 772 ) 773 774 for _, htlcID := range toDelete { 775 err = htlcsBucket.Delete( 776 htlcBucketKey(htlcAttemptInfoKey, htlcID), 777 ) 778 if err != nil { 779 return err 780 } 781 782 err = htlcsBucket.Delete( 783 htlcBucketKey(htlcFailInfoKey, htlcID), 784 ) 785 if err != nil { 786 return err 787 } 788 789 err = htlcsBucket.Delete( 790 htlcBucketKey(htlcSettleInfoKey, htlcID), 791 ) 792 if err != nil { 793 return err 794 } 795 } 796 797 return nil 798 } 799 800 seqNrs, err := fetchSequenceNumbers(bucket) 801 if err != nil { 802 return err 803 } 804 805 if err := payments.DeleteNestedBucket(paymentHash[:]); err != nil { 806 return err 807 } 808 809 indexBucket := tx.ReadWriteBucket(paymentsIndexBucket) 810 for _, k := range seqNrs { 811 if err := indexBucket.Delete(k); err != nil { 812 return err 813 } 814 } 815 816 return nil 817 }, func() {}) 818 } 819 820 // DeletePayments deletes all completed and failed payments from the DB. If 821 // failedOnly is set, only failed payments will be considered for deletion. If 822 // failedHtlsOnly is set, the payment itself won't be deleted, only failed HTLC 823 // attempts. 824 func (d *DB) DeletePayments(failedOnly, failedHtlcsOnly bool) error { 825 return kvdb.Update(d, func(tx kvdb.RwTx) error { 826 payments := tx.ReadWriteBucket(paymentsRootBucket) 827 if payments == nil { 828 return nil 829 } 830 831 var ( 832 // deleteBuckets is the set of payment buckets we need 833 // to delete. 834 deleteBuckets [][]byte 835 836 // deleteIndexes is the set of indexes pointing to these 837 // payments that need to be deleted. 838 deleteIndexes [][]byte 839 840 // deleteHtlcs maps a payment hash to the HTLC IDs we 841 // want to delete for that payment. 842 deleteHtlcs = make(map[lntypes.Hash][][]byte) 843 ) 844 err := payments.ForEach(func(k, _ []byte) error { 845 bucket := payments.NestedReadBucket(k) 846 if bucket == nil { 847 // We only expect sub-buckets to be found in 848 // this top-level bucket. 849 return fmt.Errorf("non bucket element in " + 850 "payments bucket") 851 } 852 853 // If the status is InFlight, we cannot safely delete 854 // the payment information, so we return early. 855 paymentStatus, err := fetchPaymentStatus(bucket) 856 if err != nil { 857 return err 858 } 859 860 // If the status is InFlight, we cannot safely delete 861 // the payment information, so we return early. 862 if paymentStatus == StatusInFlight { 863 return nil 864 } 865 866 // If we requested to only delete failed payments, we 867 // can return if this one is not. 868 if failedOnly && paymentStatus != StatusFailed { 869 return nil 870 } 871 872 // If we are only deleting failed HTLCs, fetch them. 873 if failedHtlcsOnly { 874 toDelete, err := fetchFailedHtlcKeys(bucket) 875 if err != nil { 876 return err 877 } 878 879 hash, err := lntypes.MakeHash(k) 880 if err != nil { 881 return err 882 } 883 884 deleteHtlcs[hash] = toDelete 885 886 // We return, we are only deleting attempts. 887 return nil 888 } 889 890 // Add the bucket to the set of buckets we can delete. 891 deleteBuckets = append(deleteBuckets, k) 892 893 // Get all the sequence number associated with the 894 // payment, including duplicates. 895 seqNrs, err := fetchSequenceNumbers(bucket) 896 if err != nil { 897 return err 898 } 899 900 deleteIndexes = append(deleteIndexes, seqNrs...) 901 return nil 902 }) 903 if err != nil { 904 return err 905 } 906 907 // Delete the failed HTLC attempts we found. 908 for hash, htlcIDs := range deleteHtlcs { 909 bucket := payments.NestedReadWriteBucket(hash[:]) 910 htlcsBucket := bucket.NestedReadWriteBucket( 911 paymentHtlcsBucket, 912 ) 913 914 for _, aid := range htlcIDs { 915 if err := htlcsBucket.Delete( 916 htlcBucketKey(htlcAttemptInfoKey, aid), 917 ); err != nil { 918 return err 919 } 920 921 if err := htlcsBucket.Delete( 922 htlcBucketKey(htlcFailInfoKey, aid), 923 ); err != nil { 924 return err 925 } 926 927 if err := htlcsBucket.Delete( 928 htlcBucketKey(htlcSettleInfoKey, aid), 929 ); err != nil { 930 return err 931 } 932 } 933 } 934 935 for _, k := range deleteBuckets { 936 if err := payments.DeleteNestedBucket(k); err != nil { 937 return err 938 } 939 } 940 941 // Get our index bucket and delete all indexes pointing to the 942 // payments we are deleting. 943 indexBucket := tx.ReadWriteBucket(paymentsIndexBucket) 944 for _, k := range deleteIndexes { 945 if err := indexBucket.Delete(k); err != nil { 946 return err 947 } 948 } 949 950 inflightBucket := tx.ReadWriteBucket(paymentsInflightIndexBucket) 951 if inflightBucket != nil { 952 for _, k := range deleteIndexes { 953 if err := indexBucket.Delete(k); err != nil { 954 return err 955 } 956 } 957 } 958 959 return nil 960 }, func() {}) 961 } 962 963 // fetchSequenceNumbers fetches all the sequence numbers associated with a 964 // payment, including those belonging to any duplicate payments. 965 func fetchSequenceNumbers(paymentBucket kvdb.RBucket) ([][]byte, error) { 966 seqNum := paymentBucket.Get(paymentSequenceKey) 967 if seqNum == nil { 968 return nil, errors.New("expected sequence number") 969 } 970 971 sequenceNumbers := [][]byte{seqNum} 972 973 // Get the duplicate payments bucket, if it has no duplicates, just 974 // return early with the payment sequence number. 975 duplicates := paymentBucket.NestedReadBucket(duplicatePaymentsBucket) 976 if duplicates == nil { 977 return sequenceNumbers, nil 978 } 979 980 // If we do have duplicated, they are keyed by sequence number, so we 981 // iterate through the duplicates bucket and add them to our set of 982 // sequence numbers. 983 if err := duplicates.ForEach(func(k, v []byte) error { 984 sequenceNumbers = append(sequenceNumbers, k) 985 return nil 986 }); err != nil { 987 return nil, err 988 } 989 990 return sequenceNumbers, nil 991 } 992 993 // nolint: dupl 994 func serializePaymentCreationInfo(w io.Writer, c *PaymentCreationInfo) error { 995 var scratch [8]byte 996 997 if _, err := w.Write(c.PaymentIdentifier[:]); err != nil { 998 return err 999 } 1000 1001 byteOrder.PutUint64(scratch[:], uint64(c.Value)) 1002 if _, err := w.Write(scratch[:]); err != nil { 1003 return err 1004 } 1005 1006 if err := serializeTime(w, c.CreationTime); err != nil { 1007 return err 1008 } 1009 1010 byteOrder.PutUint32(scratch[:4], uint32(len(c.PaymentRequest))) 1011 if _, err := w.Write(scratch[:4]); err != nil { 1012 return err 1013 } 1014 1015 if _, err := w.Write(c.PaymentRequest[:]); err != nil { 1016 return err 1017 } 1018 1019 return nil 1020 } 1021 1022 func deserializePaymentCreationInfo(r io.Reader) (*PaymentCreationInfo, error) { 1023 var scratch [8]byte 1024 1025 c := &PaymentCreationInfo{} 1026 1027 if _, err := io.ReadFull(r, c.PaymentIdentifier[:]); err != nil { 1028 return nil, err 1029 } 1030 1031 if _, err := io.ReadFull(r, scratch[:]); err != nil { 1032 return nil, err 1033 } 1034 c.Value = lnwire.MilliAtom(byteOrder.Uint64(scratch[:])) 1035 1036 creationTime, err := deserializeTime(r) 1037 if err != nil { 1038 return nil, err 1039 } 1040 c.CreationTime = creationTime 1041 1042 if _, err := io.ReadFull(r, scratch[:4]); err != nil { 1043 return nil, err 1044 } 1045 1046 reqLen := byteOrder.Uint32(scratch[:4]) 1047 payReq := make([]byte, reqLen) 1048 if reqLen > 0 { 1049 if _, err := io.ReadFull(r, payReq); err != nil { 1050 return nil, err 1051 } 1052 } 1053 c.PaymentRequest = payReq 1054 1055 return c, nil 1056 } 1057 1058 func serializeHTLCAttemptInfo(w io.Writer, a *HTLCAttemptInfo) error { 1059 if err := WriteElements(w, a.sessionKey); err != nil { 1060 return err 1061 } 1062 1063 if err := SerializeRoute(w, a.Route); err != nil { 1064 return err 1065 } 1066 1067 if err := serializeTime(w, a.AttemptTime); err != nil { 1068 return err 1069 } 1070 1071 // If the hash is nil we can just return. 1072 if a.Hash == nil { 1073 return nil 1074 } 1075 1076 if _, err := w.Write(a.Hash[:]); err != nil { 1077 return err 1078 } 1079 1080 return nil 1081 } 1082 1083 func deserializeHTLCAttemptInfo(r io.Reader) (*HTLCAttemptInfo, error) { 1084 a := &HTLCAttemptInfo{} 1085 err := ReadElements(r, &a.sessionKey) 1086 if err != nil { 1087 return nil, err 1088 } 1089 1090 a.Route, err = DeserializeRoute(r) 1091 if err != nil { 1092 return nil, err 1093 } 1094 1095 a.AttemptTime, err = deserializeTime(r) 1096 if err != nil { 1097 return nil, err 1098 } 1099 1100 hash := lntypes.Hash{} 1101 _, err = io.ReadFull(r, hash[:]) 1102 1103 switch { 1104 1105 // Older payment attempts wouldn't have the hash set, in which case we 1106 // can just return. 1107 case err == io.EOF, err == io.ErrUnexpectedEOF: 1108 return a, nil 1109 1110 case err != nil: 1111 return nil, err 1112 1113 default: 1114 } 1115 1116 a.Hash = &hash 1117 1118 return a, nil 1119 } 1120 1121 func serializeHop(w io.Writer, h *route.Hop) error { 1122 if err := WriteElements(w, 1123 h.PubKeyBytes[:], 1124 h.ChannelID, 1125 h.OutgoingTimeLock, 1126 h.AmtToForward, 1127 ); err != nil { 1128 return err 1129 } 1130 1131 if err := binary.Write(w, byteOrder, h.LegacyPayload); err != nil { 1132 return err 1133 } 1134 1135 // For legacy payloads, we don't need to write any TLV records, so 1136 // we'll write a zero indicating the our serialized TLV map has no 1137 // records. 1138 if h.LegacyPayload { 1139 return WriteElements(w, uint32(0)) 1140 } 1141 1142 // Gather all non-primitive TLV records so that they can be serialized 1143 // as a single blob. 1144 // 1145 // TODO(conner): add migration to unify all fields in a single TLV 1146 // blobs. The split approach will cause headaches down the road as more 1147 // fields are added, which we can avoid by having a single TLV stream 1148 // for all payload fields. 1149 var records []tlv.Record 1150 if h.MPP != nil { 1151 records = append(records, h.MPP.Record()) 1152 } 1153 1154 // Final sanity check to absolutely rule out custom records that are not 1155 // custom and write into the standard range. 1156 if err := h.CustomRecords.Validate(); err != nil { 1157 return err 1158 } 1159 1160 // Convert custom records to tlv and add to the record list. 1161 // MapToRecords sorts the list, so adding it here will keep the list 1162 // canonical. 1163 tlvRecords := tlv.MapToRecords(h.CustomRecords) 1164 records = append(records, tlvRecords...) 1165 1166 // Otherwise, we'll transform our slice of records into a map of the 1167 // raw bytes, then serialize them in-line with a length (number of 1168 // elements) prefix. 1169 mapRecords, err := tlv.RecordsToMap(records) 1170 if err != nil { 1171 return err 1172 } 1173 1174 numRecords := uint32(len(mapRecords)) 1175 if err := WriteElements(w, numRecords); err != nil { 1176 return err 1177 } 1178 1179 for recordType, rawBytes := range mapRecords { 1180 if err := WriteElements(w, recordType); err != nil { 1181 return err 1182 } 1183 1184 if err := wire.WriteVarBytes(w, 0, rawBytes); err != nil { 1185 return err 1186 } 1187 } 1188 1189 return nil 1190 } 1191 1192 // maxOnionPayloadSize is the largest Sphinx payload possible, so we don't need 1193 // to read/write a TLV stream larger than this. 1194 const maxOnionPayloadSize = 1300 1195 1196 func deserializeHop(r io.Reader) (*route.Hop, error) { 1197 h := &route.Hop{} 1198 1199 var pub []byte 1200 if err := ReadElements(r, &pub); err != nil { 1201 return nil, err 1202 } 1203 copy(h.PubKeyBytes[:], pub) 1204 1205 if err := ReadElements(r, 1206 &h.ChannelID, &h.OutgoingTimeLock, &h.AmtToForward, 1207 ); err != nil { 1208 return nil, err 1209 } 1210 1211 // TODO(roasbeef): change field to allow LegacyPayload false to be the 1212 // legacy default? 1213 err := binary.Read(r, byteOrder, &h.LegacyPayload) 1214 if err != nil { 1215 return nil, err 1216 } 1217 1218 var numElements uint32 1219 if err := ReadElements(r, &numElements); err != nil { 1220 return nil, err 1221 } 1222 1223 // If there're no elements, then we can return early. 1224 if numElements == 0 { 1225 return h, nil 1226 } 1227 1228 tlvMap := make(map[uint64][]byte) 1229 for i := uint32(0); i < numElements; i++ { 1230 var tlvType uint64 1231 if err := ReadElements(r, &tlvType); err != nil { 1232 return nil, err 1233 } 1234 1235 rawRecordBytes, err := wire.ReadVarBytes( 1236 r, 0, maxOnionPayloadSize, "tlv", 1237 ) 1238 if err != nil { 1239 return nil, err 1240 } 1241 1242 tlvMap[tlvType] = rawRecordBytes 1243 } 1244 1245 // If the MPP type is present, remove it from the generic TLV map and 1246 // parse it back into a proper MPP struct. 1247 // 1248 // TODO(conner): add migration to unify all fields in a single TLV 1249 // blobs. The split approach will cause headaches down the road as more 1250 // fields are added, which we can avoid by having a single TLV stream 1251 // for all payload fields. 1252 mppType := uint64(record.MPPOnionType) 1253 if mppBytes, ok := tlvMap[mppType]; ok { 1254 delete(tlvMap, mppType) 1255 1256 var ( 1257 mpp = &record.MPP{} 1258 mppRec = mpp.Record() 1259 r = bytes.NewReader(mppBytes) 1260 ) 1261 err := mppRec.Decode(r, uint64(len(mppBytes))) 1262 if err != nil { 1263 return nil, err 1264 } 1265 h.MPP = mpp 1266 } 1267 1268 h.CustomRecords = tlvMap 1269 1270 return h, nil 1271 } 1272 1273 // SerializeRoute serializes a route. 1274 func SerializeRoute(w io.Writer, r route.Route) error { 1275 if err := WriteElements(w, 1276 r.TotalTimeLock, r.TotalAmount, r.SourcePubKey[:], 1277 ); err != nil { 1278 return err 1279 } 1280 1281 if err := WriteElements(w, uint32(len(r.Hops))); err != nil { 1282 return err 1283 } 1284 1285 for _, h := range r.Hops { 1286 if err := serializeHop(w, h); err != nil { 1287 return err 1288 } 1289 } 1290 1291 return nil 1292 } 1293 1294 // DeserializeRoute deserializes a route. 1295 func DeserializeRoute(r io.Reader) (route.Route, error) { 1296 rt := route.Route{} 1297 if err := ReadElements(r, 1298 &rt.TotalTimeLock, &rt.TotalAmount, 1299 ); err != nil { 1300 return rt, err 1301 } 1302 1303 var pub []byte 1304 if err := ReadElements(r, &pub); err != nil { 1305 return rt, err 1306 } 1307 copy(rt.SourcePubKey[:], pub) 1308 1309 var numHops uint32 1310 if err := ReadElements(r, &numHops); err != nil { 1311 return rt, err 1312 } 1313 1314 var hops []*route.Hop 1315 for i := uint32(0); i < numHops; i++ { 1316 hop, err := deserializeHop(r) 1317 if err != nil { 1318 return rt, err 1319 } 1320 hops = append(hops, hop) 1321 } 1322 rt.Hops = hops 1323 1324 return rt, nil 1325 }