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 = &ampSetID
   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  }