github.com/decred/dcrlnd@v0.7.6/invoices/invoiceregistry.go (about) 1 package invoices 2 3 import ( 4 "errors" 5 "fmt" 6 "sync" 7 "sync/atomic" 8 "time" 9 10 "github.com/decred/dcrlnd/channeldb" 11 "github.com/decred/dcrlnd/clock" 12 "github.com/decred/dcrlnd/lntypes" 13 "github.com/decred/dcrlnd/lnwire" 14 "github.com/decred/dcrlnd/queue" 15 "github.com/decred/dcrlnd/record" 16 ) 17 18 var ( 19 // ErrInvoiceExpiryTooSoon is returned when an invoice is attempted to be 20 // accepted or settled with not enough blocks remaining. 21 ErrInvoiceExpiryTooSoon = errors.New("invoice expiry too soon") 22 23 // ErrInvoiceAmountTooLow is returned when an invoice is attempted to be 24 // accepted or settled with an amount that is too low. 25 ErrInvoiceAmountTooLow = errors.New("paid amount less than invoice amount") 26 27 // ErrShuttingDown is returned when an operation failed because the 28 // invoice registry is shutting down. 29 ErrShuttingDown = errors.New("invoice registry shutting down") 30 ) 31 32 const ( 33 // DefaultHtlcHoldDuration defines the default for how long mpp htlcs 34 // are held while waiting for the other set members to arrive. 35 DefaultHtlcHoldDuration = 120 * time.Second 36 ) 37 38 // RegistryConfig contains the configuration parameters for invoice registry. 39 type RegistryConfig struct { 40 // FinalCltvRejectDelta defines the number of blocks before the expiry 41 // of the htlc where we no longer settle it as an exit hop and instead 42 // cancel it back. Normally this value should be lower than the cltv 43 // expiry of any invoice we create and the code effectuating this should 44 // not be hit. 45 FinalCltvRejectDelta int32 46 47 // HtlcHoldDuration defines for how long mpp htlcs are held while 48 // waiting for the other set members to arrive. 49 HtlcHoldDuration time.Duration 50 51 // Clock holds the clock implementation that is used to provide 52 // Now() and TickAfter() and is useful to stub out the clock functions 53 // during testing. 54 Clock clock.Clock 55 56 // AcceptKeySend indicates whether we want to accept spontaneous key 57 // send payments. 58 AcceptKeySend bool 59 60 // AcceptAMP indicates whether we want to accept spontaneous AMP 61 // payments. 62 AcceptAMP bool 63 64 // GcCanceledInvoicesOnStartup if set, we'll attempt to garbage collect 65 // all canceled invoices upon start. 66 GcCanceledInvoicesOnStartup bool 67 68 // GcCanceledInvoicesOnTheFly if set, we'll garbage collect all newly 69 // canceled invoices on the fly. 70 GcCanceledInvoicesOnTheFly bool 71 72 // KeysendHoldTime indicates for how long we want to accept and hold 73 // spontaneous keysend payments. 74 KeysendHoldTime time.Duration 75 } 76 77 // htlcReleaseEvent describes an htlc auto-release event. It is used to release 78 // mpp htlcs for which the complete set didn't arrive in time. 79 type htlcReleaseEvent struct { 80 // invoiceRef identifiers the invoice this htlc belongs to. 81 invoiceRef channeldb.InvoiceRef 82 83 // key is the circuit key of the htlc to release. 84 key channeldb.CircuitKey 85 86 // releaseTime is the time at which to release the htlc. 87 releaseTime time.Time 88 } 89 90 // Less is used to order PriorityQueueItem's by their release time such that 91 // items with the older release time are at the top of the queue. 92 // 93 // NOTE: Part of the queue.PriorityQueueItem interface. 94 func (r *htlcReleaseEvent) Less(other queue.PriorityQueueItem) bool { 95 return r.releaseTime.Before(other.(*htlcReleaseEvent).releaseTime) 96 } 97 98 // InvoiceRegistry is a central registry of all the outstanding invoices 99 // created by the daemon. The registry is a thin wrapper around a map in order 100 // to ensure that all updates/reads are thread safe. 101 type InvoiceRegistry struct { 102 sync.RWMutex 103 104 cdb *channeldb.DB 105 106 // cfg contains the registry's configuration parameters. 107 cfg *RegistryConfig 108 109 clientMtx sync.Mutex 110 nextClientID uint32 111 notificationClients map[uint32]*InvoiceSubscription 112 singleNotificationClients map[uint32]*SingleInvoiceSubscription 113 114 newSubscriptions chan *InvoiceSubscription 115 subscriptionCancels chan uint32 116 117 // invoiceEvents is a single channel over which both invoice updates and 118 // new single invoice subscriptions are carried. 119 invoiceEvents chan interface{} 120 121 // subscriptions is a map from a circuit key to a list of subscribers. 122 // It is used for efficient notification of links. 123 hodlSubscriptions map[channeldb.CircuitKey]map[chan<- interface{}]struct{} 124 125 // reverseSubscriptions tracks circuit keys subscribed to per 126 // subscriber. This is used to unsubscribe from all hashes efficiently. 127 hodlReverseSubscriptions map[chan<- interface{}]map[channeldb.CircuitKey]struct{} 128 129 // htlcAutoReleaseChan contains the new htlcs that need to be 130 // auto-released. 131 htlcAutoReleaseChan chan *htlcReleaseEvent 132 133 expiryWatcher *InvoiceExpiryWatcher 134 135 wg sync.WaitGroup 136 quit chan struct{} 137 } 138 139 // NewRegistry creates a new invoice registry. The invoice registry 140 // wraps the persistent on-disk invoice storage with an additional in-memory 141 // layer. The in-memory layer is in place such that debug invoices can be added 142 // which are volatile yet available system wide within the daemon. 143 func NewRegistry(cdb *channeldb.DB, expiryWatcher *InvoiceExpiryWatcher, 144 cfg *RegistryConfig) *InvoiceRegistry { 145 146 return &InvoiceRegistry{ 147 cdb: cdb, 148 notificationClients: make(map[uint32]*InvoiceSubscription), 149 singleNotificationClients: make(map[uint32]*SingleInvoiceSubscription), 150 newSubscriptions: make(chan *InvoiceSubscription), 151 subscriptionCancels: make(chan uint32), 152 invoiceEvents: make(chan interface{}, 100), 153 hodlSubscriptions: make(map[channeldb.CircuitKey]map[chan<- interface{}]struct{}), 154 hodlReverseSubscriptions: make(map[chan<- interface{}]map[channeldb.CircuitKey]struct{}), 155 cfg: cfg, 156 htlcAutoReleaseChan: make(chan *htlcReleaseEvent), 157 expiryWatcher: expiryWatcher, 158 quit: make(chan struct{}), 159 } 160 } 161 162 // scanInvoicesOnStart will scan all invoices on start and add active invoices 163 // to the invoice expirt watcher while also attempting to delete all canceled 164 // invoices. 165 func (i *InvoiceRegistry) scanInvoicesOnStart() error { 166 var ( 167 pending []invoiceExpiry 168 removable []channeldb.InvoiceDeleteRef 169 ) 170 171 reset := func() { 172 // Zero out our results on start and if the scan is ever run 173 // more than once. This latter case can happen if the kvdb 174 // layer needs to retry the View transaction underneath (eg. 175 // using the etcd driver, where all transactions are allowed 176 // to retry for serializability). 177 pending = nil 178 removable = make([]channeldb.InvoiceDeleteRef, 0) 179 } 180 181 scanFunc := func( 182 paymentHash lntypes.Hash, invoice *channeldb.Invoice) error { 183 184 if invoice.IsPending() { 185 expiryRef := makeInvoiceExpiry(paymentHash, invoice) 186 if expiryRef != nil { 187 pending = append(pending, expiryRef) 188 } 189 } else if i.cfg.GcCanceledInvoicesOnStartup && 190 invoice.State == channeldb.ContractCanceled { 191 192 // Consider invoice for removal if it is already 193 // canceled. Invoices that are expired but not yet 194 // canceled, will be queued up for cancellation after 195 // startup and will be deleted afterwards. 196 ref := channeldb.InvoiceDeleteRef{ 197 PayHash: paymentHash, 198 AddIndex: invoice.AddIndex, 199 SettleIndex: invoice.SettleIndex, 200 } 201 202 if invoice.Terms.PaymentAddr != channeldb.BlankPayAddr { 203 ref.PayAddr = &invoice.Terms.PaymentAddr 204 } 205 206 removable = append(removable, ref) 207 } 208 return nil 209 } 210 211 err := i.cdb.ScanInvoices(scanFunc, reset) 212 if err != nil { 213 return err 214 } 215 216 log.Debugf("Adding %d pending invoices to the expiry watcher", 217 len(pending)) 218 i.expiryWatcher.AddInvoices(pending...) 219 220 if len(removable) > 0 { 221 log.Infof("Attempting to delete %v canceled invoices", 222 len(removable)) 223 if err := i.cdb.DeleteInvoice(removable); err != nil { 224 log.Warnf("Deleting canceled invoices failed: %v", err) 225 } else { 226 log.Infof("Deleted %v canceled invoices", 227 len(removable)) 228 } 229 } 230 231 return nil 232 } 233 234 // Start starts the registry and all goroutines it needs to carry out its task. 235 func (i *InvoiceRegistry) Start() error { 236 // Start InvoiceExpiryWatcher and prepopulate it with existing active 237 // invoices. 238 err := i.expiryWatcher.Start(i.cancelInvoiceImpl) 239 if err != nil { 240 return err 241 } 242 243 i.wg.Add(1) 244 go i.invoiceEventLoop() 245 246 // Now scan all pending and removable invoices to the expiry watcher or 247 // delete them. 248 err = i.scanInvoicesOnStart() 249 if err != nil { 250 _ = i.Stop() 251 return err 252 } 253 254 return nil 255 } 256 257 // Stop signals the registry for a graceful shutdown. 258 func (i *InvoiceRegistry) Stop() error { 259 log.Info("InvoiceRegistry shutting down") 260 261 i.expiryWatcher.Stop() 262 263 close(i.quit) 264 265 i.wg.Wait() 266 return nil 267 } 268 269 // invoiceEvent represents a new event that has modified on invoice on disk. 270 // Only two event types are currently supported: newly created invoices, and 271 // instance where invoices are settled. 272 type invoiceEvent struct { 273 hash lntypes.Hash 274 invoice *channeldb.Invoice 275 setID *[32]byte 276 } 277 278 // tickAt returns a channel that ticks at the specified time. If the time has 279 // already passed, it will tick immediately. 280 func (i *InvoiceRegistry) tickAt(t time.Time) <-chan time.Time { 281 now := i.cfg.Clock.Now() 282 return i.cfg.Clock.TickAfter(t.Sub(now)) 283 } 284 285 // invoiceEventLoop is the dedicated goroutine responsible for accepting 286 // new notification subscriptions, cancelling old subscriptions, and 287 // dispatching new invoice events. 288 func (i *InvoiceRegistry) invoiceEventLoop() { 289 defer i.wg.Done() 290 291 // Set up a heap for htlc auto-releases. 292 autoReleaseHeap := &queue.PriorityQueue{} 293 294 for { 295 // If there is something to release, set up a release tick 296 // channel. 297 var nextReleaseTick <-chan time.Time 298 if autoReleaseHeap.Len() > 0 { 299 head := autoReleaseHeap.Top().(*htlcReleaseEvent) 300 nextReleaseTick = i.tickAt(head.releaseTime) 301 } 302 303 select { 304 // A new invoice subscription for all invoices has just arrived! 305 // We'll query for any backlog notifications, then add it to the 306 // set of clients. 307 case newClient := <-i.newSubscriptions: 308 log.Infof("New invoice subscription "+ 309 "client: id=%v", newClient.id) 310 311 // With the backlog notifications delivered (if any), 312 // we'll add this to our active subscriptions and 313 // continue. 314 i.notificationClients[newClient.id] = newClient 315 316 // A client no longer wishes to receive invoice notifications. 317 // So we'll remove them from the set of active clients. 318 case clientID := <-i.subscriptionCancels: 319 log.Infof("Cancelling invoice subscription for "+ 320 "client=%v", clientID) 321 322 delete(i.notificationClients, clientID) 323 delete(i.singleNotificationClients, clientID) 324 325 // An invoice event has come in. This can either be an update to 326 // an invoice or a new single invoice subscriber. Both type of 327 // events are passed in via the same channel, to make sure that 328 // subscribers get a consistent view of the event sequence. 329 case event := <-i.invoiceEvents: 330 switch e := event.(type) { 331 332 // A sub-systems has just modified the invoice state, so 333 // we'll dispatch notifications to all registered 334 // clients. 335 case *invoiceEvent: 336 // For backwards compatibility, do not notify 337 // all invoice subscribers of cancel and accept 338 // events. 339 state := e.invoice.State 340 if state != channeldb.ContractCanceled && 341 state != channeldb.ContractAccepted { 342 343 i.dispatchToClients(e) 344 } 345 i.dispatchToSingleClients(e) 346 347 // A new single invoice subscription has arrived. Add it 348 // to the set of clients. It is important to do this in 349 // sequence with any other invoice events, because an 350 // initial invoice update has already been sent out to 351 // the subscriber. 352 case *SingleInvoiceSubscription: 353 log.Infof("New single invoice subscription "+ 354 "client: id=%v, ref=%v", e.id, 355 e.invoiceRef) 356 357 i.singleNotificationClients[e.id] = e 358 } 359 360 // A new htlc came in for auto-release. 361 case event := <-i.htlcAutoReleaseChan: 362 log.Debugf("Scheduling auto-release for htlc: "+ 363 "ref=%v, key=%v at %v", 364 event.invoiceRef, event.key, event.releaseTime) 365 366 // We use an independent timer for every htlc rather 367 // than a set timer that is reset with every htlc coming 368 // in. Otherwise the sender could keep resetting the 369 // timer until the broadcast window is entered and our 370 // channel is force closed. 371 autoReleaseHeap.Push(event) 372 373 // The htlc at the top of the heap needs to be auto-released. 374 case <-nextReleaseTick: 375 event := autoReleaseHeap.Pop().(*htlcReleaseEvent) 376 err := i.cancelSingleHtlc( 377 event.invoiceRef, event.key, ResultMppTimeout, 378 ) 379 if err != nil { 380 log.Errorf("HTLC timer: %v", err) 381 } 382 383 case <-i.quit: 384 return 385 } 386 } 387 } 388 389 // dispatchToSingleClients passes the supplied event to all notification clients 390 // that subscribed to all the invoice this event applies to. 391 func (i *InvoiceRegistry) dispatchToSingleClients(event *invoiceEvent) { 392 // Dispatch to single invoice subscribers. 393 for _, client := range i.singleNotificationClients { 394 payHash := client.invoiceRef.PayHash() 395 if payHash == nil || *payHash != event.hash { 396 continue 397 } 398 399 client.notify(event) 400 } 401 } 402 403 // dispatchToClients passes the supplied event to all notification clients that 404 // subscribed to all invoices. Add and settle indices are used to make sure that 405 // clients don't receive duplicate or unwanted events. 406 func (i *InvoiceRegistry) dispatchToClients(event *invoiceEvent) { 407 invoice := event.invoice 408 409 for clientID, client := range i.notificationClients { 410 // Before we dispatch this event, we'll check 411 // to ensure that this client hasn't already 412 // received this notification in order to 413 // ensure we don't duplicate any events. 414 415 // TODO(joostjager): Refactor switches. 416 state := event.invoice.State 417 switch { 418 // If we've already sent this settle event to 419 // the client, then we can skip this. 420 case state == channeldb.ContractSettled && 421 client.settleIndex >= invoice.SettleIndex: 422 continue 423 424 // Similarly, if we've already sent this add to 425 // the client then we can skip this one, but only if this isn't 426 // an AMP invoice. AMP invoices always remain in the settle 427 // state as a base invoice. 428 case event.setID == nil && state == channeldb.ContractOpen && 429 client.addIndex >= invoice.AddIndex: 430 continue 431 432 // These two states should never happen, but we 433 // log them just in case so we can detect this 434 // instance. 435 case state == channeldb.ContractOpen && 436 client.addIndex+1 != invoice.AddIndex: 437 log.Warnf("client=%v for invoice "+ 438 "notifications missed an update, "+ 439 "add_index=%v, new add event index=%v", 440 clientID, client.addIndex, 441 invoice.AddIndex) 442 443 case state == channeldb.ContractSettled && 444 client.settleIndex+1 != invoice.SettleIndex: 445 log.Warnf("client=%v for invoice "+ 446 "notifications missed an update, "+ 447 "settle_index=%v, new settle event index=%v", 448 clientID, client.settleIndex, 449 invoice.SettleIndex) 450 } 451 452 select { 453 case client.ntfnQueue.ChanIn() <- &invoiceEvent{ 454 invoice: invoice, 455 setID: event.setID, 456 }: 457 case <-i.quit: 458 return 459 } 460 461 // Each time we send a notification to a client, we'll record 462 // the latest add/settle index it has. We'll use this to ensure 463 // we don't send a notification twice, which can happen if a new 464 // event is added while we're catching up a new client. 465 invState := event.invoice.State 466 switch { 467 468 case invState == channeldb.ContractSettled: 469 client.settleIndex = invoice.SettleIndex 470 471 case invState == channeldb.ContractOpen && event.setID == nil: 472 client.addIndex = invoice.AddIndex 473 474 // If this is an AMP invoice, then we'll need to use the set ID 475 // to keep track of the settle index of the client. AMP 476 // invoices never go to the open state, but if a setID is 477 // passed, then we know it was just settled and will track the 478 // highest settle index so far. 479 case invState == channeldb.ContractOpen && event.setID != nil: 480 setID := *event.setID 481 client.settleIndex = invoice.AMPState[setID].SettleIndex 482 483 default: 484 log.Errorf("unexpected invoice state: %v", 485 event.invoice.State) 486 } 487 } 488 } 489 490 // deliverBacklogEvents will attempts to query the invoice database for any 491 // notifications that the client has missed since it reconnected last. 492 func (i *InvoiceRegistry) deliverBacklogEvents(client *InvoiceSubscription) error { 493 addEvents, err := i.cdb.InvoicesAddedSince(client.addIndex) 494 if err != nil { 495 return err 496 } 497 498 settleEvents, err := i.cdb.InvoicesSettledSince(client.settleIndex) 499 if err != nil { 500 return err 501 } 502 503 // If we have any to deliver, then we'll append them to the end of the 504 // notification queue in order to catch up the client before delivering 505 // any new notifications. 506 for _, addEvent := range addEvents { 507 // We re-bind the loop variable to ensure we don't hold onto 508 // the loop reference causing is to point to the same item. 509 addEvent := addEvent 510 511 select { 512 case client.ntfnQueue.ChanIn() <- &invoiceEvent{ 513 invoice: &addEvent, 514 }: 515 case <-i.quit: 516 return ErrShuttingDown 517 } 518 } 519 520 for _, settleEvent := range settleEvents { 521 // We re-bind the loop variable to ensure we don't hold onto 522 // the loop reference causing is to point to the same item. 523 settleEvent := settleEvent 524 525 select { 526 case client.ntfnQueue.ChanIn() <- &invoiceEvent{ 527 invoice: &settleEvent, 528 }: 529 case <-i.quit: 530 return ErrShuttingDown 531 } 532 } 533 534 return nil 535 } 536 537 // deliverSingleBacklogEvents will attempt to query the invoice database to 538 // retrieve the current invoice state and deliver this to the subscriber. Single 539 // invoice subscribers will always receive the current state right after 540 // subscribing. Only in case the invoice does not yet exist, nothing is sent 541 // yet. 542 func (i *InvoiceRegistry) deliverSingleBacklogEvents( 543 client *SingleInvoiceSubscription) error { 544 545 invoice, err := i.cdb.LookupInvoice(client.invoiceRef) 546 547 // It is possible that the invoice does not exist yet, but the client is 548 // already watching it in anticipation. 549 if err == channeldb.ErrInvoiceNotFound || 550 err == channeldb.ErrNoInvoicesCreated { 551 552 return nil 553 } 554 if err != nil { 555 return err 556 } 557 558 payHash := client.invoiceRef.PayHash() 559 if payHash == nil { 560 return nil 561 } 562 563 err = client.notify(&invoiceEvent{ 564 hash: *payHash, 565 invoice: &invoice, 566 }) 567 if err != nil { 568 return err 569 } 570 571 return nil 572 } 573 574 // AddInvoice adds a regular invoice for the specified amount, identified by 575 // the passed preimage. Additionally, any memo or receipt data provided will 576 // also be stored on-disk. Once this invoice is added, subsystems within the 577 // daemon add/forward HTLCs are able to obtain the proper preimage required for 578 // redemption in the case that we're the final destination. We also return the 579 // addIndex of the newly created invoice which monotonically increases for each 580 // new invoice added. A side effect of this function is that it also sets 581 // AddIndex on the invoice argument. 582 func (i *InvoiceRegistry) AddInvoice(invoice *channeldb.Invoice, 583 paymentHash lntypes.Hash) (uint64, error) { 584 585 i.Lock() 586 587 ref := channeldb.InvoiceRefByHash(paymentHash) 588 log.Debugf("Invoice%v: added with terms %v", ref, invoice.Terms) 589 590 addIndex, err := i.cdb.AddInvoice(invoice, paymentHash) 591 if err != nil { 592 i.Unlock() 593 return 0, err 594 } 595 596 // Now that we've added the invoice, we'll send dispatch a message to 597 // notify the clients of this new invoice. 598 i.notifyClients(paymentHash, invoice, nil) 599 i.Unlock() 600 601 // InvoiceExpiryWatcher.AddInvoice must not be locked by InvoiceRegistry 602 // to avoid deadlock when a new invoice is added while an other is being 603 // canceled. 604 invoiceExpiryRef := makeInvoiceExpiry(paymentHash, invoice) 605 if invoiceExpiryRef != nil { 606 i.expiryWatcher.AddInvoices(invoiceExpiryRef) 607 } 608 609 return addIndex, nil 610 } 611 612 // LookupInvoice looks up an invoice by its payment hash (R-Hash), if found 613 // then we're able to pull the funds pending within an HTLC. 614 // 615 // TODO(roasbeef): ignore if settled? 616 func (i *InvoiceRegistry) LookupInvoice(rHash lntypes.Hash) (channeldb.Invoice, 617 error) { 618 619 // We'll check the database to see if there's an existing matching 620 // invoice. 621 ref := channeldb.InvoiceRefByHash(rHash) 622 return i.cdb.LookupInvoice(ref) 623 } 624 625 // LookupInvoiceByRef looks up an invoice by the given reference, if found 626 // then we're able to pull the funds pending within an HTLC. 627 func (i *InvoiceRegistry) LookupInvoiceByRef( 628 ref channeldb.InvoiceRef) (channeldb.Invoice, error) { 629 630 return i.cdb.LookupInvoice(ref) 631 } 632 633 // startHtlcTimer starts a new timer via the invoice registry main loop that 634 // cancels a single htlc on an invoice when the htlc hold duration has passed. 635 func (i *InvoiceRegistry) startHtlcTimer(invoiceRef channeldb.InvoiceRef, 636 key channeldb.CircuitKey, acceptTime time.Time) error { 637 638 releaseTime := acceptTime.Add(i.cfg.HtlcHoldDuration) 639 event := &htlcReleaseEvent{ 640 invoiceRef: invoiceRef, 641 key: key, 642 releaseTime: releaseTime, 643 } 644 645 select { 646 case i.htlcAutoReleaseChan <- event: 647 return nil 648 649 case <-i.quit: 650 return ErrShuttingDown 651 } 652 } 653 654 // cancelSingleHtlc cancels a single accepted htlc on an invoice. It takes 655 // a resolution result which will be used to notify subscribed links and 656 // resolvers of the details of the htlc cancellation. 657 func (i *InvoiceRegistry) cancelSingleHtlc(invoiceRef channeldb.InvoiceRef, 658 key channeldb.CircuitKey, result FailResolutionResult) error { 659 660 i.Lock() 661 defer i.Unlock() 662 663 updateInvoice := func(invoice *channeldb.Invoice) ( 664 *channeldb.InvoiceUpdateDesc, error) { 665 666 // Only allow individual htlc cancelation on open invoices. 667 if invoice.State != channeldb.ContractOpen { 668 log.Debugf("cancelSingleHtlc: invoice %v no longer "+ 669 "open", invoiceRef) 670 671 return nil, nil 672 } 673 674 // Lookup the current status of the htlc in the database. 675 var ( 676 htlcState channeldb.HtlcState 677 setID *channeldb.SetID 678 ) 679 htlc, ok := invoice.Htlcs[key] 680 if !ok { 681 // If this is an AMP invoice, then all the HTLCs won't 682 // be read out, so we'll consult the other mapping to 683 // try to find the HTLC state in question here. 684 var found bool 685 for ampSetID, htlcSet := range invoice.AMPState { 686 ampSetID := ampSetID 687 for htlcKey := range htlcSet.InvoiceKeys { 688 if htlcKey == key { 689 htlcState = htlcSet.State 690 setID = &SetID 691 692 found = true 693 break 694 } 695 } 696 } 697 698 if !found { 699 return nil, fmt.Errorf("htlc %v not found", key) 700 } 701 } else { 702 htlcState = htlc.State 703 } 704 705 // Cancelation is only possible if the htlc wasn't already 706 // resolved. 707 if htlcState != channeldb.HtlcStateAccepted { 708 log.Debugf("cancelSingleHtlc: htlc %v on invoice %v "+ 709 "is already resolved", key, invoiceRef) 710 711 return nil, nil 712 } 713 714 log.Debugf("cancelSingleHtlc: cancelling htlc %v on invoice %v", 715 key, invoiceRef) 716 717 // Return an update descriptor that cancels htlc and keeps 718 // invoice open. 719 canceledHtlcs := map[channeldb.CircuitKey]struct{}{ 720 key: {}, 721 } 722 723 return &channeldb.InvoiceUpdateDesc{ 724 CancelHtlcs: canceledHtlcs, 725 SetID: setID, 726 }, nil 727 } 728 729 // Try to mark the specified htlc as canceled in the invoice database. 730 // Intercept the update descriptor to set the local updated variable. If 731 // no invoice update is performed, we can return early. 732 var updated bool 733 invoice, err := i.cdb.UpdateInvoice(invoiceRef, nil, 734 func(invoice *channeldb.Invoice) ( 735 *channeldb.InvoiceUpdateDesc, error) { 736 737 updateDesc, err := updateInvoice(invoice) 738 if err != nil { 739 return nil, err 740 } 741 updated = updateDesc != nil 742 743 return updateDesc, err 744 }, 745 ) 746 if err != nil { 747 return err 748 } 749 if !updated { 750 return nil 751 } 752 753 // The invoice has been updated. Notify subscribers of the htlc 754 // resolution. 755 htlc, ok := invoice.Htlcs[key] 756 if !ok { 757 return fmt.Errorf("htlc %v not found", key) 758 } 759 if htlc.State == channeldb.HtlcStateCanceled { 760 resolution := NewFailResolution( 761 key, int32(htlc.AcceptHeight), result, 762 ) 763 764 i.notifyHodlSubscribers(resolution) 765 } 766 return nil 767 } 768 769 // processKeySend just-in-time inserts an invoice if this htlc is a keysend 770 // htlc. 771 func (i *InvoiceRegistry) processKeySend(ctx invoiceUpdateCtx) error { 772 // Retrieve keysend record if present. 773 preimageSlice, ok := ctx.customRecords[record.KeySendType] 774 if !ok { 775 return nil 776 } 777 778 // Cancel htlc is preimage is invalid. 779 preimage, err := lntypes.MakePreimage(preimageSlice) 780 if err != nil || preimage.Hash() != ctx.hash { 781 return errors.New("invalid keysend preimage") 782 } 783 784 // Only allow keysend for non-mpp payments. 785 if ctx.mpp != nil { 786 return errors.New("no mpp keysend supported") 787 } 788 789 // Create an invoice for the htlc amount. 790 amt := ctx.amtPaid 791 792 // Set tlv optional feature vector on the invoice. Otherwise we wouldn't 793 // be able to pay to it with keysend. 794 rawFeatures := lnwire.NewRawFeatureVector( 795 lnwire.TLVOnionPayloadOptional, 796 ) 797 features := lnwire.NewFeatureVector(rawFeatures, lnwire.Features) 798 799 // Use the minimum block delta that we require for settling htlcs. 800 finalCltvDelta := i.cfg.FinalCltvRejectDelta 801 802 // Pre-check expiry here to prevent inserting an invoice that will not 803 // be settled. 804 if ctx.expiry < uint32(ctx.currentHeight+finalCltvDelta) { 805 return errors.New("final expiry too soon") 806 } 807 808 // The invoice database indexes all invoices by payment address, however 809 // legacy keysend payment do not have one. In order to avoid a new 810 // payment type on-disk wrt. to indexing, we'll continue to insert a 811 // blank payment address which is special cased in the insertion logic 812 // to not be indexed. In the future, once AMP is merged, this should be 813 // replaced by generating a random payment address on the behalf of the 814 // sender. 815 payAddr := channeldb.BlankPayAddr 816 817 // Create placeholder invoice. 818 invoice := &channeldb.Invoice{ 819 CreationDate: i.cfg.Clock.Now(), 820 Terms: channeldb.ContractTerm{ 821 FinalCltvDelta: finalCltvDelta, 822 Value: amt, 823 PaymentPreimage: &preimage, 824 PaymentAddr: payAddr, 825 Features: features, 826 }, 827 } 828 829 if i.cfg.KeysendHoldTime != 0 { 830 invoice.HodlInvoice = true 831 invoice.Terms.Expiry = i.cfg.KeysendHoldTime 832 } 833 834 // Insert invoice into database. Ignore duplicates, because this 835 // may be a replay. 836 _, err = i.AddInvoice(invoice, ctx.hash) 837 if err != nil && err != channeldb.ErrDuplicateInvoice { 838 return err 839 } 840 841 return nil 842 } 843 844 // processAMP just-in-time inserts an invoice if this htlc is a keysend 845 // htlc. 846 func (i *InvoiceRegistry) processAMP(ctx invoiceUpdateCtx) error { 847 // AMP payments MUST also include an MPP record. 848 if ctx.mpp == nil { 849 return errors.New("no MPP record for AMP") 850 } 851 852 // Create an invoice for the total amount expected, provided in the MPP 853 // record. 854 amt := ctx.mpp.TotalMAtoms() 855 856 // Set the TLV and MPP optional features on the invoice. We'll also make 857 // the AMP features required so that it can't be paid by legacy or MPP 858 // htlcs. 859 rawFeatures := lnwire.NewRawFeatureVector( 860 lnwire.TLVOnionPayloadOptional, 861 lnwire.PaymentAddrOptional, 862 lnwire.AMPRequired, 863 ) 864 features := lnwire.NewFeatureVector(rawFeatures, lnwire.Features) 865 866 // Use the minimum block delta that we require for settling htlcs. 867 finalCltvDelta := i.cfg.FinalCltvRejectDelta 868 869 // Pre-check expiry here to prevent inserting an invoice that will not 870 // be settled. 871 if ctx.expiry < uint32(ctx.currentHeight+finalCltvDelta) { 872 return errors.New("final expiry too soon") 873 } 874 875 // We'll use the sender-generated payment address provided in the HTLC 876 // to create our AMP invoice. 877 payAddr := ctx.mpp.PaymentAddr() 878 879 // Create placeholder invoice. 880 invoice := &channeldb.Invoice{ 881 CreationDate: i.cfg.Clock.Now(), 882 Terms: channeldb.ContractTerm{ 883 FinalCltvDelta: finalCltvDelta, 884 Value: amt, 885 PaymentPreimage: nil, 886 PaymentAddr: payAddr, 887 Features: features, 888 }, 889 } 890 891 // Insert invoice into database. Ignore duplicates payment hashes and 892 // payment addrs, this may be a replay or a different HTLC for the AMP 893 // invoice. 894 _, err := i.AddInvoice(invoice, ctx.hash) 895 switch { 896 case err == channeldb.ErrDuplicateInvoice: 897 return nil 898 case err == channeldb.ErrDuplicatePayAddr: 899 return nil 900 default: 901 return err 902 } 903 } 904 905 // NotifyExitHopHtlc attempts to mark an invoice as settled. The return value 906 // describes how the htlc should be resolved. 907 // 908 // When the preimage of the invoice is not yet known (hodl invoice), this 909 // function moves the invoice to the accepted state. When SettleHoldInvoice is 910 // called later, a resolution message will be send back to the caller via the 911 // provided hodlChan. Invoice registry sends on this channel what action needs 912 // to be taken on the htlc (settle or cancel). The caller needs to ensure that 913 // the channel is either buffered or received on from another goroutine to 914 // prevent deadlock. 915 // 916 // In the case that the htlc is part of a larger set of htlcs that pay to the 917 // same invoice (multi-path payment), the htlc is held until the set is 918 // complete. If the set doesn't fully arrive in time, a timer will cancel the 919 // held htlc. 920 func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, 921 amtPaid lnwire.MilliAtom, expiry uint32, currentHeight int32, 922 circuitKey channeldb.CircuitKey, hodlChan chan<- interface{}, 923 payload Payload) (HtlcResolution, error) { 924 925 // Create the update context containing the relevant details of the 926 // incoming htlc. 927 ctx := invoiceUpdateCtx{ 928 hash: rHash, 929 circuitKey: circuitKey, 930 amtPaid: amtPaid, 931 expiry: expiry, 932 currentHeight: currentHeight, 933 finalCltvRejectDelta: i.cfg.FinalCltvRejectDelta, 934 customRecords: payload.CustomRecords(), 935 mpp: payload.MultiPath(), 936 amp: payload.AMPRecord(), 937 } 938 939 switch { 940 941 // If we are accepting spontaneous AMP payments and this payload 942 // contains an AMP record, create an AMP invoice that will be settled 943 // below. 944 case i.cfg.AcceptAMP && ctx.amp != nil: 945 err := i.processAMP(ctx) 946 if err != nil { 947 ctx.log(fmt.Sprintf("amp error: %v", err)) 948 949 return NewFailResolution( 950 circuitKey, currentHeight, ResultAmpError, 951 ), nil 952 } 953 954 // If we are accepting spontaneous keysend payments, create a regular 955 // invoice that will be settled below. We also enforce that this is only 956 // done when no AMP payload is present since it will only be settle-able 957 // by regular HTLCs. 958 case i.cfg.AcceptKeySend && ctx.amp == nil: 959 err := i.processKeySend(ctx) 960 if err != nil { 961 ctx.log(fmt.Sprintf("keysend error: %v", err)) 962 963 return NewFailResolution( 964 circuitKey, currentHeight, ResultKeySendError, 965 ), nil 966 } 967 } 968 969 // Execute locked notify exit hop logic. 970 i.Lock() 971 resolution, invoiceToExpire, err := i.notifyExitHopHtlcLocked( 972 &ctx, hodlChan, 973 ) 974 i.Unlock() 975 if err != nil { 976 return nil, err 977 } 978 979 if invoiceToExpire != nil { 980 i.expiryWatcher.AddInvoices(invoiceToExpire) 981 } 982 983 switch r := resolution.(type) { 984 // The htlc is held. Start a timer outside the lock if the htlc should 985 // be auto-released, because otherwise a deadlock may happen with the 986 // main event loop. 987 case *htlcAcceptResolution: 988 if r.autoRelease { 989 err := i.startHtlcTimer( 990 ctx.invoiceRef(), circuitKey, r.acceptTime, 991 ) 992 if err != nil { 993 return nil, err 994 } 995 } 996 997 // We return a nil resolution because htlc acceptances are 998 // represented as nil resolutions externally. 999 // TODO(carla) update calling code to handle accept resolutions. 1000 return nil, nil 1001 1002 // A direct resolution was received for this htlc. 1003 case HtlcResolution: 1004 return r, nil 1005 1006 // Fail if an unknown resolution type was received. 1007 default: 1008 return nil, errors.New("invalid resolution type") 1009 } 1010 } 1011 1012 // notifyExitHopHtlcLocked is the internal implementation of NotifyExitHopHtlc 1013 // that should be executed inside the registry lock. The returned invoiceExpiry 1014 // (if not nil) needs to be added to the expiry watcher outside of the lock. 1015 func (i *InvoiceRegistry) notifyExitHopHtlcLocked( 1016 ctx *invoiceUpdateCtx, hodlChan chan<- interface{}) ( 1017 HtlcResolution, invoiceExpiry, error) { 1018 1019 // We'll attempt to settle an invoice matching this rHash on disk (if 1020 // one exists). The callback will update the invoice state and/or htlcs. 1021 var ( 1022 resolution HtlcResolution 1023 updateSubscribers bool 1024 ) 1025 invoice, err := i.cdb.UpdateInvoice( 1026 ctx.invoiceRef(), 1027 (*channeldb.SetID)(ctx.setID()), 1028 func(inv *channeldb.Invoice) ( 1029 *channeldb.InvoiceUpdateDesc, error) { 1030 1031 updateDesc, res, err := updateInvoice(ctx, inv) 1032 if err != nil { 1033 return nil, err 1034 } 1035 1036 // Only send an update if the invoice state was changed. 1037 updateSubscribers = updateDesc != nil && 1038 updateDesc.State != nil 1039 1040 // Assign resolution to outer scope variable. 1041 resolution = res 1042 1043 return updateDesc, nil 1044 }, 1045 ) 1046 switch err { 1047 case channeldb.ErrInvoiceNotFound: 1048 // If the invoice was not found, return a failure resolution 1049 // with an invoice not found result. 1050 return NewFailResolution( 1051 ctx.circuitKey, ctx.currentHeight, 1052 ResultInvoiceNotFound, 1053 ), nil, nil 1054 1055 case nil: 1056 1057 default: 1058 ctx.log(err.Error()) 1059 return nil, nil, err 1060 } 1061 1062 var invoiceToExpire invoiceExpiry 1063 1064 switch res := resolution.(type) { 1065 case *HtlcFailResolution: 1066 // Inspect latest htlc state on the invoice. If it is found, 1067 // we will update the accept height as it was recorded in the 1068 // invoice database (which occurs in the case where the htlc 1069 // reached the database in a previous call). If the htlc was 1070 // not found on the invoice, it was immediately failed so we 1071 // send the failure resolution as is, which has the current 1072 // height set as the accept height. 1073 invoiceHtlc, ok := invoice.Htlcs[ctx.circuitKey] 1074 if ok { 1075 res.AcceptHeight = int32(invoiceHtlc.AcceptHeight) 1076 } 1077 1078 ctx.log(fmt.Sprintf("failure resolution result "+ 1079 "outcome: %v, at accept height: %v", 1080 res.Outcome, res.AcceptHeight)) 1081 1082 // Some failures apply to the entire HTLC set. Break here if 1083 // this isn't one of them. 1084 if !res.Outcome.IsSetFailure() { 1085 break 1086 } 1087 1088 // Also cancel any HTLCs in the HTLC set that are also in the 1089 // canceled state with the same failure result. 1090 setID := ctx.setID() 1091 canceledHtlcSet := invoice.HTLCSet(setID, channeldb.HtlcStateCanceled) 1092 for key, htlc := range canceledHtlcSet { 1093 htlcFailResolution := NewFailResolution( 1094 key, int32(htlc.AcceptHeight), res.Outcome, 1095 ) 1096 1097 i.notifyHodlSubscribers(htlcFailResolution) 1098 } 1099 1100 // If the htlc was settled, we will settle any previously accepted 1101 // htlcs and notify our peer to settle them. 1102 case *HtlcSettleResolution: 1103 ctx.log(fmt.Sprintf("settle resolution result "+ 1104 "outcome: %v, at accept height: %v", 1105 res.Outcome, res.AcceptHeight)) 1106 1107 // Also settle any previously accepted htlcs. If a htlc is 1108 // marked as settled, we should follow now and settle the htlc 1109 // with our peer. 1110 setID := ctx.setID() 1111 settledHtlcSet := invoice.HTLCSet(setID, channeldb.HtlcStateSettled) 1112 for key, htlc := range settledHtlcSet { 1113 preimage := res.Preimage 1114 if htlc.AMP != nil && htlc.AMP.Preimage != nil { 1115 preimage = *htlc.AMP.Preimage 1116 } 1117 1118 // Notify subscribers that the htlcs should be settled 1119 // with our peer. Note that the outcome of the 1120 // resolution is set based on the outcome of the single 1121 // htlc that we just settled, so may not be accurate 1122 // for all htlcs. 1123 htlcSettleResolution := NewSettleResolution( 1124 preimage, key, 1125 int32(htlc.AcceptHeight), res.Outcome, 1126 ) 1127 1128 // Notify subscribers that the htlc should be settled 1129 // with our peer. 1130 i.notifyHodlSubscribers(htlcSettleResolution) 1131 } 1132 1133 // If concurrent payments were attempted to this invoice before 1134 // the current one was ultimately settled, cancel back any of 1135 // the HTLCs immediately. As a result of the settle, the HTLCs 1136 // in other HTLC sets are automatically converted to a canceled 1137 // state when updating the invoice. 1138 // 1139 // TODO(roasbeef): can remove now?? 1140 canceledHtlcSet := invoice.HTLCSetCompliment( 1141 setID, channeldb.HtlcStateCanceled, 1142 ) 1143 for key, htlc := range canceledHtlcSet { 1144 htlcFailResolution := NewFailResolution( 1145 key, int32(htlc.AcceptHeight), 1146 ResultInvoiceAlreadySettled, 1147 ) 1148 1149 i.notifyHodlSubscribers(htlcFailResolution) 1150 } 1151 1152 // If we accepted the htlc, subscribe to the hodl invoice and return 1153 // an accept resolution with the htlc's accept time on it. 1154 case *htlcAcceptResolution: 1155 invoiceHtlc, ok := invoice.Htlcs[ctx.circuitKey] 1156 if !ok { 1157 return nil, nil, fmt.Errorf("accepted htlc: %v not"+ 1158 " present on invoice: %x", ctx.circuitKey, 1159 ctx.hash[:]) 1160 } 1161 1162 // Determine accepted height of this htlc. If the htlc reached 1163 // the invoice database (possibly in a previous call to the 1164 // invoice registry), we'll take the original accepted height 1165 // as it was recorded in the database. 1166 acceptHeight := int32(invoiceHtlc.AcceptHeight) 1167 1168 ctx.log(fmt.Sprintf("accept resolution result "+ 1169 "outcome: %v, at accept height: %v", 1170 res.outcome, acceptHeight)) 1171 1172 // Auto-release the htlc if the invoice is still open. It can 1173 // only happen for mpp payments that there are htlcs in state 1174 // Accepted while the invoice is Open. 1175 if invoice.State == channeldb.ContractOpen { 1176 res.acceptTime = invoiceHtlc.AcceptTime 1177 res.autoRelease = true 1178 } 1179 1180 // If we have fully accepted the set of htlcs for this invoice, 1181 // we can now add it to our invoice expiry watcher. We do not 1182 // add invoices before they are fully accepted, because it is 1183 // possible that we MppTimeout the htlcs, and then our relevant 1184 // expiry height could change. 1185 if res.outcome == resultAccepted { 1186 invoiceToExpire = makeInvoiceExpiry(ctx.hash, invoice) 1187 } 1188 1189 i.hodlSubscribe(hodlChan, ctx.circuitKey) 1190 1191 default: 1192 panic("unknown action") 1193 } 1194 1195 // Now that the links have been notified of any state changes to their 1196 // HTLCs, we'll go ahead and notify any clients wiaiting on the invoice 1197 // state changes. 1198 if updateSubscribers { 1199 // We'll add a setID onto the notification, but only if this is 1200 // an AMP invoice being settled. 1201 var setID *[32]byte 1202 if _, ok := resolution.(*HtlcSettleResolution); ok { 1203 setID = ctx.setID() 1204 } 1205 1206 i.notifyClients(ctx.hash, invoice, setID) 1207 } 1208 1209 return resolution, invoiceToExpire, nil 1210 } 1211 1212 // SettleHodlInvoice sets the preimage of a hodl invoice. 1213 func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error { 1214 i.Lock() 1215 defer i.Unlock() 1216 1217 updateInvoice := func(invoice *channeldb.Invoice) ( 1218 *channeldb.InvoiceUpdateDesc, error) { 1219 1220 switch invoice.State { 1221 case channeldb.ContractOpen: 1222 return nil, channeldb.ErrInvoiceStillOpen 1223 case channeldb.ContractCanceled: 1224 return nil, channeldb.ErrInvoiceAlreadyCanceled 1225 case channeldb.ContractSettled: 1226 return nil, channeldb.ErrInvoiceAlreadySettled 1227 } 1228 1229 return &channeldb.InvoiceUpdateDesc{ 1230 State: &channeldb.InvoiceStateUpdateDesc{ 1231 NewState: channeldb.ContractSettled, 1232 Preimage: &preimage, 1233 }, 1234 }, nil 1235 } 1236 1237 hash := preimage.Hash() 1238 invoiceRef := channeldb.InvoiceRefByHash(hash) 1239 invoice, err := i.cdb.UpdateInvoice(invoiceRef, nil, updateInvoice) 1240 if err != nil { 1241 log.Errorf("SettleHodlInvoice with preimage %v: %v", 1242 preimage, err) 1243 1244 return err 1245 } 1246 1247 log.Debugf("Invoice%v: settled with preimage %v", invoiceRef, 1248 invoice.Terms.PaymentPreimage) 1249 1250 // In the callback, we marked the invoice as settled. UpdateInvoice will 1251 // have seen this and should have moved all htlcs that were accepted to 1252 // the settled state. In the loop below, we go through all of these and 1253 // notify links and resolvers that are waiting for resolution. Any htlcs 1254 // that were already settled before, will be notified again. This isn't 1255 // necessary but doesn't hurt either. 1256 for key, htlc := range invoice.Htlcs { 1257 if htlc.State != channeldb.HtlcStateSettled { 1258 continue 1259 } 1260 1261 resolution := NewSettleResolution( 1262 preimage, key, int32(htlc.AcceptHeight), ResultSettled, 1263 ) 1264 1265 i.notifyHodlSubscribers(resolution) 1266 } 1267 i.notifyClients(hash, invoice, nil) 1268 1269 return nil 1270 } 1271 1272 // CancelInvoice attempts to cancel the invoice corresponding to the passed 1273 // payment hash. 1274 func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error { 1275 return i.cancelInvoiceImpl(payHash, true) 1276 } 1277 1278 // shouldCancel examines the state of an invoice and whether we want to 1279 // cancel already accepted invoices, taking our force cancel boolean into 1280 // account. This is pulled out into its own function so that tests that mock 1281 // cancelInvoiceImpl can reuse this logic. 1282 func shouldCancel(state channeldb.ContractState, cancelAccepted bool) bool { 1283 if state != channeldb.ContractAccepted { 1284 return true 1285 } 1286 1287 // If the invoice is accepted, we should only cancel if we want to 1288 // force cancelation of accepted invoices. 1289 return cancelAccepted 1290 } 1291 1292 // cancelInvoice attempts to cancel the invoice corresponding to the passed 1293 // payment hash. Accepted invoices will only be canceled if explicitly 1294 // requested to do so. It notifies subscribing links and resolvers that 1295 // the associated htlcs were canceled if they change state. 1296 func (i *InvoiceRegistry) cancelInvoiceImpl(payHash lntypes.Hash, 1297 cancelAccepted bool) error { 1298 1299 i.Lock() 1300 defer i.Unlock() 1301 1302 ref := channeldb.InvoiceRefByHash(payHash) 1303 log.Debugf("Invoice%v: canceling invoice", ref) 1304 1305 updateInvoice := func(invoice *channeldb.Invoice) ( 1306 *channeldb.InvoiceUpdateDesc, error) { 1307 1308 if !shouldCancel(invoice.State, cancelAccepted) { 1309 return nil, nil 1310 } 1311 1312 // Move invoice to the canceled state. Rely on validation in 1313 // channeldb to return an error if the invoice is already 1314 // settled or canceled. 1315 return &channeldb.InvoiceUpdateDesc{ 1316 State: &channeldb.InvoiceStateUpdateDesc{ 1317 NewState: channeldb.ContractCanceled, 1318 }, 1319 }, nil 1320 } 1321 1322 invoiceRef := channeldb.InvoiceRefByHash(payHash) 1323 invoice, err := i.cdb.UpdateInvoice(invoiceRef, nil, updateInvoice) 1324 1325 // Implement idempotency by returning success if the invoice was already 1326 // canceled. 1327 if err == channeldb.ErrInvoiceAlreadyCanceled { 1328 log.Debugf("Invoice%v: already canceled", ref) 1329 return nil 1330 } 1331 if err != nil { 1332 return err 1333 } 1334 1335 // Return without cancellation if the invoice state is ContractAccepted. 1336 if invoice.State == channeldb.ContractAccepted { 1337 log.Debugf("Invoice%v: remains accepted as cancel wasn't"+ 1338 "explicitly requested.", ref) 1339 return nil 1340 } 1341 1342 log.Debugf("Invoice%v: canceled", ref) 1343 1344 // In the callback, some htlcs may have been moved to the canceled 1345 // state. We now go through all of these and notify links and resolvers 1346 // that are waiting for resolution. Any htlcs that were already canceled 1347 // before, will be notified again. This isn't necessary but doesn't hurt 1348 // either. 1349 for key, htlc := range invoice.Htlcs { 1350 if htlc.State != channeldb.HtlcStateCanceled { 1351 continue 1352 } 1353 1354 i.notifyHodlSubscribers( 1355 NewFailResolution( 1356 key, int32(htlc.AcceptHeight), ResultCanceled, 1357 ), 1358 ) 1359 } 1360 i.notifyClients(payHash, invoice, nil) 1361 1362 // Attempt to also delete the invoice if requested through the registry 1363 // config. 1364 if i.cfg.GcCanceledInvoicesOnTheFly { 1365 // Assemble the delete reference and attempt to delete through 1366 // the invocice from the DB. 1367 deleteRef := channeldb.InvoiceDeleteRef{ 1368 PayHash: payHash, 1369 AddIndex: invoice.AddIndex, 1370 SettleIndex: invoice.SettleIndex, 1371 } 1372 if invoice.Terms.PaymentAddr != channeldb.BlankPayAddr { 1373 deleteRef.PayAddr = &invoice.Terms.PaymentAddr 1374 } 1375 1376 err = i.cdb.DeleteInvoice( 1377 []channeldb.InvoiceDeleteRef{deleteRef}, 1378 ) 1379 // If by any chance deletion failed, then log it instead of 1380 // returning the error, as the invoice itsels has already been 1381 // canceled. 1382 if err != nil { 1383 log.Warnf("Invoice%v could not be deleted: %v", 1384 ref, err) 1385 } 1386 } 1387 1388 return nil 1389 } 1390 1391 // notifyClients notifies all currently registered invoice notification clients 1392 // of a newly added/settled invoice. 1393 func (i *InvoiceRegistry) notifyClients(hash lntypes.Hash, 1394 invoice *channeldb.Invoice, setID *[32]byte) { 1395 1396 event := &invoiceEvent{ 1397 invoice: invoice, 1398 hash: hash, 1399 setID: setID, 1400 } 1401 1402 select { 1403 case i.invoiceEvents <- event: 1404 case <-i.quit: 1405 } 1406 } 1407 1408 // invoiceSubscriptionKit defines that are common to both all invoice 1409 // subscribers and single invoice subscribers. 1410 type invoiceSubscriptionKit struct { 1411 id uint32 1412 inv *InvoiceRegistry 1413 ntfnQueue *queue.ConcurrentQueue 1414 1415 canceled uint32 // To be used atomically. 1416 cancelChan chan struct{} 1417 wg sync.WaitGroup 1418 } 1419 1420 // InvoiceSubscription represents an intent to receive updates for newly added 1421 // or settled invoices. For each newly added invoice, a copy of the invoice 1422 // will be sent over the NewInvoices channel. Similarly, for each newly settled 1423 // invoice, a copy of the invoice will be sent over the SettledInvoices 1424 // channel. 1425 type InvoiceSubscription struct { 1426 invoiceSubscriptionKit 1427 1428 // NewInvoices is a channel that we'll use to send all newly created 1429 // invoices with an invoice index greater than the specified 1430 // StartingInvoiceIndex field. 1431 NewInvoices chan *channeldb.Invoice 1432 1433 // SettledInvoices is a channel that we'll use to send all setted 1434 // invoices with an invoices index greater than the specified 1435 // StartingInvoiceIndex field. 1436 SettledInvoices chan *channeldb.Invoice 1437 1438 // addIndex is the highest add index the caller knows of. We'll use 1439 // this information to send out an event backlog to the notifications 1440 // subscriber. Any new add events with an index greater than this will 1441 // be dispatched before any new notifications are sent out. 1442 addIndex uint64 1443 1444 // settleIndex is the highest settle index the caller knows of. We'll 1445 // use this information to send out an event backlog to the 1446 // notifications subscriber. Any new settle events with an index 1447 // greater than this will be dispatched before any new notifications 1448 // are sent out. 1449 settleIndex uint64 1450 } 1451 1452 // SingleInvoiceSubscription represents an intent to receive updates for a 1453 // specific invoice. 1454 type SingleInvoiceSubscription struct { 1455 invoiceSubscriptionKit 1456 1457 invoiceRef channeldb.InvoiceRef 1458 1459 // Updates is a channel that we'll use to send all invoice events for 1460 // the invoice that is subscribed to. 1461 Updates chan *channeldb.Invoice 1462 } 1463 1464 // Cancel unregisters the InvoiceSubscription, freeing any previously allocated 1465 // resources. 1466 func (i *invoiceSubscriptionKit) Cancel() { 1467 if !atomic.CompareAndSwapUint32(&i.canceled, 0, 1) { 1468 return 1469 } 1470 1471 select { 1472 case i.inv.subscriptionCancels <- i.id: 1473 case <-i.inv.quit: 1474 } 1475 1476 i.ntfnQueue.Stop() 1477 close(i.cancelChan) 1478 1479 i.wg.Wait() 1480 } 1481 1482 func (i *invoiceSubscriptionKit) notify(event *invoiceEvent) error { 1483 select { 1484 case i.ntfnQueue.ChanIn() <- event: 1485 case <-i.inv.quit: 1486 return ErrShuttingDown 1487 } 1488 1489 return nil 1490 } 1491 1492 // SubscribeNotifications returns an InvoiceSubscription which allows the 1493 // caller to receive async notifications when any invoices are settled or 1494 // added. The invoiceIndex parameter is a streaming "checkpoint". We'll start 1495 // by first sending out all new events with an invoice index _greater_ than 1496 // this value. Afterwards, we'll send out real-time notifications. 1497 func (i *InvoiceRegistry) SubscribeNotifications( 1498 addIndex, settleIndex uint64) (*InvoiceSubscription, error) { 1499 1500 client := &InvoiceSubscription{ 1501 NewInvoices: make(chan *channeldb.Invoice), 1502 SettledInvoices: make(chan *channeldb.Invoice), 1503 addIndex: addIndex, 1504 settleIndex: settleIndex, 1505 invoiceSubscriptionKit: invoiceSubscriptionKit{ 1506 inv: i, 1507 ntfnQueue: queue.NewConcurrentQueue(20), 1508 cancelChan: make(chan struct{}), 1509 }, 1510 } 1511 client.ntfnQueue.Start() 1512 1513 i.clientMtx.Lock() 1514 client.id = i.nextClientID 1515 i.nextClientID++ 1516 i.clientMtx.Unlock() 1517 1518 // Before we register this new invoice subscription, we'll launch a new 1519 // goroutine that will proxy all notifications appended to the end of 1520 // the concurrent queue to the two client-side channels the caller will 1521 // feed off of. 1522 i.wg.Add(1) 1523 go func() { 1524 defer i.wg.Done() 1525 1526 for { 1527 select { 1528 // A new invoice event has been sent by the 1529 // invoiceRegistry! We'll figure out if this is an add 1530 // event or a settle event, then dispatch the event to 1531 // the client. 1532 case ntfn := <-client.ntfnQueue.ChanOut(): 1533 invoiceEvent := ntfn.(*invoiceEvent) 1534 1535 var targetChan chan *channeldb.Invoice 1536 state := invoiceEvent.invoice.State 1537 switch { 1538 // AMP invoices never move to settled, but will 1539 // be sent with a set ID if an HTLC set is 1540 // being settled. 1541 case state == channeldb.ContractOpen && 1542 invoiceEvent.setID != nil: 1543 fallthrough 1544 case state == channeldb.ContractSettled: 1545 targetChan = client.SettledInvoices 1546 1547 case state == channeldb.ContractOpen: 1548 targetChan = client.NewInvoices 1549 1550 default: 1551 log.Errorf("unknown invoice "+ 1552 "state: %v", state) 1553 1554 continue 1555 } 1556 1557 select { 1558 case targetChan <- invoiceEvent.invoice: 1559 1560 case <-client.cancelChan: 1561 return 1562 1563 case <-i.quit: 1564 return 1565 } 1566 1567 case <-client.cancelChan: 1568 return 1569 1570 case <-i.quit: 1571 return 1572 } 1573 } 1574 }() 1575 1576 i.Lock() 1577 defer i.Unlock() 1578 1579 // Query the database to see if based on the provided addIndex and 1580 // settledIndex we need to deliver any backlog notifications. 1581 err := i.deliverBacklogEvents(client) 1582 if err != nil { 1583 return nil, err 1584 } 1585 1586 select { 1587 case i.newSubscriptions <- client: 1588 case <-i.quit: 1589 return nil, ErrShuttingDown 1590 } 1591 1592 return client, nil 1593 } 1594 1595 // SubscribeSingleInvoice returns an SingleInvoiceSubscription which allows the 1596 // caller to receive async notifications for a specific invoice. 1597 func (i *InvoiceRegistry) SubscribeSingleInvoice( 1598 hash lntypes.Hash) (*SingleInvoiceSubscription, error) { 1599 1600 client := &SingleInvoiceSubscription{ 1601 Updates: make(chan *channeldb.Invoice), 1602 invoiceSubscriptionKit: invoiceSubscriptionKit{ 1603 inv: i, 1604 ntfnQueue: queue.NewConcurrentQueue(20), 1605 cancelChan: make(chan struct{}), 1606 }, 1607 invoiceRef: channeldb.InvoiceRefByHash(hash), 1608 } 1609 client.ntfnQueue.Start() 1610 1611 i.clientMtx.Lock() 1612 client.id = i.nextClientID 1613 i.nextClientID++ 1614 i.clientMtx.Unlock() 1615 1616 // Before we register this new invoice subscription, we'll launch a new 1617 // goroutine that will proxy all notifications appended to the end of 1618 // the concurrent queue to the two client-side channels the caller will 1619 // feed off of. 1620 i.wg.Add(1) 1621 go func() { 1622 defer i.wg.Done() 1623 1624 for { 1625 select { 1626 // A new invoice event has been sent by the 1627 // invoiceRegistry. We will dispatch the event to the 1628 // client. 1629 case ntfn := <-client.ntfnQueue.ChanOut(): 1630 invoiceEvent := ntfn.(*invoiceEvent) 1631 1632 select { 1633 case client.Updates <- invoiceEvent.invoice: 1634 1635 case <-client.cancelChan: 1636 return 1637 1638 case <-i.quit: 1639 return 1640 } 1641 1642 case <-client.cancelChan: 1643 return 1644 1645 case <-i.quit: 1646 return 1647 } 1648 } 1649 }() 1650 1651 // Within the lock, we both query the invoice state and pass the client 1652 // subscription to the invoiceEvents channel. This is to make sure that 1653 // the client receives a consistent stream of events. 1654 i.Lock() 1655 defer i.Unlock() 1656 1657 err := i.deliverSingleBacklogEvents(client) 1658 if err != nil { 1659 return nil, err 1660 } 1661 1662 select { 1663 case i.invoiceEvents <- client: 1664 case <-i.quit: 1665 return nil, ErrShuttingDown 1666 } 1667 1668 return client, nil 1669 } 1670 1671 // notifyHodlSubscribers sends out the htlc resolution to all current 1672 // subscribers. 1673 func (i *InvoiceRegistry) notifyHodlSubscribers(htlcResolution HtlcResolution) { 1674 subscribers, ok := i.hodlSubscriptions[htlcResolution.CircuitKey()] 1675 if !ok { 1676 return 1677 } 1678 1679 // Notify all interested subscribers and remove subscription from both 1680 // maps. The subscription can be removed as there only ever will be a 1681 // single resolution for each hash. 1682 for subscriber := range subscribers { 1683 select { 1684 case subscriber <- htlcResolution: 1685 case <-i.quit: 1686 return 1687 } 1688 1689 delete( 1690 i.hodlReverseSubscriptions[subscriber], 1691 htlcResolution.CircuitKey(), 1692 ) 1693 } 1694 1695 delete(i.hodlSubscriptions, htlcResolution.CircuitKey()) 1696 } 1697 1698 // hodlSubscribe adds a new invoice subscription. 1699 func (i *InvoiceRegistry) hodlSubscribe(subscriber chan<- interface{}, 1700 circuitKey channeldb.CircuitKey) { 1701 1702 log.Debugf("Hodl subscribe for %v", circuitKey) 1703 1704 subscriptions, ok := i.hodlSubscriptions[circuitKey] 1705 if !ok { 1706 subscriptions = make(map[chan<- interface{}]struct{}) 1707 i.hodlSubscriptions[circuitKey] = subscriptions 1708 } 1709 subscriptions[subscriber] = struct{}{} 1710 1711 reverseSubscriptions, ok := i.hodlReverseSubscriptions[subscriber] 1712 if !ok { 1713 reverseSubscriptions = make(map[channeldb.CircuitKey]struct{}) 1714 i.hodlReverseSubscriptions[subscriber] = reverseSubscriptions 1715 } 1716 reverseSubscriptions[circuitKey] = struct{}{} 1717 } 1718 1719 // HodlUnsubscribeAll cancels the subscription. 1720 func (i *InvoiceRegistry) HodlUnsubscribeAll(subscriber chan<- interface{}) { 1721 i.Lock() 1722 defer i.Unlock() 1723 1724 hashes := i.hodlReverseSubscriptions[subscriber] 1725 for hash := range hashes { 1726 delete(i.hodlSubscriptions[hash], subscriber) 1727 } 1728 1729 delete(i.hodlReverseSubscriptions, subscriber) 1730 }