github.com/decred/dcrlnd@v0.7.6/channeldb/invoices.go (about) 1 package channeldb 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "errors" 7 "fmt" 8 "io" 9 "strings" 10 "time" 11 12 "github.com/decred/dcrlnd/feature" 13 "github.com/decred/dcrlnd/htlcswitch/hop" 14 "github.com/decred/dcrlnd/kvdb" 15 "github.com/decred/dcrlnd/lntypes" 16 "github.com/decred/dcrlnd/lnwire" 17 "github.com/decred/dcrlnd/record" 18 "github.com/decred/dcrlnd/tlv" 19 ) 20 21 var ( 22 // unknownPreimage is an all-zeroes preimage that indicates that the 23 // preimage for this invoice is not yet known. 24 unknownPreimage lntypes.Preimage 25 26 // BlankPayAddr is a sentinel payment address for legacy invoices. 27 // Invoices with this payment address are special-cased in the insertion 28 // logic to prevent being indexed in the payment address index, 29 // otherwise they would cause collisions after the first insertion. 30 BlankPayAddr [32]byte 31 32 // invoiceBucket is the name of the bucket within the database that 33 // stores all data related to invoices no matter their final state. 34 // Within the invoice bucket, each invoice is keyed by its invoice ID 35 // which is a monotonically increasing uint32. 36 invoiceBucket = []byte("invoices") 37 38 // paymentHashIndexBucket is the name of the sub-bucket within the 39 // invoiceBucket which indexes all invoices by their payment hash. The 40 // payment hash is the chainhash of the invoice's payment preimage. This 41 // index is used to detect duplicates, and also to provide a fast path 42 // for looking up incoming HTLCs to determine if we're able to settle 43 // them fully. 44 // 45 // maps: payHash => invoiceKey 46 invoiceIndexBucket = []byte("paymenthashes") 47 48 // payAddrIndexBucket is the name of the top-level bucket that maps 49 // payment addresses to their invoice number. This can be used 50 // to efficiently query or update non-legacy invoices. Note that legacy 51 // invoices will not be included in this index since they all have the 52 // same, all-zero payment address, however all newly generated invoices 53 // will end up in this index. 54 // 55 // maps: payAddr => invoiceKey 56 payAddrIndexBucket = []byte("pay-addr-index") 57 58 // setIDIndexBucket is the name of the top-level bucket that maps set 59 // ids to their invoice number. This can be used to efficiently query or 60 // update AMP invoice. Note that legacy or MPP invoices will not be 61 // included in this index, since their HTLCs do not have a set id. 62 // 63 // maps: setID => invoiceKey 64 setIDIndexBucket = []byte("set-id-index") 65 66 // numInvoicesKey is the name of key which houses the auto-incrementing 67 // invoice ID which is essentially used as a primary key. With each 68 // invoice inserted, the primary key is incremented by one. This key is 69 // stored within the invoiceIndexBucket. Within the invoiceBucket 70 // invoices are uniquely identified by the invoice ID. 71 numInvoicesKey = []byte("nik") 72 73 // addIndexBucket is an index bucket that we'll use to create a 74 // monotonically increasing set of add indexes. Each time we add a new 75 // invoice, this sequence number will be incremented and then populated 76 // within the new invoice. 77 // 78 // In addition to this sequence number, we map: 79 // 80 // addIndexNo => invoiceKey 81 addIndexBucket = []byte("invoice-add-index") 82 83 // settleIndexBucket is an index bucket that we'll use to create a 84 // monotonically increasing integer for tracking a "settle index". Each 85 // time an invoice is settled, this sequence number will be incremented 86 // as populate within the newly settled invoice. 87 // 88 // In addition to this sequence number, we map: 89 // 90 // settleIndexNo => invoiceKey 91 settleIndexBucket = []byte("invoice-settle-index") 92 93 // ErrInvoiceAlreadySettled is returned when the invoice is already 94 // settled. 95 ErrInvoiceAlreadySettled = errors.New("invoice already settled") 96 97 // ErrInvoiceAlreadyCanceled is returned when the invoice is already 98 // canceled. 99 ErrInvoiceAlreadyCanceled = errors.New("invoice already canceled") 100 101 // ErrInvoiceAlreadyAccepted is returned when the invoice is already 102 // accepted. 103 ErrInvoiceAlreadyAccepted = errors.New("invoice already accepted") 104 105 // ErrInvoiceStillOpen is returned when the invoice is still open. 106 ErrInvoiceStillOpen = errors.New("invoice still open") 107 108 // ErrInvoiceCannotOpen is returned when an attempt is made to move an 109 // invoice to the open state. 110 ErrInvoiceCannotOpen = errors.New("cannot move invoice to open") 111 112 // ErrInvoiceCannotAccept is returned when an attempt is made to accept 113 // an invoice while the invoice is not in the open state. 114 ErrInvoiceCannotAccept = errors.New("cannot accept invoice") 115 116 // ErrInvoicePreimageMismatch is returned when the preimage doesn't 117 // match the invoice hash. 118 ErrInvoicePreimageMismatch = errors.New("preimage does not match") 119 120 // ErrHTLCPreimageMissing is returned when trying to accept/settle an 121 // AMP HTLC but the HTLC-level preimage has not been set. 122 ErrHTLCPreimageMissing = errors.New("AMP htlc missing preimage") 123 124 // ErrHTLCPreimageMismatch is returned when trying to accept/settle an 125 // AMP HTLC but the HTLC-level preimage does not satisfying the 126 // HTLC-level payment hash. 127 ErrHTLCPreimageMismatch = errors.New("htlc preimage mismatch") 128 129 // ErrHTLCAlreadySettled is returned when trying to settle an invoice 130 // but HTLC already exists in the settled state. 131 ErrHTLCAlreadySettled = errors.New("htlc already settled") 132 133 // ErrInvoiceHasHtlcs is returned when attempting to insert an invoice 134 // that already has HTLCs. 135 ErrInvoiceHasHtlcs = errors.New("cannot add invoice with htlcs") 136 137 // ErrEmptyHTLCSet is returned when attempting to accept or settle and 138 // HTLC set that has no HTLCs. 139 ErrEmptyHTLCSet = errors.New("cannot settle/accept empty HTLC set") 140 141 // ErrUnexpectedInvoicePreimage is returned when an invoice-level 142 // preimage is provided when trying to settle an invoice that shouldn't 143 // have one, e.g. an AMP invoice. 144 ErrUnexpectedInvoicePreimage = errors.New( 145 "unexpected invoice preimage provided on settle", 146 ) 147 148 // ErrHTLCPreimageAlreadyExists is returned when trying to set an 149 // htlc-level preimage but one is already known. 150 ErrHTLCPreimageAlreadyExists = errors.New( 151 "htlc-level preimage already exists", 152 ) 153 ) 154 155 // ErrDuplicateSetID is an error returned when attempting to adding an AMP HTLC 156 // to an invoice, but another invoice is already indexed by the same set id. 157 type ErrDuplicateSetID struct { 158 setID [32]byte 159 } 160 161 // Error returns a human-readable description of ErrDuplicateSetID. 162 func (e ErrDuplicateSetID) Error() string { 163 return fmt.Sprintf("invoice with set_id=%x already exists", e.setID) 164 } 165 166 const ( 167 // MaxMemoSize is maximum size of the memo field within invoices stored 168 // in the database. 169 MaxMemoSize = 1024 170 171 // MaxPaymentRequestSize is the max size of a payment request for 172 // this invoice. 173 // TODO(halseth): determine the max length payment request when field 174 // lengths are final. 175 MaxPaymentRequestSize = 4096 176 177 // A set of tlv type definitions used to serialize invoice htlcs to the 178 // database. 179 // 180 // NOTE: A migration should be added whenever this list changes. This 181 // prevents against the database being rolled back to an older 182 // format where the surrounding logic might assume a different set of 183 // fields are known. 184 chanIDType tlv.Type = 1 185 htlcIDType tlv.Type = 3 186 amtType tlv.Type = 5 187 acceptHeightType tlv.Type = 7 188 acceptTimeType tlv.Type = 9 189 resolveTimeType tlv.Type = 11 190 expiryHeightType tlv.Type = 13 191 htlcStateType tlv.Type = 15 192 mppTotalAmtType tlv.Type = 17 193 htlcAMPType tlv.Type = 19 194 htlcHashType tlv.Type = 21 195 htlcPreimageType tlv.Type = 23 196 197 // A set of tlv type definitions used to serialize invoice bodiees. 198 // 199 // NOTE: A migration should be added whenever this list changes. This 200 // prevents against the database being rolled back to an older 201 // format where the surrounding logic might assume a different set of 202 // fields are known. 203 memoType tlv.Type = 0 204 payReqType tlv.Type = 1 205 createTimeType tlv.Type = 2 206 settleTimeType tlv.Type = 3 207 addIndexType tlv.Type = 4 208 settleIndexType tlv.Type = 5 209 preimageType tlv.Type = 6 210 valueType tlv.Type = 7 211 cltvDeltaType tlv.Type = 8 212 expiryType tlv.Type = 9 213 paymentAddrType tlv.Type = 10 214 featuresType tlv.Type = 11 215 invStateType tlv.Type = 12 216 amtPaidType tlv.Type = 13 217 hodlInvoiceType tlv.Type = 14 218 invoiceAmpStateType tlv.Type = 15 219 220 // A set of tlv type definitions used to serialize the invoice AMP 221 // state along-side the main invoice body. 222 ampStateSetIDType tlv.Type = 0 223 ampStateHtlcStateType tlv.Type = 1 224 ampStateSettleIndexType tlv.Type = 2 225 ampStateSettleDateType tlv.Type = 3 226 ampStateCircuitKeysType tlv.Type = 4 227 ampStateAmtPaidType tlv.Type = 5 228 ) 229 230 // RefModifier is a modification on top of a base invoice ref. It allows the 231 // caller to opt to skip out on HTLCs for a given payAddr, or only return the 232 // set of specified HTLCs for a given setID. 233 type RefModifier uint8 234 235 const ( 236 // DefaultModifier is the base modifier that doesn't change any behavior. 237 DefaultModifier RefModifier = iota 238 239 // HtlcSetOnlyModifier can only be used with a setID based invoice ref, and 240 // specifies that only the set of HTLCs related to that setID are to be 241 // returned. 242 HtlcSetOnlyModifier 243 244 // HtlcSetOnlyModifier can only be used with a payAddr based invoice ref, 245 // and specifies that the returned invoice shouldn't include any HTLCs at 246 // all. 247 HtlcSetBlankModifier 248 ) 249 250 // InvoiceRef is a composite identifier for invoices. Invoices can be referenced 251 // by various combinations of payment hash and payment addr, in certain contexts 252 // only some of these are known. An InvoiceRef and its constructors thus 253 // encapsulate the valid combinations of query parameters that can be supplied 254 // to LookupInvoice and UpdateInvoice. 255 type InvoiceRef struct { 256 // payHash is the payment hash of the target invoice. All invoices are 257 // currently indexed by payment hash. This value will be used as a 258 // fallback when no payment address is known. 259 payHash *lntypes.Hash 260 261 // payAddr is the payment addr of the target invoice. Newer invoices 262 // (0.11 and up) are indexed by payment address in addition to payment 263 // hash, but pre 0.8 invoices do not have one at all. When this value is 264 // known it will be used as the primary identifier, falling back to 265 // payHash if no value is known. 266 payAddr *[32]byte 267 268 // setID is the optional set id for an AMP payment. This can be used to 269 // lookup or update the invoice knowing only this value. Queries by set 270 // id are only used to facilitate user-facing requests, e.g. lookup, 271 // settle or cancel an AMP invoice. The regular update flow from the 272 // invoice registry will always query for the invoice by 273 // payHash+payAddr. 274 setID *[32]byte 275 276 // refModifier allows an invoice ref to include or exclude specific 277 // HTLC sets based on the payAddr or setId. 278 refModifier RefModifier 279 } 280 281 // InvoiceRefByHash creates an InvoiceRef that queries for an invoice only by 282 // its payment hash. 283 func InvoiceRefByHash(payHash lntypes.Hash) InvoiceRef { 284 return InvoiceRef{ 285 payHash: &payHash, 286 } 287 } 288 289 // InvoiceRefByHashAndAddr creates an InvoiceRef that first queries for an 290 // invoice by the provided payment address, falling back to the payment hash if 291 // the payment address is unknown. 292 func InvoiceRefByHashAndAddr(payHash lntypes.Hash, 293 payAddr [32]byte) InvoiceRef { 294 295 return InvoiceRef{ 296 payHash: &payHash, 297 payAddr: &payAddr, 298 } 299 } 300 301 // InvoiceRefByAddr creates an InvoiceRef that queries the payment addr index 302 // for an invoice with the provided payment address. 303 func InvoiceRefByAddr(addr [32]byte) InvoiceRef { 304 return InvoiceRef{ 305 payAddr: &addr, 306 } 307 } 308 309 // InvoiceRefByAddrBlankHtlc creates an InvoiceRef that queries the payment addr index 310 // for an invoice with the provided payment address, but excludes any of the 311 // core HTLC information. 312 func InvoiceRefByAddrBlankHtlc(addr [32]byte) InvoiceRef { 313 return InvoiceRef{ 314 payAddr: &addr, 315 refModifier: HtlcSetBlankModifier, 316 } 317 } 318 319 // InvoiceRefBySetID creates an InvoiceRef that queries the set id index for an 320 // invoice with the provided setID. If the invoice is not found, the query will 321 // not fallback to payHash or payAddr. 322 func InvoiceRefBySetID(setID [32]byte) InvoiceRef { 323 return InvoiceRef{ 324 setID: &setID, 325 } 326 } 327 328 // InvoiceRefBySetIDFiltered is similar to the InvoiceRefBySetID identifier, 329 // but it specifies that the returned set of HTLCs should be filtered to only 330 // include HTLCs that are part of that set. 331 func InvoiceRefBySetIDFiltered(setID [32]byte) InvoiceRef { 332 return InvoiceRef{ 333 setID: &setID, 334 refModifier: HtlcSetOnlyModifier, 335 } 336 } 337 338 // PayHash returns the optional payment hash of the target invoice. 339 // 340 // NOTE: This value may be nil. 341 func (r InvoiceRef) PayHash() *lntypes.Hash { 342 if r.payHash != nil { 343 hash := *r.payHash 344 return &hash 345 } 346 return nil 347 } 348 349 // PayAddr returns the optional payment address of the target invoice. 350 // 351 // NOTE: This value may be nil. 352 func (r InvoiceRef) PayAddr() *[32]byte { 353 if r.payAddr != nil { 354 addr := *r.payAddr 355 return &addr 356 } 357 return nil 358 } 359 360 // SetID returns the optional set id of the target invoice. 361 // 362 // NOTE: This value may be nil. 363 func (r InvoiceRef) SetID() *[32]byte { 364 if r.setID != nil { 365 id := *r.setID 366 return &id 367 } 368 return nil 369 } 370 371 // Modifier defines the set of available modifications to the base invoice ref 372 // look up that are available. 373 func (r InvoiceRef) Modifier() RefModifier { 374 return r.refModifier 375 } 376 377 // String returns a human-readable representation of an InvoiceRef. 378 func (r InvoiceRef) String() string { 379 var ids []string 380 if r.payHash != nil { 381 ids = append(ids, fmt.Sprintf("pay_hash=%v", *r.payHash)) 382 } 383 if r.payAddr != nil { 384 ids = append(ids, fmt.Sprintf("pay_addr=%x", *r.payAddr)) 385 } 386 if r.setID != nil { 387 ids = append(ids, fmt.Sprintf("set_id=%x", *r.setID)) 388 } 389 return fmt.Sprintf("(%s)", strings.Join(ids, ", ")) 390 } 391 392 // ContractState describes the state the invoice is in. 393 type ContractState uint8 394 395 const ( 396 // ContractOpen means the invoice has only been created. 397 ContractOpen ContractState = 0 398 399 // ContractSettled means the htlc is settled and the invoice has been paid. 400 ContractSettled ContractState = 1 401 402 // ContractCanceled means the invoice has been canceled. 403 ContractCanceled ContractState = 2 404 405 // ContractAccepted means the HTLC has been accepted but not settled yet. 406 ContractAccepted ContractState = 3 407 ) 408 409 // String returns a human readable identifier for the ContractState type. 410 func (c ContractState) String() string { 411 switch c { 412 case ContractOpen: 413 return "Open" 414 case ContractSettled: 415 return "Settled" 416 case ContractCanceled: 417 return "Canceled" 418 case ContractAccepted: 419 return "Accepted" 420 } 421 422 return "Unknown" 423 } 424 425 // IsFinal returns a boolean indicating whether an invoice state is final 426 func (c ContractState) IsFinal() bool { 427 return c == ContractSettled || c == ContractCanceled 428 } 429 430 // ContractTerm is a companion struct to the Invoice struct. This struct houses 431 // the necessary conditions required before the invoice can be considered fully 432 // settled by the payee. 433 type ContractTerm struct { 434 // FinalCltvDelta is the minimum required number of blocks before htlc 435 // expiry when the invoice is accepted. 436 FinalCltvDelta int32 437 438 // Expiry defines how long after creation this invoice should expire. 439 Expiry time.Duration 440 441 // PaymentPreimage is the preimage which is to be revealed in the 442 // occasion that an HTLC paying to the hash of this preimage is 443 // extended. Set to nil if the preimage isn't known yet. 444 PaymentPreimage *lntypes.Preimage 445 446 // Value is the expected amount of milli-atoms to be paid to an HTLC 447 // which can be satisfied by the above preimage. 448 Value lnwire.MilliAtom 449 450 // PaymentAddr is a randomly generated value include in the MPP record 451 // by the sender to prevent probing of the receiver. 452 PaymentAddr [32]byte 453 454 // Features is the feature vectors advertised on the payment request. 455 Features *lnwire.FeatureVector 456 } 457 458 // String returns a human-readable description of the prominent contract terms. 459 func (c ContractTerm) String() string { 460 return fmt.Sprintf("amt=%v, expiry=%v, final_cltv_delta=%v", c.Value, 461 c.Expiry, c.FinalCltvDelta) 462 } 463 464 // SetID is the extra unique tuple item for AMP invoices. In addition to 465 // setting a payment address, each repeated payment to an AMP invoice will also 466 // contain a set ID as well. 467 type SetID [32]byte 468 469 // InvoiceStateAMP is a struct that associates the current state of an AMP 470 // invoice identified by its set ID along with the set of invoices identified 471 // by the circuit key. This allows callers to easily look up the latest state 472 // of an AMP "sub-invoice" and also look up the invoice HLTCs themselves in the 473 // greater HTLC map index. 474 type InvoiceStateAMP struct { 475 // State is the state of this sub-AMP invoice. 476 State HtlcState 477 478 // SettleIndex indicates the location in the settle index that 479 // references this instance of InvoiceStateAMP, but only if 480 // this value is set (non-zero), and State is HtlcStateSettled. 481 SettleIndex uint64 482 483 // SettleDate is the date that the setID was settled. 484 SettleDate time.Time 485 486 // InvoiceKeys is the set of circuit keys that can be used to locate 487 // the invoices for a given set ID. 488 InvoiceKeys map[CircuitKey]struct{} 489 490 // AmtPaid is the total amount that was paid in the AMP sub-invoice. 491 // Fetching the full HTLC/invoice state allows one to extract the 492 // custom records as well as the break down of the payment splits used 493 // when paying. 494 AmtPaid lnwire.MilliAtom 495 } 496 497 // AMPInvoiceState represents a type that stores metadata related to the set of 498 // settled AMP "sub-invoices". 499 type AMPInvoiceState map[SetID]InvoiceStateAMP 500 501 // recordSize returns the amount of bytes this TLV record will occupy when 502 // encoded. 503 func (a *AMPInvoiceState) recordSize() uint64 { 504 var ( 505 b bytes.Buffer 506 buf [8]byte 507 ) 508 509 // We know that encoding works since the tests pass in the build this file 510 // is checked into, so we'll simplify things and simply encode it ourselves 511 // then report the total amount of bytes used. 512 if err := ampStateEncoder(&b, a, &buf); err != nil { 513 // This should never error out, but we log it just in case it 514 // does. 515 log.Errorf("encoding the amp invoice state failed: %v", err) 516 } 517 518 return uint64(len(b.Bytes())) 519 } 520 521 // Invoice is a payment invoice generated by a payee in order to request 522 // payment for some good or service. The inclusion of invoices within Lightning 523 // creates a payment work flow for merchants very similar to that of the 524 // existing financial system within PayPal, etc. Invoices are added to the 525 // database when a payment is requested, then can be settled manually once the 526 // payment is received at the upper layer. For record keeping purposes, 527 // invoices are never deleted from the database, instead a bit is toggled 528 // denoting the invoice has been fully settled. Within the database, all 529 // invoices must have a unique payment hash which is generated by taking the 530 // chainhash of the payment preimage. 531 type Invoice struct { 532 // Memo is an optional memo to be stored along side an invoice. The 533 // memo may contain further details pertaining to the invoice itself, 534 // or any other message which fits within the size constraints. 535 Memo []byte 536 537 // PaymentRequest is the encoded payment request for this invoice. For 538 // spontaneous (keysend) payments, this field will be empty. 539 PaymentRequest []byte 540 541 // CreationDate is the exact time the invoice was created. 542 CreationDate time.Time 543 544 // SettleDate is the exact time the invoice was settled. 545 SettleDate time.Time 546 547 // Terms are the contractual payment terms of the invoice. Once all the 548 // terms have been satisfied by the payer, then the invoice can be 549 // considered fully fulfilled. 550 // 551 // TODO(roasbeef): later allow for multiple terms to fulfill the final 552 // invoice: payment fragmentation, etc. 553 Terms ContractTerm 554 555 // AddIndex is an auto-incrementing integer that acts as a 556 // monotonically increasing sequence number for all invoices created. 557 // Clients can then use this field as a "checkpoint" of sorts when 558 // implementing a streaming RPC to notify consumers of instances where 559 // an invoice has been added before they re-connected. 560 // 561 // NOTE: This index starts at 1. 562 AddIndex uint64 563 564 // SettleIndex is an auto-incrementing integer that acts as a 565 // monotonically increasing sequence number for all settled invoices. 566 // Clients can then use this field as a "checkpoint" of sorts when 567 // implementing a streaming RPC to notify consumers of instances where 568 // an invoice has been settled before they re-connected. 569 // 570 // NOTE: This index starts at 1. 571 SettleIndex uint64 572 573 // State describes the state the invoice is in. This is the global 574 // state of the invoice which may remain open even when a series of 575 // sub-invoices for this invoice has been settled. 576 State ContractState 577 578 // AmtPaid is the final amount that we ultimately accepted for pay for 579 // this invoice. We specify this value independently as it's possible 580 // that the invoice originally didn't specify an amount, or the sender 581 // overpaid. 582 AmtPaid lnwire.MilliAtom 583 584 // Htlcs records all htlcs that paid to this invoice. Some of these 585 // htlcs may have been marked as canceled. 586 Htlcs map[CircuitKey]*InvoiceHTLC 587 588 // AMPState describes the state of any related sub-invoices AMP to this 589 // greater invoice. A sub-invoice is defined by a set of HTLCs with the 590 // same set ID that attempt to make one time or recurring payments to 591 // this greater invoice. It's possible for a sub-invoice to be canceled 592 // or settled, but the greater invoice still open. 593 AMPState AMPInvoiceState 594 595 // HodlInvoice indicates whether the invoice should be held in the 596 // Accepted state or be settled right away. 597 HodlInvoice bool 598 } 599 600 // HTLCSet returns the set of HTLCs belonging to setID and in the provided 601 // state. Passing a nil setID will return all HTLCs in the provided state in the 602 // case of legacy or MPP, and no HTLCs in the case of AMP. Otherwise, the 603 // returned set will be filtered by the populated setID which is used to 604 // retrieve AMP HTLC sets. 605 func (i *Invoice) HTLCSet(setID *[32]byte, state HtlcState) map[CircuitKey]*InvoiceHTLC { 606 htlcSet := make(map[CircuitKey]*InvoiceHTLC) 607 for key, htlc := range i.Htlcs { 608 // Only add HTLCs that are in the requested HtlcState. 609 if htlc.State != state { 610 continue 611 } 612 613 if !htlc.IsInHTLCSet(setID) { 614 continue 615 } 616 617 htlcSet[key] = htlc 618 } 619 620 return htlcSet 621 } 622 623 // HTLCSetCompliment returns the set of all HTLCs not belonging to setID that 624 // are in the target state. Passing a nil setID will return no invoices, since 625 // all MPP HTLCs are part of the same HTLC set. 626 func (i *Invoice) HTLCSetCompliment(setID *[32]byte, 627 state HtlcState) map[CircuitKey]*InvoiceHTLC { 628 629 htlcSet := make(map[CircuitKey]*InvoiceHTLC) 630 for key, htlc := range i.Htlcs { 631 // Only add HTLCs that are in the requested HtlcState. 632 if htlc.State != state { 633 continue 634 } 635 636 // We are constructing the compliment, so filter anything that 637 // matches this set id. 638 if htlc.IsInHTLCSet(setID) { 639 continue 640 } 641 642 htlcSet[key] = htlc 643 } 644 645 return htlcSet 646 } 647 648 // HtlcState defines the states an htlc paying to an invoice can be in. 649 type HtlcState uint8 650 651 const ( 652 // HtlcStateAccepted indicates the htlc is locked-in, but not resolved. 653 HtlcStateAccepted HtlcState = iota 654 655 // HtlcStateCanceled indicates the htlc is canceled back to the 656 // sender. 657 HtlcStateCanceled 658 659 // HtlcStateSettled indicates the htlc is settled. 660 HtlcStateSettled 661 ) 662 663 // InvoiceHTLC contains details about an htlc paying to this invoice. 664 type InvoiceHTLC struct { 665 // Amt is the amount that is carried by this htlc. 666 Amt lnwire.MilliAtom 667 668 // MppTotalAmt is a field for mpp that indicates the expected total 669 // amount. 670 MppTotalAmt lnwire.MilliAtom 671 672 // AcceptHeight is the block height at which the invoice registry 673 // decided to accept this htlc as a payment to the invoice. At this 674 // height, the invoice cltv delay must have been met. 675 AcceptHeight uint32 676 677 // AcceptTime is the wall clock time at which the invoice registry 678 // decided to accept the htlc. 679 AcceptTime time.Time 680 681 // ResolveTime is the wall clock time at which the invoice registry 682 // decided to settle the htlc. 683 ResolveTime time.Time 684 685 // Expiry is the expiry height of this htlc. 686 Expiry uint32 687 688 // State indicates the state the invoice htlc is currently in. A 689 // canceled htlc isn't just removed from the invoice htlcs map, because 690 // we need AcceptHeight to properly cancel the htlc back. 691 State HtlcState 692 693 // CustomRecords contains the custom key/value pairs that accompanied 694 // the htlc. 695 CustomRecords record.CustomSet 696 697 // AMP encapsulates additional data relevant to AMP HTLCs. This includes 698 // the AMP onion record, in addition to the HTLC's payment hash and 699 // preimage since these are unique to each AMP HTLC, and not the invoice 700 // as a whole. 701 // 702 // NOTE: This value will only be set for AMP HTLCs. 703 AMP *InvoiceHtlcAMPData 704 } 705 706 // Copy makes a deep copy of the target InvoiceHTLC. 707 func (h *InvoiceHTLC) Copy() *InvoiceHTLC { 708 result := *h 709 710 // Make a copy of the CustomSet map. 711 result.CustomRecords = make(record.CustomSet) 712 for k, v := range h.CustomRecords { 713 result.CustomRecords[k] = v 714 } 715 716 result.AMP = h.AMP.Copy() 717 718 return &result 719 } 720 721 // IsInHTLCSet returns true if this HTLC is part an HTLC set. If nil is passed, 722 // this method returns true if this is an MPP HTLC. Otherwise, it only returns 723 // true if the AMP HTLC's set id matches the populated setID. 724 func (h *InvoiceHTLC) IsInHTLCSet(setID *[32]byte) bool { 725 wantAMPSet := setID != nil 726 isAMPHtlc := h.AMP != nil 727 728 // Non-AMP HTLCs cannot be part of AMP HTLC sets, and vice versa. 729 if wantAMPSet != isAMPHtlc { 730 return false 731 } 732 733 // Skip AMP HTLCs that have differing set ids. 734 if isAMPHtlc && *setID != h.AMP.Record.SetID() { 735 return false 736 } 737 738 return true 739 } 740 741 // InvoiceHtlcAMPData is a struct hodling the additional metadata stored for 742 // each received AMP HTLC. This includes the AMP onion record, in addition to 743 // the HTLC's payment hash and preimage. 744 type InvoiceHtlcAMPData struct { 745 // AMP is a copy of the AMP record presented in the onion payload 746 // containing the information necessary to correlate and settle a 747 // spontaneous HTLC set. Newly accepted legacy keysend payments will 748 // also have this field set as we automatically promote them into an AMP 749 // payment for internal processing. 750 Record record.AMP 751 752 // Hash is an HTLC-level payment hash that is stored only for AMP 753 // payments. This is done because an AMP HTLC will carry a different 754 // payment hash from the invoice it might be satisfying, so we track the 755 // payment hashes individually to able to compute whether or not the 756 // reconstructed preimage correctly matches the HTLC's hash. 757 Hash lntypes.Hash 758 759 // Preimage is an HTLC-level preimage that satisfies the AMP HTLC's 760 // Hash. The preimage will be be derived either from secret share 761 // reconstruction of the shares in the AMP payload. 762 // 763 // NOTE: Preimage will only be present once the HTLC is in 764 // HtlcStateSettled. 765 Preimage *lntypes.Preimage 766 } 767 768 // Copy returns a deep copy of the InvoiceHtlcAMPData. 769 func (d *InvoiceHtlcAMPData) Copy() *InvoiceHtlcAMPData { 770 if d == nil { 771 return nil 772 } 773 774 var preimage *lntypes.Preimage 775 if d.Preimage != nil { 776 pimg := *d.Preimage 777 preimage = &pimg 778 } 779 780 return &InvoiceHtlcAMPData{ 781 Record: d.Record, 782 Hash: d.Hash, 783 Preimage: preimage, 784 } 785 } 786 787 // HtlcAcceptDesc describes the details of a newly accepted htlc. 788 type HtlcAcceptDesc struct { 789 // AcceptHeight is the block height at which this htlc was accepted. 790 AcceptHeight int32 791 792 // Amt is the amount that is carried by this htlc. 793 Amt lnwire.MilliAtom 794 795 // MppTotalAmt is a field for mpp that indicates the expected total 796 // amount. 797 MppTotalAmt lnwire.MilliAtom 798 799 // Expiry is the expiry height of this htlc. 800 Expiry uint32 801 802 // CustomRecords contains the custom key/value pairs that accompanied 803 // the htlc. 804 CustomRecords record.CustomSet 805 806 // AMP encapsulates additional data relevant to AMP HTLCs. This includes 807 // the AMP onion record, in addition to the HTLC's payment hash and 808 // preimage since these are unique to each AMP HTLC, and not the invoice 809 // as a whole. 810 // 811 // NOTE: This value will only be set for AMP HTLCs. 812 AMP *InvoiceHtlcAMPData 813 } 814 815 // InvoiceUpdateDesc describes the changes that should be applied to the 816 // invoice. 817 type InvoiceUpdateDesc struct { 818 // State is the new state that this invoice should progress to. If nil, 819 // the state is left unchanged. 820 State *InvoiceStateUpdateDesc 821 822 // CancelHtlcs describes the htlcs that need to be canceled. 823 CancelHtlcs map[CircuitKey]struct{} 824 825 // AddHtlcs describes the newly accepted htlcs that need to be added to 826 // the invoice. 827 AddHtlcs map[CircuitKey]*HtlcAcceptDesc 828 829 // SetID is an optional set ID for AMP invoices that allows operations 830 // to be more efficient by ensuring we don't need to read out the 831 // entire HTLC set each timee an HTLC is to be cancelled. 832 SetID *SetID 833 } 834 835 // InvoiceStateUpdateDesc describes an invoice-level state transition. 836 type InvoiceStateUpdateDesc struct { 837 // NewState is the new state that this invoice should progress to. 838 NewState ContractState 839 840 // Preimage must be set to the preimage when NewState is settled. 841 Preimage *lntypes.Preimage 842 843 // HTLCPreimages set the HTLC-level preimages stored for AMP HTLCs. 844 // These are only learned when settling the invoice as a whole. Must be 845 // set when settling an invoice with non-nil SetID. 846 HTLCPreimages map[CircuitKey]lntypes.Preimage 847 848 // SetID identifies a specific set of HTLCs destined for the same 849 // invoice as part of a larger AMP payment. This value will be nil for 850 // legacy or MPP payments. 851 SetID *[32]byte 852 } 853 854 // InvoiceUpdateCallback is a callback used in the db transaction to update the 855 // invoice. 856 type InvoiceUpdateCallback = func(invoice *Invoice) (*InvoiceUpdateDesc, error) 857 858 func validateInvoice(i *Invoice, paymentHash lntypes.Hash) error { 859 // Avoid conflicts with all-zeroes magic value in the database. 860 if paymentHash == unknownPreimage.Hash() { 861 return fmt.Errorf("cannot use hash of all-zeroes preimage") 862 } 863 864 if len(i.Memo) > MaxMemoSize { 865 return fmt.Errorf("max length a memo is %v, and invoice "+ 866 "of length %v was provided", MaxMemoSize, len(i.Memo)) 867 } 868 if len(i.PaymentRequest) > MaxPaymentRequestSize { 869 return fmt.Errorf("max length of payment request is %v, length "+ 870 "provided was %v", MaxPaymentRequestSize, 871 len(i.PaymentRequest)) 872 } 873 if i.Terms.Features == nil { 874 return errors.New("invoice must have a feature vector") 875 } 876 877 err := feature.ValidateDeps(i.Terms.Features) 878 if err != nil { 879 return err 880 } 881 882 // AMP invoices and hodl invoices are allowed to have no preimage 883 // specified. 884 isAMP := i.Terms.Features.HasFeature( 885 lnwire.AMPOptional, 886 ) 887 if i.Terms.PaymentPreimage == nil && !(i.HodlInvoice || isAMP) { 888 return errors.New("non-hodl invoices must have a preimage") 889 } 890 891 if len(i.Htlcs) > 0 { 892 return ErrInvoiceHasHtlcs 893 } 894 895 return nil 896 } 897 898 // IsPending returns ture if the invoice is in ContractOpen state. 899 func (i *Invoice) IsPending() bool { 900 return i.State == ContractOpen || i.State == ContractAccepted 901 } 902 903 // AddInvoice inserts the targeted invoice into the database. If the invoice has 904 // *any* payment hashes which already exists within the database, then the 905 // insertion will be aborted and rejected due to the strict policy banning any 906 // duplicate payment hashes. A side effect of this function is that it sets 907 // AddIndex on newInvoice. 908 func (d *DB) AddInvoice(newInvoice *Invoice, paymentHash lntypes.Hash) ( 909 uint64, error) { 910 911 if err := validateInvoice(newInvoice, paymentHash); err != nil { 912 return 0, err 913 } 914 915 var invoiceAddIndex uint64 916 err := kvdb.Update(d, func(tx kvdb.RwTx) error { 917 invoices, err := tx.CreateTopLevelBucket(invoiceBucket) 918 if err != nil { 919 return err 920 } 921 922 invoiceIndex, err := invoices.CreateBucketIfNotExists( 923 invoiceIndexBucket, 924 ) 925 if err != nil { 926 return err 927 } 928 addIndex, err := invoices.CreateBucketIfNotExists( 929 addIndexBucket, 930 ) 931 if err != nil { 932 return err 933 } 934 935 // Ensure that an invoice an identical payment hash doesn't 936 // already exist within the index. 937 if invoiceIndex.Get(paymentHash[:]) != nil { 938 return ErrDuplicateInvoice 939 } 940 941 // Check that we aren't inserting an invoice with a duplicate 942 // payment address. The all-zeros payment address is 943 // special-cased to support legacy keysend invoices which don't 944 // assign one. This is safe since later we also will avoid 945 // indexing them and avoid collisions. 946 payAddrIndex := tx.ReadWriteBucket(payAddrIndexBucket) 947 if newInvoice.Terms.PaymentAddr != BlankPayAddr { 948 if payAddrIndex.Get(newInvoice.Terms.PaymentAddr[:]) != nil { 949 return ErrDuplicatePayAddr 950 } 951 } 952 953 // If the current running payment ID counter hasn't yet been 954 // created, then create it now. 955 var invoiceNum uint32 956 invoiceCounter := invoiceIndex.Get(numInvoicesKey) 957 if invoiceCounter == nil { 958 var scratch [4]byte 959 byteOrder.PutUint32(scratch[:], invoiceNum) 960 err := invoiceIndex.Put(numInvoicesKey, scratch[:]) 961 if err != nil { 962 return err 963 } 964 } else { 965 invoiceNum = byteOrder.Uint32(invoiceCounter) 966 } 967 968 newIndex, err := putInvoice( 969 invoices, invoiceIndex, payAddrIndex, addIndex, 970 newInvoice, invoiceNum, paymentHash, 971 ) 972 if err != nil { 973 return err 974 } 975 976 invoiceAddIndex = newIndex 977 return nil 978 }, func() { 979 invoiceAddIndex = 0 980 }) 981 if err != nil { 982 return 0, err 983 } 984 985 return invoiceAddIndex, err 986 } 987 988 // InvoicesAddedSince can be used by callers to seek into the event time series 989 // of all the invoices added in the database. The specified sinceAddIndex 990 // should be the highest add index that the caller knows of. This method will 991 // return all invoices with an add index greater than the specified 992 // sinceAddIndex. 993 // 994 // NOTE: The index starts from 1, as a result. We enforce that specifying a 995 // value below the starting index value is a noop. 996 func (d *DB) InvoicesAddedSince(sinceAddIndex uint64) ([]Invoice, error) { 997 var newInvoices []Invoice 998 999 // If an index of zero was specified, then in order to maintain 1000 // backwards compat, we won't send out any new invoices. 1001 if sinceAddIndex == 0 { 1002 return newInvoices, nil 1003 } 1004 1005 var startIndex [8]byte 1006 byteOrder.PutUint64(startIndex[:], sinceAddIndex) 1007 1008 err := kvdb.View(d, func(tx kvdb.RTx) error { 1009 invoices := tx.ReadBucket(invoiceBucket) 1010 if invoices == nil { 1011 return nil 1012 } 1013 1014 addIndex := invoices.NestedReadBucket(addIndexBucket) 1015 if addIndex == nil { 1016 return nil 1017 } 1018 1019 // We'll now run through each entry in the add index starting 1020 // at our starting index. We'll continue until we reach the 1021 // very end of the current key space. 1022 invoiceCursor := addIndex.ReadCursor() 1023 1024 // We'll seek to the starting index, then manually advance the 1025 // cursor in order to skip the entry with the since add index. 1026 invoiceCursor.Seek(startIndex[:]) 1027 addSeqNo, invoiceKey := invoiceCursor.Next() 1028 1029 for ; addSeqNo != nil && bytes.Compare(addSeqNo, startIndex[:]) > 0; addSeqNo, invoiceKey = invoiceCursor.Next() { 1030 1031 // For each key found, we'll look up the actual 1032 // invoice, then accumulate it into our return value. 1033 invoice, err := fetchInvoice(invoiceKey, invoices) 1034 if err != nil { 1035 return err 1036 } 1037 1038 newInvoices = append(newInvoices, invoice) 1039 } 1040 1041 return nil 1042 }, func() { 1043 newInvoices = nil 1044 }) 1045 if err != nil { 1046 return nil, err 1047 } 1048 1049 return newInvoices, nil 1050 } 1051 1052 // LookupInvoice attempts to look up an invoice according to its 32 byte 1053 // payment hash. If an invoice which can settle the HTLC identified by the 1054 // passed payment hash isn't found, then an error is returned. Otherwise, the 1055 // full invoice is returned. Before setting the incoming HTLC, the values 1056 // SHOULD be checked to ensure the payer meets the agreed upon contractual 1057 // terms of the payment. 1058 func (d *DB) LookupInvoice(ref InvoiceRef) (Invoice, error) { 1059 var invoice Invoice 1060 err := kvdb.View(d, func(tx kvdb.RTx) error { 1061 invoices := tx.ReadBucket(invoiceBucket) 1062 if invoices == nil { 1063 return ErrNoInvoicesCreated 1064 } 1065 invoiceIndex := invoices.NestedReadBucket(invoiceIndexBucket) 1066 if invoiceIndex == nil { 1067 return ErrNoInvoicesCreated 1068 } 1069 payAddrIndex := tx.ReadBucket(payAddrIndexBucket) 1070 setIDIndex := tx.ReadBucket(setIDIndexBucket) 1071 1072 // Retrieve the invoice number for this invoice using 1073 // the provided invoice reference. 1074 invoiceNum, err := fetchInvoiceNumByRef( 1075 invoiceIndex, payAddrIndex, setIDIndex, ref, 1076 ) 1077 if err != nil { 1078 return err 1079 } 1080 1081 var setID *SetID 1082 switch { 1083 // If this is a payment address ref, and the blank modified was 1084 // specified, then we'll use the zero set ID to indicate that 1085 // we won't want any HTLCs returned. 1086 case ref.PayAddr() != nil && ref.Modifier() == HtlcSetBlankModifier: 1087 var zeroSetID SetID 1088 setID = &zeroSetID 1089 1090 // If this is a set ID ref, and the htlc set only modified was 1091 // specified, then we'll pass through the specified setID so 1092 // only that will be returned. 1093 case ref.SetID() != nil && ref.Modifier() == HtlcSetOnlyModifier: 1094 setID = (*SetID)(ref.SetID()) 1095 } 1096 1097 // An invoice was found, retrieve the remainder of the invoice 1098 // body. 1099 i, err := fetchInvoice(invoiceNum, invoices, setID) 1100 if err != nil { 1101 return err 1102 } 1103 invoice = i 1104 1105 return nil 1106 }, func() {}) 1107 if err != nil { 1108 return invoice, err 1109 } 1110 1111 return invoice, nil 1112 } 1113 1114 // fetchInvoiceNumByRef retrieve the invoice number for the provided invoice 1115 // reference. The payment address will be treated as the primary key, falling 1116 // back to the payment hash if nothing is found for the payment address. An 1117 // error is returned if the invoice is not found. 1118 func fetchInvoiceNumByRef(invoiceIndex, payAddrIndex, setIDIndex kvdb.RBucket, 1119 ref InvoiceRef) ([]byte, error) { 1120 1121 // If the set id is present, we only consult the set id index for this 1122 // invoice. This type of query is only used to facilitate user-facing 1123 // requests to lookup, settle or cancel an AMP invoice. 1124 setID := ref.SetID() 1125 if setID != nil { 1126 invoiceNumBySetID := setIDIndex.Get(setID[:]) 1127 if invoiceNumBySetID == nil { 1128 return nil, ErrInvoiceNotFound 1129 } 1130 1131 return invoiceNumBySetID, nil 1132 } 1133 1134 payHash := ref.PayHash() 1135 payAddr := ref.PayAddr() 1136 1137 getInvoiceNumByHash := func() []byte { 1138 if payHash != nil { 1139 return invoiceIndex.Get(payHash[:]) 1140 } 1141 return nil 1142 } 1143 1144 getInvoiceNumByAddr := func() []byte { 1145 if payAddr != nil { 1146 // Only allow lookups for payment address if it is not a 1147 // blank payment address, which is a special-cased value 1148 // for legacy keysend invoices. 1149 if *payAddr != BlankPayAddr { 1150 return payAddrIndex.Get(payAddr[:]) 1151 } 1152 } 1153 return nil 1154 } 1155 1156 invoiceNumByHash := getInvoiceNumByHash() 1157 invoiceNumByAddr := getInvoiceNumByAddr() 1158 switch { 1159 1160 // If payment address and payment hash both reference an existing 1161 // invoice, ensure they reference the _same_ invoice. 1162 case invoiceNumByAddr != nil && invoiceNumByHash != nil: 1163 if !bytes.Equal(invoiceNumByAddr, invoiceNumByHash) { 1164 return nil, ErrInvRefEquivocation 1165 } 1166 1167 return invoiceNumByAddr, nil 1168 1169 // Return invoices by payment addr only. 1170 // 1171 // NOTE: We constrain this lookup to only apply if the invoice ref does 1172 // not contain a payment hash. Legacy and MPP payments depend on the 1173 // payment hash index to enforce that the HTLCs payment hash matches the 1174 // payment hash for the invoice, without this check we would 1175 // inadvertently assume the invoice contains the correct preimage for 1176 // the HTLC, which we only enforce via the lookup by the invoice index. 1177 case invoiceNumByAddr != nil && payHash == nil: 1178 return invoiceNumByAddr, nil 1179 1180 // If we were only able to reference the invoice by hash, return the 1181 // corresponding invoice number. This can happen when no payment address 1182 // was provided, or if it didn't match anything in our records. 1183 case invoiceNumByHash != nil: 1184 return invoiceNumByHash, nil 1185 1186 // Otherwise we don't know of the target invoice. 1187 default: 1188 return nil, ErrInvoiceNotFound 1189 } 1190 } 1191 1192 // ScanInvoices scans trough all invoices and calls the passed scanFunc for 1193 // for each invoice with its respective payment hash. Additionally a reset() 1194 // closure is passed which is used to reset/initialize partial results and also 1195 // to signal if the kvdb.View transaction has been retried. 1196 func (d *DB) ScanInvoices( 1197 scanFunc func(lntypes.Hash, *Invoice) error, reset func()) error { 1198 1199 return kvdb.View(d, func(tx kvdb.RTx) error { 1200 invoices := tx.ReadBucket(invoiceBucket) 1201 if invoices == nil { 1202 return ErrNoInvoicesCreated 1203 } 1204 1205 invoiceIndex := invoices.NestedReadBucket(invoiceIndexBucket) 1206 if invoiceIndex == nil { 1207 // Mask the error if there's no invoice 1208 // index as that simply means there are no 1209 // invoices added yet to the DB. In this case 1210 // we simply return an empty list. 1211 return nil 1212 } 1213 1214 return invoiceIndex.ForEach(func(k, v []byte) error { 1215 // Skip the special numInvoicesKey as that does not 1216 // point to a valid invoice. 1217 if bytes.Equal(k, numInvoicesKey) { 1218 return nil 1219 } 1220 1221 // Skip sub-buckets. 1222 if v == nil { 1223 return nil 1224 } 1225 1226 invoice, err := fetchInvoice(v, invoices) 1227 if err != nil { 1228 return err 1229 } 1230 1231 var paymentHash lntypes.Hash 1232 copy(paymentHash[:], k) 1233 1234 return scanFunc(paymentHash, &invoice) 1235 }) 1236 }, reset) 1237 } 1238 1239 // InvoiceQuery represents a query to the invoice database. The query allows a 1240 // caller to retrieve all invoices starting from a particular add index and 1241 // limit the number of results returned. 1242 type InvoiceQuery struct { 1243 // IndexOffset is the offset within the add indices to start at. This 1244 // can be used to start the response at a particular invoice. 1245 IndexOffset uint64 1246 1247 // NumMaxInvoices is the maximum number of invoices that should be 1248 // starting from the add index. 1249 NumMaxInvoices uint64 1250 1251 // PendingOnly, if set, returns unsettled invoices starting from the 1252 // add index. 1253 PendingOnly bool 1254 1255 // Reversed, if set, indicates that the invoices returned should start 1256 // from the IndexOffset and go backwards. 1257 Reversed bool 1258 } 1259 1260 // InvoiceSlice is the response to a invoice query. It includes the original 1261 // query, the set of invoices that match the query, and an integer which 1262 // represents the offset index of the last item in the set of returned invoices. 1263 // This integer allows callers to resume their query using this offset in the 1264 // event that the query's response exceeds the maximum number of returnable 1265 // invoices. 1266 type InvoiceSlice struct { 1267 InvoiceQuery 1268 1269 // Invoices is the set of invoices that matched the query above. 1270 Invoices []Invoice 1271 1272 // FirstIndexOffset is the index of the first element in the set of 1273 // returned Invoices above. Callers can use this to resume their query 1274 // in the event that the slice has too many events to fit into a single 1275 // response. 1276 FirstIndexOffset uint64 1277 1278 // LastIndexOffset is the index of the last element in the set of 1279 // returned Invoices above. Callers can use this to resume their query 1280 // in the event that the slice has too many events to fit into a single 1281 // response. 1282 LastIndexOffset uint64 1283 } 1284 1285 // QueryInvoices allows a caller to query the invoice database for invoices 1286 // within the specified add index range. 1287 func (d *DB) QueryInvoices(q InvoiceQuery) (InvoiceSlice, error) { 1288 var resp InvoiceSlice 1289 1290 err := kvdb.View(d, func(tx kvdb.RTx) error { 1291 // If the bucket wasn't found, then there aren't any invoices 1292 // within the database yet, so we can simply exit. 1293 invoices := tx.ReadBucket(invoiceBucket) 1294 if invoices == nil { 1295 return ErrNoInvoicesCreated 1296 } 1297 1298 // Get the add index bucket which we will use to iterate through 1299 // our indexed invoices. 1300 invoiceAddIndex := invoices.NestedReadBucket(addIndexBucket) 1301 if invoiceAddIndex == nil { 1302 return ErrNoInvoicesCreated 1303 } 1304 1305 // Create a paginator which reads from our add index bucket with 1306 // the parameters provided by the invoice query. 1307 paginator := newPaginator( 1308 invoiceAddIndex.ReadCursor(), q.Reversed, q.IndexOffset, 1309 q.NumMaxInvoices, 1310 ) 1311 1312 // accumulateInvoices looks up an invoice based on the index we 1313 // are given, adds it to our set of invoices if it has the right 1314 // characteristics for our query and returns the number of items 1315 // we have added to our set of invoices. 1316 accumulateInvoices := func(_, indexValue []byte) (bool, error) { 1317 invoice, err := fetchInvoice(indexValue, invoices) 1318 if err != nil { 1319 return false, err 1320 } 1321 1322 // Skip any settled or canceled invoices if the caller 1323 // is only interested in pending ones. 1324 if q.PendingOnly && !invoice.IsPending() { 1325 return false, nil 1326 } 1327 1328 // At this point, we've exhausted the offset, so we'll 1329 // begin collecting invoices found within the range. 1330 resp.Invoices = append(resp.Invoices, invoice) 1331 return true, nil 1332 } 1333 1334 // Query our paginator using accumulateInvoices to build up a 1335 // set of invoices. 1336 if err := paginator.query(accumulateInvoices); err != nil { 1337 return err 1338 } 1339 1340 // If we iterated through the add index in reverse order, then 1341 // we'll need to reverse the slice of invoices to return them in 1342 // forward order. 1343 if q.Reversed { 1344 numInvoices := len(resp.Invoices) 1345 for i := 0; i < numInvoices/2; i++ { 1346 opposite := numInvoices - i - 1 1347 resp.Invoices[i], resp.Invoices[opposite] = 1348 resp.Invoices[opposite], resp.Invoices[i] 1349 } 1350 } 1351 1352 return nil 1353 }, func() { 1354 resp = InvoiceSlice{ 1355 InvoiceQuery: q, 1356 } 1357 }) 1358 if err != nil && err != ErrNoInvoicesCreated { 1359 return resp, err 1360 } 1361 1362 // Finally, record the indexes of the first and last invoices returned 1363 // so that the caller can resume from this point later on. 1364 if len(resp.Invoices) > 0 { 1365 resp.FirstIndexOffset = resp.Invoices[0].AddIndex 1366 resp.LastIndexOffset = resp.Invoices[len(resp.Invoices)-1].AddIndex 1367 } 1368 1369 return resp, nil 1370 } 1371 1372 // UpdateInvoice attempts to update an invoice corresponding to the passed 1373 // payment hash. If an invoice matching the passed payment hash doesn't exist 1374 // within the database, then the action will fail with a "not found" error. 1375 // 1376 // The update is performed inside the same database transaction that fetches the 1377 // invoice and is therefore atomic. The fields to update are controlled by the 1378 // supplied callback. 1379 func (d *DB) UpdateInvoice(ref InvoiceRef, setIDHint *SetID, 1380 callback InvoiceUpdateCallback) (*Invoice, error) { 1381 1382 var updatedInvoice *Invoice 1383 err := kvdb.Update(d, func(tx kvdb.RwTx) error { 1384 invoices, err := tx.CreateTopLevelBucket(invoiceBucket) 1385 if err != nil { 1386 return err 1387 } 1388 invoiceIndex, err := invoices.CreateBucketIfNotExists( 1389 invoiceIndexBucket, 1390 ) 1391 if err != nil { 1392 return err 1393 } 1394 settleIndex, err := invoices.CreateBucketIfNotExists( 1395 settleIndexBucket, 1396 ) 1397 if err != nil { 1398 return err 1399 } 1400 payAddrIndex := tx.ReadBucket(payAddrIndexBucket) 1401 setIDIndex := tx.ReadWriteBucket(setIDIndexBucket) 1402 1403 // Retrieve the invoice number for this invoice using the 1404 // provided invoice reference. 1405 invoiceNum, err := fetchInvoiceNumByRef( 1406 invoiceIndex, payAddrIndex, setIDIndex, ref, 1407 ) 1408 if err != nil { 1409 return err 1410 } 1411 1412 payHash := ref.PayHash() 1413 updatedInvoice, err = d.updateInvoice( 1414 payHash, setIDHint, invoices, settleIndex, setIDIndex, 1415 invoiceNum, callback, 1416 ) 1417 1418 return err 1419 }, func() { 1420 updatedInvoice = nil 1421 }) 1422 1423 return updatedInvoice, err 1424 } 1425 1426 // InvoicesSettledSince can be used by callers to catch up any settled invoices 1427 // they missed within the settled invoice time series. We'll return all known 1428 // settled invoice that have a settle index higher than the passed 1429 // sinceSettleIndex. 1430 // 1431 // NOTE: The index starts from 1, as a result. We enforce that specifying a 1432 // value below the starting index value is a noop. 1433 func (d *DB) InvoicesSettledSince(sinceSettleIndex uint64) ([]Invoice, error) { 1434 var settledInvoices []Invoice 1435 1436 // If an index of zero was specified, then in order to maintain 1437 // backwards compat, we won't send out any new invoices. 1438 if sinceSettleIndex == 0 { 1439 return settledInvoices, nil 1440 } 1441 1442 var startIndex [8]byte 1443 byteOrder.PutUint64(startIndex[:], sinceSettleIndex) 1444 1445 err := kvdb.View(d, func(tx kvdb.RTx) error { 1446 invoices := tx.ReadBucket(invoiceBucket) 1447 if invoices == nil { 1448 return nil 1449 } 1450 1451 settleIndex := invoices.NestedReadBucket(settleIndexBucket) 1452 if settleIndex == nil { 1453 return nil 1454 } 1455 1456 // We'll now run through each entry in the add index starting 1457 // at our starting index. We'll continue until we reach the 1458 // very end of the current key space. 1459 invoiceCursor := settleIndex.ReadCursor() 1460 1461 // We'll seek to the starting index, then manually advance the 1462 // cursor in order to skip the entry with the since add index. 1463 invoiceCursor.Seek(startIndex[:]) 1464 seqNo, indexValue := invoiceCursor.Next() 1465 1466 for ; seqNo != nil && bytes.Compare(seqNo, startIndex[:]) > 0; seqNo, indexValue = invoiceCursor.Next() { 1467 1468 // Depending on the length of the index value, this may 1469 // or may not be an AMP invoice, so we'll extract the 1470 // invoice value into two components: the invoice num, 1471 // and the setID (may not be there). 1472 var ( 1473 invoiceKey [4]byte 1474 setID *SetID 1475 ) 1476 1477 valueLen := copy(invoiceKey[:], indexValue) 1478 if len(indexValue) == invoiceSetIDKeyLen { 1479 setID = new(SetID) 1480 copy(setID[:], indexValue[valueLen:]) 1481 } 1482 1483 // For each key found, we'll look up the actual 1484 // invoice, then accumulate it into our return value. 1485 invoice, err := fetchInvoice(invoiceKey[:], invoices, setID) 1486 if err != nil { 1487 return err 1488 } 1489 1490 settledInvoices = append(settledInvoices, invoice) 1491 } 1492 1493 return nil 1494 }, func() { 1495 settledInvoices = nil 1496 }) 1497 if err != nil { 1498 return nil, err 1499 } 1500 1501 return settledInvoices, nil 1502 } 1503 1504 func putInvoice(invoices, invoiceIndex, payAddrIndex, addIndex kvdb.RwBucket, 1505 i *Invoice, invoiceNum uint32, paymentHash lntypes.Hash) ( 1506 uint64, error) { 1507 1508 // Create the invoice key which is just the big-endian representation 1509 // of the invoice number. 1510 var invoiceKey [4]byte 1511 byteOrder.PutUint32(invoiceKey[:], invoiceNum) 1512 1513 // Increment the num invoice counter index so the next invoice bares 1514 // the proper ID. 1515 var scratch [4]byte 1516 invoiceCounter := invoiceNum + 1 1517 byteOrder.PutUint32(scratch[:], invoiceCounter) 1518 if err := invoiceIndex.Put(numInvoicesKey, scratch[:]); err != nil { 1519 return 0, err 1520 } 1521 1522 // Add the payment hash to the invoice index. This will let us quickly 1523 // identify if we can settle an incoming payment, and also to possibly 1524 // allow a single invoice to have multiple payment installations. 1525 err := invoiceIndex.Put(paymentHash[:], invoiceKey[:]) 1526 if err != nil { 1527 return 0, err 1528 } 1529 1530 // Add the invoice to the payment address index, but only if the invoice 1531 // has a non-zero payment address. The all-zero payment address is still 1532 // in use by legacy keysend, so we special-case here to avoid 1533 // collisions. 1534 if i.Terms.PaymentAddr != BlankPayAddr { 1535 err = payAddrIndex.Put(i.Terms.PaymentAddr[:], invoiceKey[:]) 1536 if err != nil { 1537 return 0, err 1538 } 1539 } 1540 1541 // Next, we'll obtain the next add invoice index (sequence 1542 // number), so we can properly place this invoice within this 1543 // event stream. 1544 nextAddSeqNo, err := addIndex.NextSequence() 1545 if err != nil { 1546 return 0, err 1547 } 1548 1549 // With the next sequence obtained, we'll updating the event series in 1550 // the add index bucket to map this current add counter to the index of 1551 // this new invoice. 1552 var seqNoBytes [8]byte 1553 byteOrder.PutUint64(seqNoBytes[:], nextAddSeqNo) 1554 if err := addIndex.Put(seqNoBytes[:], invoiceKey[:]); err != nil { 1555 return 0, err 1556 } 1557 1558 i.AddIndex = nextAddSeqNo 1559 1560 // Finally, serialize the invoice itself to be written to the disk. 1561 var buf bytes.Buffer 1562 if err := serializeInvoice(&buf, i); err != nil { 1563 return 0, err 1564 } 1565 1566 if err := invoices.Put(invoiceKey[:], buf.Bytes()); err != nil { 1567 return 0, err 1568 } 1569 1570 return nextAddSeqNo, nil 1571 } 1572 1573 // serializeInvoice serializes an invoice to a writer. 1574 // 1575 // Note: this function is in use for a migration. Before making changes that 1576 // would modify the on disk format, make a copy of the original code and store 1577 // it with the migration. 1578 func serializeInvoice(w io.Writer, i *Invoice) error { 1579 creationDateBytes, err := i.CreationDate.MarshalBinary() 1580 if err != nil { 1581 return err 1582 } 1583 1584 settleDateBytes, err := i.SettleDate.MarshalBinary() 1585 if err != nil { 1586 return err 1587 } 1588 1589 var fb bytes.Buffer 1590 err = i.Terms.Features.EncodeBase256(&fb) 1591 if err != nil { 1592 return err 1593 } 1594 featureBytes := fb.Bytes() 1595 1596 preimage := [32]byte(unknownPreimage) 1597 if i.Terms.PaymentPreimage != nil { 1598 preimage = *i.Terms.PaymentPreimage 1599 if preimage == unknownPreimage { 1600 return errors.New("cannot use all-zeroes preimage") 1601 } 1602 } 1603 value := uint64(i.Terms.Value) 1604 cltvDelta := uint32(i.Terms.FinalCltvDelta) 1605 expiry := uint64(i.Terms.Expiry) 1606 1607 amtPaid := uint64(i.AmtPaid) 1608 state := uint8(i.State) 1609 1610 var hodlInvoice uint8 1611 if i.HodlInvoice { 1612 hodlInvoice = 1 1613 } 1614 1615 tlvStream, err := tlv.NewStream( 1616 // Memo and payreq. 1617 tlv.MakePrimitiveRecord(memoType, &i.Memo), 1618 tlv.MakePrimitiveRecord(payReqType, &i.PaymentRequest), 1619 1620 // Add/settle metadata. 1621 tlv.MakePrimitiveRecord(createTimeType, &creationDateBytes), 1622 tlv.MakePrimitiveRecord(settleTimeType, &settleDateBytes), 1623 tlv.MakePrimitiveRecord(addIndexType, &i.AddIndex), 1624 tlv.MakePrimitiveRecord(settleIndexType, &i.SettleIndex), 1625 1626 // Terms. 1627 tlv.MakePrimitiveRecord(preimageType, &preimage), 1628 tlv.MakePrimitiveRecord(valueType, &value), 1629 tlv.MakePrimitiveRecord(cltvDeltaType, &cltvDelta), 1630 tlv.MakePrimitiveRecord(expiryType, &expiry), 1631 tlv.MakePrimitiveRecord(paymentAddrType, &i.Terms.PaymentAddr), 1632 tlv.MakePrimitiveRecord(featuresType, &featureBytes), 1633 1634 // Invoice state. 1635 tlv.MakePrimitiveRecord(invStateType, &state), 1636 tlv.MakePrimitiveRecord(amtPaidType, &amtPaid), 1637 1638 tlv.MakePrimitiveRecord(hodlInvoiceType, &hodlInvoice), 1639 1640 // Invoice AMP state. 1641 tlv.MakeDynamicRecord( 1642 invoiceAmpStateType, &i.AMPState, 1643 i.AMPState.recordSize, 1644 ampStateEncoder, ampStateDecoder, 1645 ), 1646 ) 1647 if err != nil { 1648 return err 1649 } 1650 1651 var b bytes.Buffer 1652 if err = tlvStream.Encode(&b); err != nil { 1653 return err 1654 } 1655 1656 err = binary.Write(w, byteOrder, uint64(b.Len())) 1657 if err != nil { 1658 return err 1659 } 1660 1661 if _, err = w.Write(b.Bytes()); err != nil { 1662 return err 1663 } 1664 1665 // Only if this is a _non_ AMP invoice do we serialize the HTLCs 1666 // in-line with the rest of the invoice. 1667 ampInvoice := i.Terms.Features.HasFeature( 1668 lnwire.AMPOptional, 1669 ) 1670 if ampInvoice { 1671 return nil 1672 } 1673 1674 return serializeHtlcs(w, i.Htlcs) 1675 } 1676 1677 // serializeHtlcs serializes a map containing circuit keys and invoice htlcs to 1678 // a writer. 1679 func serializeHtlcs(w io.Writer, htlcs map[CircuitKey]*InvoiceHTLC) error { 1680 for key, htlc := range htlcs { 1681 // Encode the htlc in a tlv stream. 1682 chanID := key.ChanID.ToUint64() 1683 amt := uint64(htlc.Amt) 1684 mppTotalAmt := uint64(htlc.MppTotalAmt) 1685 acceptTime := putNanoTime(htlc.AcceptTime) 1686 resolveTime := putNanoTime(htlc.ResolveTime) 1687 state := uint8(htlc.State) 1688 1689 var records []tlv.Record 1690 records = append(records, 1691 tlv.MakePrimitiveRecord(chanIDType, &chanID), 1692 tlv.MakePrimitiveRecord(htlcIDType, &key.HtlcID), 1693 tlv.MakePrimitiveRecord(amtType, &amt), 1694 tlv.MakePrimitiveRecord( 1695 acceptHeightType, &htlc.AcceptHeight, 1696 ), 1697 tlv.MakePrimitiveRecord(acceptTimeType, &acceptTime), 1698 tlv.MakePrimitiveRecord(resolveTimeType, &resolveTime), 1699 tlv.MakePrimitiveRecord(expiryHeightType, &htlc.Expiry), 1700 tlv.MakePrimitiveRecord(htlcStateType, &state), 1701 tlv.MakePrimitiveRecord(mppTotalAmtType, &mppTotalAmt), 1702 ) 1703 1704 if htlc.AMP != nil { 1705 setIDRecord := tlv.MakeDynamicRecord( 1706 htlcAMPType, &htlc.AMP.Record, 1707 htlc.AMP.Record.PayloadSize, 1708 record.AMPEncoder, record.AMPDecoder, 1709 ) 1710 records = append(records, setIDRecord) 1711 1712 hash32 := [32]byte(htlc.AMP.Hash) 1713 hashRecord := tlv.MakePrimitiveRecord( 1714 htlcHashType, &hash32, 1715 ) 1716 records = append(records, hashRecord) 1717 1718 if htlc.AMP.Preimage != nil { 1719 preimage32 := [32]byte(*htlc.AMP.Preimage) 1720 preimageRecord := tlv.MakePrimitiveRecord( 1721 htlcPreimageType, &preimage32, 1722 ) 1723 records = append(records, preimageRecord) 1724 } 1725 } 1726 1727 // Convert the custom records to tlv.Record types that are ready 1728 // for serialization. 1729 customRecords := tlv.MapToRecords(htlc.CustomRecords) 1730 1731 // Append the custom records. Their ids are in the experimental 1732 // range and sorted, so there is no need to sort again. 1733 records = append(records, customRecords...) 1734 1735 tlvStream, err := tlv.NewStream(records...) 1736 if err != nil { 1737 return err 1738 } 1739 1740 var b bytes.Buffer 1741 if err := tlvStream.Encode(&b); err != nil { 1742 return err 1743 } 1744 1745 // Write the length of the tlv stream followed by the stream 1746 // bytes. 1747 err = binary.Write(w, byteOrder, uint64(b.Len())) 1748 if err != nil { 1749 return err 1750 } 1751 1752 if _, err := w.Write(b.Bytes()); err != nil { 1753 return err 1754 } 1755 } 1756 1757 return nil 1758 } 1759 1760 // putNanoTime returns the unix nano time for the passed timestamp. A zero-value 1761 // timestamp will be mapped to 0, since calling UnixNano in that case is 1762 // undefined. 1763 func putNanoTime(t time.Time) uint64 { 1764 if t.IsZero() { 1765 return 0 1766 } 1767 return uint64(t.UnixNano()) 1768 } 1769 1770 // getNanoTime returns a timestamp for the given number of nano seconds. If zero 1771 // is provided, an zero-value time stamp is returned. 1772 func getNanoTime(ns uint64) time.Time { 1773 if ns == 0 { 1774 return time.Time{} 1775 } 1776 return time.Unix(0, int64(ns)) 1777 } 1778 1779 // fetchFilteredAmpInvoices retrieves only a select set of AMP invoices 1780 // identified by the setID value. 1781 func fetchFilteredAmpInvoices(invoiceBucket kvdb.RBucket, 1782 invoiceNum []byte, setIDs ...*SetID) (map[CircuitKey]*InvoiceHTLC, error) { 1783 1784 htlcs := make(map[CircuitKey]*InvoiceHTLC) 1785 for _, setID := range setIDs { 1786 invoiceSetIDKey := makeInvoiceSetIDKey(invoiceNum, setID[:]) 1787 1788 htlcSetBytes := invoiceBucket.Get(invoiceSetIDKey[:]) 1789 if htlcSetBytes == nil { 1790 // A set ID was passed in, but we don't have this 1791 // stored yet, meaning that the setID is being added 1792 // for the first time. 1793 return htlcs, ErrInvoiceNotFound 1794 } 1795 1796 htlcSetReader := bytes.NewReader(htlcSetBytes) 1797 htlcsBySetID, err := deserializeHtlcs(htlcSetReader) 1798 if err != nil { 1799 return nil, err 1800 } 1801 1802 for key, htlc := range htlcsBySetID { 1803 htlcs[key] = htlc 1804 } 1805 } 1806 1807 return htlcs, nil 1808 } 1809 1810 // forEachAMPInvoice is a helper function that attempts to iterate over each of 1811 // the HTLC sets (based on their set ID) for the given AMP invoice identified 1812 // by its invoiceNum. The callback closure is called for each key within the 1813 // prefix range. 1814 func forEachAMPInvoice(invoiceBucket kvdb.RBucket, invoiceNum []byte, 1815 callback func(key, htlcSet []byte) error) error { 1816 1817 invoiceCursor := invoiceBucket.ReadCursor() 1818 1819 // Seek to the first key that includes the invoice data itself. 1820 invoiceCursor.Seek(invoiceNum) 1821 1822 // Advance to the very first key _after_ the invoice data, as this is 1823 // where we'll encounter our first HTLC (if any are present). 1824 cursorKey, htlcSet := invoiceCursor.Next() 1825 1826 // If at this point, the cursor key doesn't match the invoice num 1827 // prefix, then we know that this HTLC doesn't have any set ID HTLCs 1828 // associated with it. 1829 if !bytes.HasPrefix(cursorKey, invoiceNum) { 1830 return nil 1831 } 1832 1833 // Otherwise continue to iterate until we no longer match the prefix, 1834 // executing the call back at each step. 1835 for ; cursorKey != nil && bytes.HasPrefix(cursorKey, invoiceNum); cursorKey, htlcSet = invoiceCursor.Next() { 1836 err := callback(cursorKey, htlcSet) 1837 if err != nil { 1838 return err 1839 } 1840 } 1841 1842 return nil 1843 } 1844 1845 // fetchAmpSubInvoices attempts to use the invoiceNum as a prefix within the 1846 // AMP bucket to find all the individual HTLCs (by setID) associated with a 1847 // given invoice. If a list of set IDs are specified, then only HTLCs 1848 // associated with that setID will be retrieved. 1849 func fetchAmpSubInvoices(invoiceBucket kvdb.RBucket, 1850 invoiceNum []byte, setIDs ...*SetID) (map[CircuitKey]*InvoiceHTLC, error) { 1851 1852 // If a set of setIDs was specified, then we can skip the cursor and 1853 // just read out exactly what we need. 1854 if len(setIDs) != 0 && setIDs[0] != nil { 1855 return fetchFilteredAmpInvoices( 1856 invoiceBucket, invoiceNum, setIDs..., 1857 ) 1858 } 1859 1860 // Otherwise, iterate over all the htlc sets that are prefixed beside 1861 // this invoice in the main invoice bucket. 1862 htlcs := make(map[CircuitKey]*InvoiceHTLC) 1863 err := forEachAMPInvoice(invoiceBucket, invoiceNum, func(key, htlcSet []byte) error { 1864 htlcSetReader := bytes.NewReader(htlcSet) 1865 htlcsBySetID, err := deserializeHtlcs(htlcSetReader) 1866 if err != nil { 1867 return err 1868 } 1869 1870 for key, htlc := range htlcsBySetID { 1871 htlcs[key] = htlc 1872 } 1873 1874 return nil 1875 }) 1876 if err != nil { 1877 return nil, err 1878 } 1879 1880 return htlcs, nil 1881 } 1882 1883 // fetchInvoice attempts to read out the relevant state for the invoice as 1884 // specified by the invoice number. If the setID fields are set, then only the 1885 // HTLC information pertaining to those set IDs is returned. 1886 func fetchInvoice(invoiceNum []byte, invoices kvdb.RBucket, setIDs ...*SetID) (Invoice, error) { 1887 invoiceBytes := invoices.Get(invoiceNum) 1888 if invoiceBytes == nil { 1889 return Invoice{}, ErrInvoiceNotFound 1890 } 1891 1892 invoiceReader := bytes.NewReader(invoiceBytes) 1893 1894 invoice, err := deserializeInvoice(invoiceReader) 1895 if err != nil { 1896 return Invoice{}, err 1897 } 1898 1899 // If this is an AMP invoice, then we'll also attempt to read out the 1900 // set of HTLCs that were paid to prior set IDs. However, we'll only do 1901 // this is the invoice didn't already have HTLCs stored in-line. 1902 invoiceIsAMP := invoice.Terms.Features.HasFeature( 1903 lnwire.AMPOptional, 1904 ) 1905 switch { 1906 case !invoiceIsAMP: 1907 return invoice, nil 1908 1909 // For AMP invoice that already have HTLCs populated (created before 1910 // recurring invoices), then we don't need to read from the prefix 1911 // keyed section of the bucket. 1912 case invoiceIsAMP && len(invoice.Htlcs) != 0: 1913 return invoice, nil 1914 1915 // If the "zero" setID was specified, then this means that no HTLC data 1916 // should be returned alongside of it. 1917 case invoiceIsAMP && len(setIDs) != 0 && setIDs[0] != nil && 1918 *setIDs[0] == BlankPayAddr: 1919 1920 return invoice, nil 1921 } 1922 1923 invoice.Htlcs, err = fetchAmpSubInvoices( 1924 invoices, invoiceNum, setIDs..., 1925 ) 1926 if err != nil { 1927 return invoice, nil 1928 } 1929 1930 return invoice, nil 1931 } 1932 1933 // fetchInvoiceStateAMP retrieves the state of all the relevant sub-invoice for 1934 // an AMP invoice. This methods only decode the relevant state vs the entire 1935 // invoice. 1936 func fetchInvoiceStateAMP(invoiceNum []byte, 1937 invoices kvdb.RBucket) (AMPInvoiceState, error) { 1938 1939 // Fetch the raw invoice bytes. 1940 invoiceBytes := invoices.Get(invoiceNum) 1941 if invoiceBytes == nil { 1942 return nil, ErrInvoiceNotFound 1943 } 1944 1945 r := bytes.NewReader(invoiceBytes) 1946 1947 var bodyLen int64 1948 err := binary.Read(r, byteOrder, &bodyLen) 1949 if err != nil { 1950 return nil, err 1951 } 1952 1953 // Next, we'll make a new TLV stream that only attempts to decode the 1954 // bytes we actually need. 1955 ampState := make(AMPInvoiceState) 1956 tlvStream, err := tlv.NewStream( 1957 // Invoice AMP state. 1958 tlv.MakeDynamicRecord( 1959 invoiceAmpStateType, &State, nil, 1960 ampStateEncoder, ampStateDecoder, 1961 ), 1962 ) 1963 if err != nil { 1964 return nil, err 1965 } 1966 1967 invoiceReader := io.LimitReader(r, bodyLen) 1968 if err = tlvStream.Decode(invoiceReader); err != nil { 1969 return nil, err 1970 } 1971 1972 return ampState, nil 1973 } 1974 1975 func deserializeInvoice(r io.Reader) (Invoice, error) { 1976 var ( 1977 preimageBytes [32]byte 1978 value uint64 1979 cltvDelta uint32 1980 expiry uint64 1981 amtPaid uint64 1982 state uint8 1983 hodlInvoice uint8 1984 1985 creationDateBytes []byte 1986 settleDateBytes []byte 1987 featureBytes []byte 1988 ) 1989 1990 var i Invoice 1991 i.AMPState = make(AMPInvoiceState) 1992 tlvStream, err := tlv.NewStream( 1993 // Memo and payreq. 1994 tlv.MakePrimitiveRecord(memoType, &i.Memo), 1995 tlv.MakePrimitiveRecord(payReqType, &i.PaymentRequest), 1996 1997 // Add/settle metadata. 1998 tlv.MakePrimitiveRecord(createTimeType, &creationDateBytes), 1999 tlv.MakePrimitiveRecord(settleTimeType, &settleDateBytes), 2000 tlv.MakePrimitiveRecord(addIndexType, &i.AddIndex), 2001 tlv.MakePrimitiveRecord(settleIndexType, &i.SettleIndex), 2002 2003 // Terms. 2004 tlv.MakePrimitiveRecord(preimageType, &preimageBytes), 2005 tlv.MakePrimitiveRecord(valueType, &value), 2006 tlv.MakePrimitiveRecord(cltvDeltaType, &cltvDelta), 2007 tlv.MakePrimitiveRecord(expiryType, &expiry), 2008 tlv.MakePrimitiveRecord(paymentAddrType, &i.Terms.PaymentAddr), 2009 tlv.MakePrimitiveRecord(featuresType, &featureBytes), 2010 2011 // Invoice state. 2012 tlv.MakePrimitiveRecord(invStateType, &state), 2013 tlv.MakePrimitiveRecord(amtPaidType, &amtPaid), 2014 2015 tlv.MakePrimitiveRecord(hodlInvoiceType, &hodlInvoice), 2016 2017 // Invoice AMP state. 2018 tlv.MakeDynamicRecord( 2019 invoiceAmpStateType, &i.AMPState, nil, 2020 ampStateEncoder, ampStateDecoder, 2021 ), 2022 ) 2023 if err != nil { 2024 return i, err 2025 } 2026 2027 var bodyLen int64 2028 err = binary.Read(r, byteOrder, &bodyLen) 2029 if err != nil { 2030 return i, err 2031 } 2032 2033 lr := io.LimitReader(r, bodyLen) 2034 if err = tlvStream.Decode(lr); err != nil { 2035 return i, err 2036 } 2037 2038 preimage := lntypes.Preimage(preimageBytes) 2039 if preimage != unknownPreimage { 2040 i.Terms.PaymentPreimage = &preimage 2041 } 2042 2043 i.Terms.Value = lnwire.MilliAtom(value) 2044 i.Terms.FinalCltvDelta = int32(cltvDelta) 2045 i.Terms.Expiry = time.Duration(expiry) 2046 i.AmtPaid = lnwire.MilliAtom(amtPaid) 2047 i.State = ContractState(state) 2048 2049 if hodlInvoice != 0 { 2050 i.HodlInvoice = true 2051 } 2052 2053 err = i.CreationDate.UnmarshalBinary(creationDateBytes) 2054 if err != nil { 2055 return i, err 2056 } 2057 2058 err = i.SettleDate.UnmarshalBinary(settleDateBytes) 2059 if err != nil { 2060 return i, err 2061 } 2062 2063 rawFeatures := lnwire.NewRawFeatureVector() 2064 err = rawFeatures.DecodeBase256( 2065 bytes.NewReader(featureBytes), len(featureBytes), 2066 ) 2067 if err != nil { 2068 return i, err 2069 } 2070 2071 i.Terms.Features = lnwire.NewFeatureVector( 2072 rawFeatures, lnwire.Features, 2073 ) 2074 2075 i.Htlcs, err = deserializeHtlcs(r) 2076 return i, err 2077 } 2078 2079 func encodeCircuitKeys(w io.Writer, val interface{}, buf *[8]byte) error { 2080 if v, ok := val.(*map[CircuitKey]struct{}); ok { 2081 // We encode the set of circuit keys as a varint length prefix. 2082 // followed by a series of fixed sized uint8 integers. 2083 numKeys := uint64(len(*v)) 2084 2085 if err := tlv.WriteVarInt(w, numKeys, buf); err != nil { 2086 return err 2087 } 2088 2089 for key := range *v { 2090 scidInt := key.ChanID.ToUint64() 2091 2092 if err := tlv.EUint64(w, &scidInt, buf); err != nil { 2093 return err 2094 } 2095 if err := tlv.EUint64(w, &key.HtlcID, buf); err != nil { 2096 return err 2097 } 2098 } 2099 2100 return nil 2101 } 2102 2103 return tlv.NewTypeForEncodingErr(val, "*map[CircuitKey]struct{}") 2104 } 2105 2106 func decodeCircuitKeys(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { 2107 if v, ok := val.(*map[CircuitKey]struct{}); ok { 2108 // First, we'll read out the varint that encodes the number of 2109 // circuit keys encoded. 2110 numKeys, err := tlv.ReadVarInt(r, buf) 2111 if err != nil { 2112 return err 2113 } 2114 2115 // Now that we know how many keys to expect, iterate reading each 2116 // one until we're done. 2117 for i := uint64(0); i < numKeys; i++ { 2118 var ( 2119 key CircuitKey 2120 scid uint64 2121 ) 2122 2123 if err := tlv.DUint64(r, &scid, buf, 8); err != nil { 2124 return err 2125 } 2126 2127 key.ChanID = lnwire.NewShortChanIDFromInt(scid) 2128 2129 if err := tlv.DUint64(r, &key.HtlcID, buf, 8); err != nil { 2130 return err 2131 } 2132 2133 (*v)[key] = struct{}{} 2134 } 2135 2136 return nil 2137 } 2138 2139 return tlv.NewTypeForDecodingErr(val, "*map[CircuitKey]struct{}", l, l) 2140 } 2141 2142 // ampStateEncoder is a custom TLV encoder for the AMPInvoiceState record. 2143 func ampStateEncoder(w io.Writer, val interface{}, buf *[8]byte) error { 2144 if v, ok := val.(*AMPInvoiceState); ok { 2145 // We'll encode the AMP state as a series of KV pairs on the 2146 // wire with a length prefix. 2147 numRecords := uint64(len(*v)) 2148 2149 // First, we'll write out the number of records as a var int. 2150 if err := tlv.WriteVarInt(w, numRecords, buf); err != nil { 2151 return err 2152 } 2153 2154 // With that written out, we'll now encode the entries 2155 // themselves as a sub-TLV record, which includes its _own_ 2156 // inner length prefix. 2157 for setID, ampState := range *v { 2158 setID := [32]byte(setID) 2159 ampState := ampState 2160 2161 htlcState := uint8(ampState.State) 2162 settleDateBytes, err := ampState.SettleDate.MarshalBinary() 2163 if err != nil { 2164 return err 2165 } 2166 2167 amtPaid := uint64(ampState.AmtPaid) 2168 2169 var ampStateTlvBytes bytes.Buffer 2170 tlvStream, err := tlv.NewStream( 2171 tlv.MakePrimitiveRecord( 2172 ampStateSetIDType, &setID, 2173 ), 2174 tlv.MakePrimitiveRecord( 2175 ampStateHtlcStateType, &htlcState, 2176 ), 2177 tlv.MakePrimitiveRecord( 2178 ampStateSettleIndexType, &State.SettleIndex, 2179 ), 2180 tlv.MakePrimitiveRecord( 2181 ampStateSettleDateType, &settleDateBytes, 2182 ), 2183 tlv.MakeDynamicRecord( 2184 ampStateCircuitKeysType, 2185 &State.InvoiceKeys, 2186 func() uint64 { 2187 // The record takes 8 bytes to encode the 2188 // set of circuits, 8 bytes for the scid 2189 // for the key, and 8 bytes for the HTLC 2190 // index. 2191 numKeys := uint64(len(ampState.InvoiceKeys)) 2192 return tlv.VarIntSize(numKeys) + (numKeys * 16) 2193 }, 2194 encodeCircuitKeys, decodeCircuitKeys, 2195 ), 2196 tlv.MakePrimitiveRecord( 2197 ampStateAmtPaidType, &amtPaid, 2198 ), 2199 ) 2200 if err != nil { 2201 return err 2202 } 2203 2204 if err := tlvStream.Encode(&StateTlvBytes); err != nil { 2205 return err 2206 } 2207 2208 // We encode the record with a varint length followed by 2209 // the _raw_ TLV bytes. 2210 tlvLen := uint64(len(ampStateTlvBytes.Bytes())) 2211 if err := tlv.WriteVarInt(w, tlvLen, buf); err != nil { 2212 return err 2213 } 2214 2215 if _, err := w.Write(ampStateTlvBytes.Bytes()); err != nil { 2216 return err 2217 } 2218 } 2219 2220 return nil 2221 } 2222 2223 return tlv.NewTypeForEncodingErr(val, "channeldb.AMPInvoiceState") 2224 } 2225 2226 // ampStateDecoder is a custom TLV decoder for the AMPInvoiceState record. 2227 func ampStateDecoder(r io.Reader, val interface{}, buf *[8]byte, l uint64) error { 2228 if v, ok := val.(*AMPInvoiceState); ok { 2229 // First, we'll decode the varint that encodes how many set IDs 2230 // are encoded within the greater map. 2231 numRecords, err := tlv.ReadVarInt(r, buf) 2232 if err != nil { 2233 return err 2234 } 2235 2236 // Now that we know how many records we'll need to read, we can 2237 // iterate and read them all out in series. 2238 for i := uint64(0); i < numRecords; i++ { 2239 // Read out the varint that encodes the size of this inner 2240 // TLV record 2241 stateRecordSize, err := tlv.ReadVarInt(r, buf) 2242 if err != nil { 2243 return err 2244 } 2245 2246 // Using this information, we'll create a new limited 2247 // reader that'll return an EOF once the end has been 2248 // reached so the stream stops consuming bytes. 2249 innerTlvReader := io.LimitedReader{ 2250 R: r, 2251 N: int64(stateRecordSize), 2252 } 2253 2254 var ( 2255 setID [32]byte 2256 htlcState uint8 2257 settleIndex uint64 2258 settleDateBytes []byte 2259 invoiceKeys = make(map[CircuitKey]struct{}) 2260 amtPaid uint64 2261 ) 2262 tlvStream, err := tlv.NewStream( 2263 tlv.MakePrimitiveRecord( 2264 ampStateSetIDType, &setID, 2265 ), 2266 tlv.MakePrimitiveRecord( 2267 ampStateHtlcStateType, &htlcState, 2268 ), 2269 tlv.MakePrimitiveRecord( 2270 ampStateSettleIndexType, &settleIndex, 2271 ), 2272 tlv.MakePrimitiveRecord( 2273 ampStateSettleDateType, &settleDateBytes, 2274 ), 2275 tlv.MakeDynamicRecord( 2276 ampStateCircuitKeysType, 2277 &invoiceKeys, nil, 2278 encodeCircuitKeys, decodeCircuitKeys, 2279 ), 2280 tlv.MakePrimitiveRecord( 2281 ampStateAmtPaidType, &amtPaid, 2282 ), 2283 ) 2284 if err != nil { 2285 return err 2286 } 2287 2288 if err := tlvStream.Decode(&innerTlvReader); err != nil { 2289 return err 2290 } 2291 2292 var settleDate time.Time 2293 err = settleDate.UnmarshalBinary(settleDateBytes) 2294 if err != nil { 2295 return err 2296 } 2297 2298 (*v)[setID] = InvoiceStateAMP{ 2299 State: HtlcState(htlcState), 2300 SettleIndex: settleIndex, 2301 SettleDate: settleDate, 2302 InvoiceKeys: invoiceKeys, 2303 AmtPaid: lnwire.MilliAtom(amtPaid), 2304 } 2305 } 2306 2307 return nil 2308 } 2309 2310 return tlv.NewTypeForEncodingErr(val, "channeldb.AMPInvoiceState") 2311 } 2312 2313 // deserializeHtlcs reads a list of invoice htlcs from a reader and returns it 2314 // as a map. 2315 func deserializeHtlcs(r io.Reader) (map[CircuitKey]*InvoiceHTLC, error) { 2316 htlcs := make(map[CircuitKey]*InvoiceHTLC) 2317 2318 for { 2319 // Read the length of the tlv stream for this htlc. 2320 var streamLen int64 2321 if err := binary.Read(r, byteOrder, &streamLen); err != nil { 2322 if err == io.EOF { 2323 break 2324 } 2325 2326 return nil, err 2327 } 2328 2329 // Limit the reader so that it stops at the end of this htlc's 2330 // stream. 2331 htlcReader := io.LimitReader(r, streamLen) 2332 2333 // Decode the contents into the htlc fields. 2334 var ( 2335 htlc InvoiceHTLC 2336 key CircuitKey 2337 chanID uint64 2338 state uint8 2339 acceptTime, resolveTime uint64 2340 amt, mppTotalAmt uint64 2341 amp = &record.AMP{} 2342 hash32 = &[32]byte{} 2343 preimage32 = &[32]byte{} 2344 ) 2345 tlvStream, err := tlv.NewStream( 2346 tlv.MakePrimitiveRecord(chanIDType, &chanID), 2347 tlv.MakePrimitiveRecord(htlcIDType, &key.HtlcID), 2348 tlv.MakePrimitiveRecord(amtType, &amt), 2349 tlv.MakePrimitiveRecord( 2350 acceptHeightType, &htlc.AcceptHeight, 2351 ), 2352 tlv.MakePrimitiveRecord(acceptTimeType, &acceptTime), 2353 tlv.MakePrimitiveRecord(resolveTimeType, &resolveTime), 2354 tlv.MakePrimitiveRecord(expiryHeightType, &htlc.Expiry), 2355 tlv.MakePrimitiveRecord(htlcStateType, &state), 2356 tlv.MakePrimitiveRecord(mppTotalAmtType, &mppTotalAmt), 2357 tlv.MakeDynamicRecord( 2358 htlcAMPType, amp, amp.PayloadSize, 2359 record.AMPEncoder, record.AMPDecoder, 2360 ), 2361 tlv.MakePrimitiveRecord(htlcHashType, hash32), 2362 tlv.MakePrimitiveRecord(htlcPreimageType, preimage32), 2363 ) 2364 if err != nil { 2365 return nil, err 2366 } 2367 2368 parsedTypes, err := tlvStream.DecodeWithParsedTypes(htlcReader) 2369 if err != nil { 2370 return nil, err 2371 } 2372 2373 if _, ok := parsedTypes[htlcAMPType]; !ok { 2374 amp = nil 2375 } 2376 2377 var preimage *lntypes.Preimage 2378 if _, ok := parsedTypes[htlcPreimageType]; ok { 2379 pimg := lntypes.Preimage(*preimage32) 2380 preimage = &pimg 2381 } 2382 2383 var hash *lntypes.Hash 2384 if _, ok := parsedTypes[htlcHashType]; ok { 2385 h := lntypes.Hash(*hash32) 2386 hash = &h 2387 } 2388 2389 key.ChanID = lnwire.NewShortChanIDFromInt(chanID) 2390 htlc.AcceptTime = getNanoTime(acceptTime) 2391 htlc.ResolveTime = getNanoTime(resolveTime) 2392 htlc.State = HtlcState(state) 2393 htlc.Amt = lnwire.MilliAtom(amt) 2394 htlc.MppTotalAmt = lnwire.MilliAtom(mppTotalAmt) 2395 if amp != nil && hash != nil { 2396 htlc.AMP = &InvoiceHtlcAMPData{ 2397 Record: *amp, 2398 Hash: *hash, 2399 Preimage: preimage, 2400 } 2401 } 2402 2403 // Reconstruct the custom records fields from the parsed types 2404 // map return from the tlv parser. 2405 htlc.CustomRecords = hop.NewCustomRecords(parsedTypes) 2406 2407 htlcs[key] = &htlc 2408 } 2409 2410 return htlcs, nil 2411 } 2412 2413 // copySlice allocates a new slice and copies the source into it. 2414 func copySlice(src []byte) []byte { 2415 dest := make([]byte, len(src)) 2416 copy(dest, src) 2417 return dest 2418 } 2419 2420 // copyInvoice makes a deep copy of the supplied invoice. 2421 func copyInvoice(src *Invoice) *Invoice { 2422 dest := Invoice{ 2423 Memo: copySlice(src.Memo), 2424 PaymentRequest: copySlice(src.PaymentRequest), 2425 CreationDate: src.CreationDate, 2426 SettleDate: src.SettleDate, 2427 Terms: src.Terms, 2428 AddIndex: src.AddIndex, 2429 SettleIndex: src.SettleIndex, 2430 State: src.State, 2431 AmtPaid: src.AmtPaid, 2432 Htlcs: make( 2433 map[CircuitKey]*InvoiceHTLC, len(src.Htlcs), 2434 ), 2435 HodlInvoice: src.HodlInvoice, 2436 } 2437 2438 dest.Terms.Features = src.Terms.Features.Clone() 2439 2440 if src.Terms.PaymentPreimage != nil { 2441 preimage := *src.Terms.PaymentPreimage 2442 dest.Terms.PaymentPreimage = &preimage 2443 } 2444 2445 for k, v := range src.Htlcs { 2446 dest.Htlcs[k] = v.Copy() 2447 } 2448 2449 return &dest 2450 } 2451 2452 // invoiceSetIDKeyLen is the length of the key that's used to store the 2453 // individual HTLCs prefixed by their ID along side the main invoice within the 2454 // invoiceBytes. We use 4 bytes for the invoice number, and 32 bytes for the 2455 // set ID. 2456 const invoiceSetIDKeyLen = 4 + 32 2457 2458 // makeInvoiceSetIDKey returns the prefix key, based on the set ID and invoice 2459 // number where the HTLCs for this setID will be stored udner. 2460 func makeInvoiceSetIDKey(invoiceNum, setID []byte) [invoiceSetIDKeyLen]byte { 2461 // Construct the prefix key we need to obtain the invoice information: 2462 // invoiceNum || setID. 2463 var invoiceSetIDKey [invoiceSetIDKeyLen]byte 2464 copy(invoiceSetIDKey[:], invoiceNum) 2465 copy(invoiceSetIDKey[len(invoiceNum):], setID) 2466 2467 return invoiceSetIDKey 2468 } 2469 2470 // updateAMPInvoices updates the set of AMP invoices in-place. For AMP, rather 2471 // then continually write the invoices to the end of the invoice value, we 2472 // instead write the invoices into a new key preifx that follows the main 2473 // invoice number. This ensures that we don't need to continually decode a 2474 // potentially massive HTLC set, and also allows us to quickly find the HLTCs 2475 // associated with a particular HTLC set. 2476 func updateAMPInvoices(invoiceBucket kvdb.RwBucket, invoiceNum []byte, 2477 htlcsToUpdate map[SetID]map[CircuitKey]*InvoiceHTLC) error { 2478 2479 for setID, htlcSet := range htlcsToUpdate { 2480 // First write out the set of HTLCs including all the relevant TLV 2481 // values. 2482 var b bytes.Buffer 2483 if err := serializeHtlcs(&b, htlcSet); err != nil { 2484 return err 2485 } 2486 2487 // Next store each HTLC in-line, using a prefix based off the 2488 // invoice number. 2489 invoiceSetIDKey := makeInvoiceSetIDKey(invoiceNum, setID[:]) 2490 2491 err := invoiceBucket.Put(invoiceSetIDKey[:], b.Bytes()) 2492 if err != nil { 2493 return err 2494 } 2495 } 2496 2497 return nil 2498 } 2499 2500 // updateHtlcsAmp takes an invoice, and a new HTLC to be added (along with its 2501 // set ID), and update sthe internal AMP state of an invoice, and also tallies 2502 // the set of HTLCs to be updated on disk. 2503 func updateHtlcsAmp(invoice *Invoice, 2504 updateMap map[SetID]map[CircuitKey]*InvoiceHTLC, htlc *InvoiceHTLC, 2505 setID SetID, circuitKey CircuitKey) { 2506 2507 ampState, ok := invoice.AMPState[setID] 2508 if !ok { 2509 // If an entry for this set ID doesn't already exist, then 2510 // we'll need to create it. 2511 ampState = InvoiceStateAMP{ 2512 State: HtlcStateAccepted, 2513 InvoiceKeys: make(map[CircuitKey]struct{}), 2514 } 2515 } 2516 2517 ampState.AmtPaid += htlc.Amt 2518 ampState.InvoiceKeys[circuitKey] = struct{}{} 2519 2520 // Due to the way maps work, we need to read out the value, update it, 2521 // then re-assign it into the map. 2522 invoice.AMPState[setID] = ampState 2523 2524 // Now that we've updated the invoice state, we'll inform the caller of 2525 // the _neitre_ HTLC set they need to write for this new set ID. 2526 if _, ok := updateMap[setID]; !ok { 2527 // If we're just now creating the HTLCs for this set then we'll 2528 // also pull in the existing HTLCs are part of this set, so we 2529 // can write them all to disk together (same value) 2530 updateMap[setID] = invoice.HTLCSet( 2531 (*[32]byte)(&setID), HtlcStateAccepted, 2532 ) 2533 } 2534 updateMap[setID][circuitKey] = htlc 2535 } 2536 2537 // cancelHtlcsAmp processes a cancellation of an HTLC that belongs to an AMP 2538 // HTLC set. We'll need to update the meta data in the main invoice, and also 2539 // apply the new update to the update MAP, since all the HTLCs for a given HTLC 2540 // set need to be written in-line with each other. 2541 func cancelHtlcsAmp(invoice *Invoice, 2542 updateMap map[SetID]map[CircuitKey]*InvoiceHTLC, htlc *InvoiceHTLC, 2543 circuitKey CircuitKey) { 2544 2545 setID := htlc.AMP.Record.SetID() 2546 2547 // First, we'll update the state of the entire HTLC set to cancelled. 2548 ampState := invoice.AMPState[setID] 2549 ampState.State = HtlcStateCanceled 2550 2551 ampState.InvoiceKeys[circuitKey] = struct{}{} 2552 ampState.AmtPaid -= htlc.Amt 2553 2554 // With the state update,d we'll set the new value so the struct 2555 // changes are propagated. 2556 invoice.AMPState[setID] = ampState 2557 2558 if _, ok := updateMap[setID]; !ok { 2559 // Only HTLCs in the accepted state, can be cancelled, but we 2560 // also want to merge that with HTLCs that may be canceled as 2561 // well since it can be cancelled one by one. 2562 updateMap[setID] = invoice.HTLCSet(&setID, HtlcStateAccepted) 2563 2564 cancelledHtlcs := invoice.HTLCSet(&setID, HtlcStateCanceled) 2565 for htlcKey, htlc := range cancelledHtlcs { 2566 updateMap[setID][htlcKey] = htlc 2567 } 2568 } 2569 2570 // Finally, include the newly cancelled HTLC in the set of HTLCs we 2571 // need to cancel. 2572 updateMap[setID][circuitKey] = htlc 2573 2574 // We'll only decrement the total amount paid if the invoice was 2575 // already in the accepted state. 2576 if invoice.AmtPaid != 0 { 2577 invoice.AmtPaid -= htlc.Amt 2578 } 2579 } 2580 2581 // settleHtlcsAmp processes a new settle operation on an HTLC set for an AMP 2582 // invoice. We'll update some meta data in the main invoice, and also signal 2583 // that this HTLC set needs to be re-written back to disk. 2584 func settleHtlcsAmp(invoice *Invoice, 2585 settledSetIDs map[SetID]struct{}, 2586 updateMap map[SetID]map[CircuitKey]*InvoiceHTLC, htlc *InvoiceHTLC, 2587 circuitKey CircuitKey) { 2588 2589 // First, add the set ID to the set that was settled in this invoice 2590 // update. We'll use this later to update the settle index. 2591 setID := htlc.AMP.Record.SetID() 2592 settledSetIDs[setID] = struct{}{} 2593 2594 // Next update the main AMP meta-data to indicate that this HTLC set 2595 // has been fully settled. 2596 ampState := invoice.AMPState[setID] 2597 ampState.State = HtlcStateSettled 2598 2599 ampState.InvoiceKeys[circuitKey] = struct{}{} 2600 2601 invoice.AMPState[setID] = ampState 2602 2603 // Finally, we'll add this to the set of HTLCs that need to be updated. 2604 if _, ok := updateMap[setID]; !ok { 2605 updateMap[setID] = make(map[CircuitKey]*InvoiceHTLC) 2606 } 2607 updateMap[setID][circuitKey] = htlc 2608 } 2609 2610 // updateInvoice fetches the invoice, obtains the update descriptor from the 2611 // callback and applies the updates in a single db transaction. 2612 func (d *DB) updateInvoice(hash *lntypes.Hash, refSetID *SetID, invoices, 2613 settleIndex, setIDIndex kvdb.RwBucket, invoiceNum []byte, 2614 callback InvoiceUpdateCallback) (*Invoice, error) { 2615 2616 // If the set ID is non-nil, then we'll use that to filter out the 2617 // HTLCs for AMP invoice so we don't need to read them all out to 2618 // satisfy the invoice callback below. If it's nil, then we pass in the 2619 // zero set ID which means no HTLCs will be read out. 2620 var invSetID SetID 2621 if refSetID != nil { 2622 invSetID = *refSetID 2623 } 2624 invoice, err := fetchInvoice(invoiceNum, invoices, &invSetID) 2625 if err != nil { 2626 return nil, err 2627 } 2628 2629 // Create deep copy to prevent any accidental modification in the 2630 // callback. 2631 invoiceCopy := copyInvoice(&invoice) 2632 2633 // Call the callback and obtain the update descriptor. 2634 update, err := callback(invoiceCopy) 2635 if err != nil { 2636 return &invoice, err 2637 } 2638 2639 // If there is nothing to update, return early. 2640 if update == nil { 2641 return &invoice, nil 2642 } 2643 2644 var ( 2645 newState = invoice.State 2646 setID *[32]byte 2647 ) 2648 2649 // We can either get the set ID from the main state update (if the 2650 // state is changing), or via the hint passed in returned by the update 2651 // call back. 2652 if update.State != nil { 2653 setID = update.State.SetID 2654 newState = update.State.NewState 2655 } else if update.SetID != nil { 2656 // When we go to cancel HTLCs, there's no new state, but the 2657 // set of HTLCs to be cancelled along with the setID affected 2658 // will be passed in. 2659 setID = (*[32]byte)(update.SetID) 2660 } 2661 2662 now := d.clock.Now() 2663 2664 invoiceIsAMP := invoiceCopy.Terms.Features.HasFeature( 2665 lnwire.AMPOptional, 2666 ) 2667 2668 // Process add actions from update descriptor. 2669 htlcsAmpUpdate := make(map[SetID]map[CircuitKey]*InvoiceHTLC) 2670 for key, htlcUpdate := range update.AddHtlcs { 2671 if _, exists := invoice.Htlcs[key]; exists { 2672 return nil, fmt.Errorf("duplicate add of htlc %v", key) 2673 } 2674 2675 // Force caller to supply htlc without custom records in a 2676 // consistent way. 2677 if htlcUpdate.CustomRecords == nil { 2678 return nil, errors.New("nil custom records map") 2679 } 2680 2681 // If a newly added HTLC has an associated set id, use it to 2682 // index this invoice in the set id index. An error is returned 2683 // if we find the index already points to a different invoice. 2684 var setID [32]byte 2685 if htlcUpdate.AMP != nil { 2686 setID = htlcUpdate.AMP.Record.SetID() 2687 setIDInvNum := setIDIndex.Get(setID[:]) 2688 if setIDInvNum == nil { 2689 err = setIDIndex.Put(setID[:], invoiceNum) 2690 if err != nil { 2691 return nil, err 2692 } 2693 } else if !bytes.Equal(setIDInvNum, invoiceNum) { 2694 return nil, ErrDuplicateSetID{setID: setID} 2695 } 2696 } 2697 2698 htlc := &InvoiceHTLC{ 2699 Amt: htlcUpdate.Amt, 2700 MppTotalAmt: htlcUpdate.MppTotalAmt, 2701 Expiry: htlcUpdate.Expiry, 2702 AcceptHeight: uint32(htlcUpdate.AcceptHeight), 2703 AcceptTime: now, 2704 State: HtlcStateAccepted, 2705 CustomRecords: htlcUpdate.CustomRecords, 2706 AMP: htlcUpdate.AMP.Copy(), 2707 } 2708 2709 invoice.Htlcs[key] = htlc 2710 2711 // Collect the set of new HTLCs so we can write them properly 2712 // below, but only if this is an AMP invoice. 2713 if invoiceIsAMP { 2714 updateHtlcsAmp( 2715 &invoice, htlcsAmpUpdate, htlc, setID, key, 2716 ) 2717 } 2718 } 2719 2720 // Process cancel actions from update descriptor. 2721 cancelHtlcs := update.CancelHtlcs 2722 for key, htlc := range invoice.Htlcs { 2723 htlc := htlc 2724 2725 // Check whether this htlc needs to be canceled. If it does, 2726 // update the htlc state to Canceled. 2727 _, cancel := cancelHtlcs[key] 2728 if !cancel { 2729 continue 2730 } 2731 2732 // Consistency check to verify that there is no overlap between 2733 // the add and cancel sets. 2734 if _, added := update.AddHtlcs[key]; added { 2735 return nil, fmt.Errorf("added htlc %v canceled", key) 2736 } 2737 2738 err := cancelSingleHtlc(now, htlc, newState) 2739 if err != nil { 2740 return nil, err 2741 } 2742 2743 // Delete processed cancel action, so that we can check later 2744 // that there are no actions left. 2745 delete(cancelHtlcs, key) 2746 2747 // Tally this into the set of HTLCs that need to be updated on 2748 // disk, but once again, only if this is an AMP invoice. 2749 if invoiceIsAMP { 2750 cancelHtlcsAmp( 2751 &invoice, htlcsAmpUpdate, htlc, key, 2752 ) 2753 } 2754 } 2755 2756 // Verify that we didn't get an action for htlcs that are not present on 2757 // the invoice. 2758 if len(cancelHtlcs) > 0 { 2759 return nil, errors.New("cancel action on non-existent htlc(s)") 2760 } 2761 2762 // At this point, the set of accepted HTLCs should be fully 2763 // populated with added HTLCs or removed of canceled ones. Update 2764 // invoice state if the update descriptor indicates an invoice state 2765 // change, which depends on having an accurate view of the accepted 2766 // HTLCs. 2767 if update.State != nil { 2768 newState, err := updateInvoiceState( 2769 &invoice, hash, *update.State, 2770 ) 2771 if err != nil { 2772 return nil, err 2773 } 2774 2775 // If this isn't an AMP invoice, then we'll go ahead and update 2776 // the invoice state directly here. For AMP invoices, we 2777 // instead will keep the top-level invoice open, and instead 2778 // update the state of each _htlc set_ instead. However, we'll 2779 // allow the invoice to transition to the cancelled state 2780 // regardless. 2781 if !invoiceIsAMP || *newState == ContractCanceled { 2782 invoice.State = *newState 2783 } 2784 2785 // If this is a non-AMP invoice, then the state can eventually 2786 // go to ContractSettled, so we pass in nil value as part of 2787 // setSettleMetaFields. 2788 if !invoiceIsAMP && update.State.NewState == ContractSettled { 2789 err := setSettleMetaFields( 2790 settleIndex, invoiceNum, &invoice, now, nil, 2791 ) 2792 if err != nil { 2793 return nil, err 2794 } 2795 } 2796 } 2797 2798 // The set of HTLC pre-images will only be set if we were actually able 2799 // to reconstruct all the AMP pre-images. 2800 var settleEligibleAMP bool 2801 if update.State != nil { 2802 settleEligibleAMP = len(update.State.HTLCPreimages) != 0 2803 } 2804 2805 // With any invoice level state transitions recorded, we'll now 2806 // finalize the process by updating the state transitions for 2807 // individual HTLCs 2808 var ( 2809 settledSetIDs = make(map[SetID]struct{}) 2810 amtPaid lnwire.MilliAtom 2811 ) 2812 for key, htlc := range invoice.Htlcs { 2813 // Set the HTLC preimage for any AMP HTLCs. 2814 if setID != nil && update.State != nil { 2815 preimage, ok := update.State.HTLCPreimages[key] 2816 switch { 2817 2818 // If we don't already have a preimage for this HTLC, we 2819 // can set it now. 2820 case ok && htlc.AMP.Preimage == nil: 2821 htlc.AMP.Preimage = &preimage 2822 2823 // Otherwise, prevent over-writing an existing 2824 // preimage. Ignore the case where the preimage is 2825 // identical. 2826 case ok && *htlc.AMP.Preimage != preimage: 2827 return nil, ErrHTLCPreimageAlreadyExists 2828 } 2829 } 2830 2831 // The invoice state may have changed and this could have 2832 // implications for the states of the individual htlcs. Align 2833 // the htlc state with the current invoice state. 2834 // 2835 // If we have all the pre-images for an AMP invoice, then we'll 2836 // act as if we're able to settle the entire invoice. We need 2837 // to do this since it's possible for us to settle AMP invoices 2838 // while the contract state (on disk) is still in the accept 2839 // state. 2840 htlcContextState := invoice.State 2841 if settleEligibleAMP { 2842 htlcContextState = ContractSettled 2843 } 2844 htlcSettled, err := updateHtlc( 2845 now, htlc, htlcContextState, setID, 2846 ) 2847 if err != nil { 2848 return nil, err 2849 } 2850 2851 // If the HTLC has being settled for the first time, and this 2852 // is an AMP invoice, then we'll need to update some additional 2853 // meta data state. 2854 if htlcSettled && invoiceIsAMP { 2855 settleHtlcsAmp( 2856 &invoice, settledSetIDs, htlcsAmpUpdate, htlc, key, 2857 ) 2858 } 2859 2860 invoiceStateReady := (htlc.State == HtlcStateAccepted || 2861 htlc.State == HtlcStateSettled) 2862 if !invoiceIsAMP { 2863 // Update the running amount paid to this invoice. We 2864 // don't include accepted htlcs when the invoice is 2865 // still open. 2866 if invoice.State != ContractOpen && invoiceStateReady { 2867 amtPaid += htlc.Amt 2868 } 2869 } else { 2870 // For AMP invoices, since we won't always be reading 2871 // out the total invoice set each time, we'll instead 2872 // accumulate newly added invoices to the total amount 2873 // paid. 2874 if _, ok := update.AddHtlcs[key]; !ok { 2875 continue 2876 } 2877 2878 // Update the running amount paid to this invoice. AMP 2879 // invoices never go to the settled state, so if it's 2880 // open, then we tally the HTLC. 2881 if invoice.State == ContractOpen && invoiceStateReady { 2882 amtPaid += htlc.Amt 2883 } 2884 } 2885 } 2886 2887 // For non-AMP invoices we recalculate the amount paid from scratch 2888 // each time, while for AMP invoices, we'll accumulate only based on 2889 // newly added HTLCs. 2890 if !invoiceIsAMP { 2891 invoice.AmtPaid = amtPaid 2892 } else { 2893 2894 invoice.AmtPaid += amtPaid 2895 } 2896 2897 // As we don't update the settle index above for AMP invoices, we'll do 2898 // it here for each sub-AMP invoice that was settled. 2899 for settledSetID := range settledSetIDs { 2900 settledSetID := settledSetID 2901 err := setSettleMetaFields( 2902 settleIndex, invoiceNum, &invoice, now, &settledSetID, 2903 ) 2904 if err != nil { 2905 return nil, err 2906 } 2907 } 2908 2909 // Reserialize and update invoice. 2910 var buf bytes.Buffer 2911 if err := serializeInvoice(&buf, &invoice); err != nil { 2912 return nil, err 2913 } 2914 2915 if err := invoices.Put(invoiceNum[:], buf.Bytes()); err != nil { 2916 return nil, err 2917 } 2918 2919 // If this is an AMP invoice, then we'll actually store the rest of the 2920 // HTLCs in-line with the invoice, using the invoice ID as a prefix, 2921 // and the AMP key as a suffix: invoiceNum || setID. 2922 if invoiceIsAMP { 2923 err := updateAMPInvoices(invoices, invoiceNum, htlcsAmpUpdate) 2924 if err != nil { 2925 return nil, err 2926 } 2927 } 2928 2929 return &invoice, nil 2930 } 2931 2932 // updateInvoiceState validates and processes an invoice state update. The new 2933 // state to transition to is returned, so the caller is able to select exactly 2934 // how the invoice state is updated. 2935 func updateInvoiceState(invoice *Invoice, hash *lntypes.Hash, 2936 update InvoiceStateUpdateDesc) (*ContractState, error) { 2937 2938 // Returning to open is never allowed from any state. 2939 if update.NewState == ContractOpen { 2940 return nil, ErrInvoiceCannotOpen 2941 } 2942 2943 switch invoice.State { 2944 2945 // Once a contract is accepted, we can only transition to settled or 2946 // canceled. Forbid transitioning back into this state. Otherwise this 2947 // state is identical to ContractOpen, so we fallthrough to apply the 2948 // same checks that we apply to open invoices. 2949 case ContractAccepted: 2950 if update.NewState == ContractAccepted { 2951 return nil, ErrInvoiceCannotAccept 2952 } 2953 2954 fallthrough 2955 2956 // If a contract is open, permit a state transition to accepted, settled 2957 // or canceled. The only restriction is on transitioning to settled 2958 // where we ensure the preimage is valid. 2959 case ContractOpen: 2960 if update.NewState == ContractCanceled { 2961 return &update.NewState, nil 2962 } 2963 2964 // Sanity check that the user isn't trying to settle or accept a 2965 // non-existent HTLC set. 2966 if len(invoice.HTLCSet(update.SetID, HtlcStateAccepted)) == 0 { 2967 return nil, ErrEmptyHTLCSet 2968 } 2969 2970 // For AMP invoices, there are no invoice-level preimage checks. 2971 // However, we still sanity check that we aren't trying to 2972 // settle an AMP invoice with a preimage. 2973 if update.SetID != nil { 2974 if update.Preimage != nil { 2975 return nil, errors.New("AMP set cannot have " + 2976 "preimage") 2977 } 2978 return &update.NewState, nil 2979 } 2980 2981 switch { 2982 2983 // If an invoice-level preimage was supplied, but the InvoiceRef 2984 // doesn't specify a hash (e.g. AMP invoices) we fail. 2985 case update.Preimage != nil && hash == nil: 2986 return nil, ErrUnexpectedInvoicePreimage 2987 2988 // Validate the supplied preimage for non-AMP invoices. 2989 case update.Preimage != nil: 2990 if update.Preimage.Hash() != *hash { 2991 return nil, ErrInvoicePreimageMismatch 2992 } 2993 invoice.Terms.PaymentPreimage = update.Preimage 2994 2995 // Permit non-AMP invoices to be accepted without knowing the 2996 // preimage. When trying to settle we'll have to pass through 2997 // the above check in order to not hit the one below. 2998 case update.NewState == ContractAccepted: 2999 3000 // Fail if we still don't have a preimage when transitioning to 3001 // settle the non-AMP invoice. 3002 case update.NewState == ContractSettled && 3003 invoice.Terms.PaymentPreimage == nil: 3004 3005 return nil, errors.New("unknown preimage") 3006 } 3007 3008 return &update.NewState, nil 3009 3010 // Once settled, we are in a terminal state. 3011 case ContractSettled: 3012 return nil, ErrInvoiceAlreadySettled 3013 3014 // Once canceled, we are in a terminal state. 3015 case ContractCanceled: 3016 return nil, ErrInvoiceAlreadyCanceled 3017 3018 default: 3019 return nil, errors.New("unknown state transition") 3020 } 3021 } 3022 3023 // cancelSingleHtlc validates cancelation of a single htlc and update its state. 3024 func cancelSingleHtlc(resolveTime time.Time, htlc *InvoiceHTLC, 3025 invState ContractState) error { 3026 3027 // It is only possible to cancel individual htlcs on an open invoice. 3028 if invState != ContractOpen { 3029 return fmt.Errorf("htlc canceled on invoice in "+ 3030 "state %v", invState) 3031 } 3032 3033 // It is only possible if the htlc is still pending. 3034 if htlc.State != HtlcStateAccepted { 3035 return fmt.Errorf("htlc canceled in state %v", 3036 htlc.State) 3037 } 3038 3039 htlc.State = HtlcStateCanceled 3040 htlc.ResolveTime = resolveTime 3041 3042 return nil 3043 } 3044 3045 // updateHtlc aligns the state of an htlc with the given invoice state. A 3046 // boolean is returned if the HTLC was settled. 3047 func updateHtlc(resolveTime time.Time, htlc *InvoiceHTLC, 3048 invState ContractState, setID *[32]byte) (bool, error) { 3049 3050 trySettle := func(persist bool) (bool, error) { 3051 if htlc.State != HtlcStateAccepted { 3052 return false, nil 3053 } 3054 3055 // Settle the HTLC if it matches the settled set id. If 3056 // there're other HTLCs with distinct setIDs, then we'll leave 3057 // them, as they may eventually be settled as we permit 3058 // multiple settles to a single pay_addr for AMP. 3059 var htlcState HtlcState 3060 if htlc.IsInHTLCSet(setID) { 3061 // Non-AMP HTLCs can be settled immediately since we 3062 // already know the preimage is valid due to checks at 3063 // the invoice level. For AMP HTLCs, verify that the 3064 // per-HTLC preimage-hash pair is valid. 3065 switch { 3066 3067 // Non-AMP HTLCs can be settle immediately since we 3068 // already know the preimage is valid due to checks at 3069 // the invoice level. 3070 case setID == nil: 3071 3072 // At this point, the setID is non-nil, meaning this is 3073 // an AMP HTLC. We know that htlc.AMP cannot be nil, 3074 // otherwise IsInHTLCSet would have returned false. 3075 // 3076 // Fail if an accepted AMP HTLC has no preimage. 3077 case htlc.AMP.Preimage == nil: 3078 return false, ErrHTLCPreimageMissing 3079 3080 // Fail if the accepted AMP HTLC has an invalid 3081 // preimage. 3082 case !htlc.AMP.Preimage.Matches(htlc.AMP.Hash): 3083 return false, ErrHTLCPreimageMismatch 3084 } 3085 3086 htlcState = HtlcStateSettled 3087 } 3088 3089 // Only persist the changes if the invoice is moving to the 3090 // settled state, and we're actually updating the state to 3091 // settled. 3092 if persist && htlcState == HtlcStateSettled { 3093 htlc.State = htlcState 3094 htlc.ResolveTime = resolveTime 3095 } 3096 3097 return persist && htlcState == HtlcStateSettled, nil 3098 } 3099 3100 if invState == ContractSettled { 3101 // Check that we can settle the HTLCs. For legacy and MPP HTLCs 3102 // this will be a NOP, but for AMP HTLCs this asserts that we 3103 // have a valid hash/preimage pair. Passing true permits the 3104 // method to update the HTLC to HtlcStateSettled. 3105 return trySettle(true) 3106 } 3107 3108 // We should never find a settled HTLC on an invoice that isn't in 3109 // ContractSettled. 3110 if htlc.State == HtlcStateSettled { 3111 return false, ErrHTLCAlreadySettled 3112 } 3113 3114 switch invState { 3115 3116 case ContractCanceled: 3117 if htlc.State == HtlcStateAccepted { 3118 htlc.State = HtlcStateCanceled 3119 htlc.ResolveTime = resolveTime 3120 } 3121 return false, nil 3122 3123 // TODO(roasbeef): never fully passed thru now? 3124 case ContractAccepted: 3125 // Check that we can settle the HTLCs. For legacy and MPP HTLCs 3126 // this will be a NOP, but for AMP HTLCs this asserts that we 3127 // have a valid hash/preimage pair. Passing false prevents the 3128 // method from putting the HTLC in HtlcStateSettled, leaving it 3129 // in HtlcStateAccepted. 3130 return trySettle(false) 3131 3132 case ContractOpen: 3133 return false, nil 3134 3135 default: 3136 return false, errors.New("unknown state transition") 3137 } 3138 } 3139 3140 // setSettleMetaFields updates the metadata associated with settlement of an 3141 // invoice. If a non-nil setID is passed in, then the value will be append to 3142 // the invoice number as well, in order to allow us to detect repeated payments 3143 // to the same AMP invoices "across time". 3144 func setSettleMetaFields(settleIndex kvdb.RwBucket, invoiceNum []byte, 3145 invoice *Invoice, now time.Time, setID *SetID) error { 3146 3147 // Now that we know the invoice hasn't already been settled, we'll 3148 // update the settle index so we can place this settle event in the 3149 // proper location within our time series. 3150 nextSettleSeqNo, err := settleIndex.NextSequence() 3151 if err != nil { 3152 return err 3153 } 3154 3155 // Make a new byte array on the stack that can potentially store the 4 3156 // byte invoice number along w/ the 32 byte set ID. We capture valueLen 3157 // here which is the number of bytes copied so we can only store the 4 3158 // bytes if this is a non-AMP invoice. 3159 var indexKey [invoiceSetIDKeyLen]byte 3160 valueLen := copy(indexKey[:], invoiceNum) 3161 3162 if setID != nil { 3163 valueLen += copy(indexKey[valueLen:], setID[:]) 3164 } 3165 3166 var seqNoBytes [8]byte 3167 byteOrder.PutUint64(seqNoBytes[:], nextSettleSeqNo) 3168 if err := settleIndex.Put(seqNoBytes[:], indexKey[:valueLen]); err != nil { 3169 return err 3170 } 3171 3172 // If the setID is nil, then this means that this is a non-AMP settle, 3173 // so we'll update the invoice settle index directly. 3174 if setID == nil { 3175 invoice.SettleDate = now 3176 invoice.SettleIndex = nextSettleSeqNo 3177 } else { 3178 // If the set ID isn't blank, we'll update the AMP state map 3179 // which tracks when each of the setIDs associated with a given 3180 // AMP invoice are settled. 3181 ampState := invoice.AMPState[*setID] 3182 3183 ampState.SettleDate = now 3184 ampState.SettleIndex = nextSettleSeqNo 3185 3186 invoice.AMPState[*setID] = ampState 3187 } 3188 3189 return nil 3190 } 3191 3192 // delAMPInvoices attempts to delete all the "sub" invoices associated with a 3193 // greater AMP invoices. We do this by deleting the set of keys that share the 3194 // invoice number as a prefix. 3195 func delAMPInvoices(invoiceNum []byte, invoiceBucket kvdb.RwBucket) error { 3196 // Since it isn't safe to delete using an active cursor, we'll use the 3197 // cursor simply to collect the set of keys we need to delete, _then_ 3198 // delete them in another pass. 3199 var keysToDel [][]byte 3200 err := forEachAMPInvoice(invoiceBucket, invoiceNum, func(cursorKey, v []byte) error { 3201 keysToDel = append(keysToDel, cursorKey) 3202 return nil 3203 }) 3204 if err != nil { 3205 return err 3206 } 3207 3208 // In this next phase, we'll then delete all the relevant invoices. 3209 for _, keyToDel := range keysToDel { 3210 if err := invoiceBucket.Delete(keyToDel); err != nil { 3211 return err 3212 } 3213 } 3214 3215 return nil 3216 } 3217 3218 // delAMPSettleIndex removes all the entries in the settle index associated 3219 // with a given AMP invoice. 3220 func delAMPSettleIndex(invoiceNum []byte, invoices, settleIndex kvdb.RwBucket) error { 3221 // First, we need to grab the AMP invoice state to see if there's 3222 // anything that we even need to delete. 3223 ampState, err := fetchInvoiceStateAMP(invoiceNum, invoices) 3224 if err != nil { 3225 return err 3226 } 3227 3228 // If there's no AMP state at all (non-AMP invoice), then we can return early. 3229 if len(ampState) == 0 { 3230 return nil 3231 } 3232 3233 // Otherwise, we'll need to iterate and delete each settle index within 3234 // the set of returned entries. 3235 var settleIndexKey [8]byte 3236 for _, subState := range ampState { 3237 byteOrder.PutUint64( 3238 settleIndexKey[:], subState.SettleIndex, 3239 ) 3240 3241 if err := settleIndex.Delete(settleIndexKey[:]); err != nil { 3242 return err 3243 } 3244 } 3245 3246 return nil 3247 } 3248 3249 // InvoiceDeleteRef holds a reference to an invoice to be deleted. 3250 type InvoiceDeleteRef struct { 3251 // PayHash is the payment hash of the target invoice. All invoices are 3252 // currently indexed by payment hash. 3253 PayHash lntypes.Hash 3254 3255 // PayAddr is the payment addr of the target invoice. Newer invoices 3256 // (0.11 and up) are indexed by payment address in addition to payment 3257 // hash, but pre 0.8 invoices do not have one at all. 3258 PayAddr *[32]byte 3259 3260 // AddIndex is the add index of the invoice. 3261 AddIndex uint64 3262 3263 // SettleIndex is the settle index of the invoice. 3264 SettleIndex uint64 3265 } 3266 3267 // DeleteInvoice attempts to delete the passed invoices from the database in 3268 // one transaction. The passed delete references hold all keys required to 3269 // delete the invoices without also needing to deserialze them. 3270 func (d *DB) DeleteInvoice(invoicesToDelete []InvoiceDeleteRef) error { 3271 err := kvdb.Update(d, func(tx kvdb.RwTx) error { 3272 invoices := tx.ReadWriteBucket(invoiceBucket) 3273 if invoices == nil { 3274 return ErrNoInvoicesCreated 3275 } 3276 3277 invoiceIndex := invoices.NestedReadWriteBucket( 3278 invoiceIndexBucket, 3279 ) 3280 if invoiceIndex == nil { 3281 return ErrNoInvoicesCreated 3282 } 3283 3284 invoiceAddIndex := invoices.NestedReadWriteBucket( 3285 addIndexBucket, 3286 ) 3287 if invoiceAddIndex == nil { 3288 return ErrNoInvoicesCreated 3289 } 3290 3291 // settleIndex can be nil, as the bucket is created lazily 3292 // when the first invoice is settled. 3293 settleIndex := invoices.NestedReadWriteBucket(settleIndexBucket) 3294 3295 payAddrIndex := tx.ReadWriteBucket(payAddrIndexBucket) 3296 3297 for _, ref := range invoicesToDelete { 3298 // Fetch the invoice key for using it to check for 3299 // consistency and also to delete from the invoice index. 3300 invoiceKey := invoiceIndex.Get(ref.PayHash[:]) 3301 if invoiceKey == nil { 3302 return ErrInvoiceNotFound 3303 } 3304 3305 err := invoiceIndex.Delete(ref.PayHash[:]) 3306 if err != nil { 3307 return err 3308 } 3309 3310 // Delete payment address index reference if there's a 3311 // valid payment address passed. 3312 if ref.PayAddr != nil { 3313 // To ensure consistency check that the already 3314 // fetched invoice key matches the one in the 3315 // payment address index. 3316 key := payAddrIndex.Get(ref.PayAddr[:]) 3317 if bytes.Equal(key, invoiceKey) { 3318 // Delete from the payment address index. 3319 // Note that since the payment address 3320 // index has been introduced with an 3321 // empty migration it may be possible 3322 // that the index doesn't have an entry 3323 // for this invoice. 3324 // ref: https://github.com/decred/dcrlnd/pull/4285/commits/cbf71b5452fa1d3036a43309e490787c5f7f08dc#r426368127 3325 if err := payAddrIndex.Delete( 3326 ref.PayAddr[:], 3327 ); err != nil { 3328 return err 3329 } 3330 } 3331 } 3332 3333 var addIndexKey [8]byte 3334 byteOrder.PutUint64(addIndexKey[:], ref.AddIndex) 3335 3336 // To ensure consistency check that the key stored in 3337 // the add index also matches the previously fetched 3338 // invoice key. 3339 key := invoiceAddIndex.Get(addIndexKey[:]) 3340 if !bytes.Equal(key, invoiceKey) { 3341 return fmt.Errorf("unknown invoice " + 3342 "in add index") 3343 } 3344 3345 // Remove from the add index. 3346 err = invoiceAddIndex.Delete(addIndexKey[:]) 3347 if err != nil { 3348 return err 3349 } 3350 3351 // Remove from the settle index if available and 3352 // if the invoice is settled. 3353 if settleIndex != nil && ref.SettleIndex > 0 { 3354 var settleIndexKey [8]byte 3355 byteOrder.PutUint64( 3356 settleIndexKey[:], ref.SettleIndex, 3357 ) 3358 3359 // To ensure consistency check that the already 3360 // fetched invoice key matches the one in the 3361 // settle index 3362 key := settleIndex.Get(settleIndexKey[:]) 3363 if !bytes.Equal(key, invoiceKey) { 3364 return fmt.Errorf("unknown invoice " + 3365 "in settle index") 3366 } 3367 3368 err = settleIndex.Delete(settleIndexKey[:]) 3369 if err != nil { 3370 return err 3371 } 3372 3373 } 3374 3375 // In addition to deleting the main invoice state, if 3376 // this is an AMP invoice, then we'll also need to 3377 // delete the set HTLC set stored as a key prefix. For 3378 // non-AMP invoices, this'll be a noop. 3379 err = delAMPSettleIndex( 3380 invoiceKey, invoices, settleIndex, 3381 ) 3382 if err != nil { 3383 return err 3384 } 3385 err = delAMPInvoices(invoiceKey, invoices) 3386 if err != nil { 3387 return err 3388 } 3389 3390 // Finally remove the serialized invoice from the 3391 // invoice bucket. 3392 err = invoices.Delete(invoiceKey) 3393 if err != nil { 3394 return err 3395 } 3396 } 3397 3398 return nil 3399 }, func() {}) 3400 3401 return err 3402 }