github.com/decred/dcrlnd@v0.7.6/contractcourt/utxonursery.go (about)

     1  package contractcourt
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"io"
     8  	"sync"
     9  	"sync/atomic"
    10  
    11  	"github.com/davecgh/go-spew/spew"
    12  	"github.com/decred/dcrd/dcrutil/v4"
    13  	"github.com/decred/dcrd/wire"
    14  	"github.com/decred/dcrlnd/chainntnfs"
    15  	"github.com/decred/dcrlnd/channeldb"
    16  	"github.com/decred/dcrlnd/input"
    17  	"github.com/decred/dcrlnd/labels"
    18  	"github.com/decred/dcrlnd/lnwallet"
    19  	"github.com/decred/dcrlnd/sweep"
    20  )
    21  
    22  //                          SUMMARY OF OUTPUT STATES
    23  //
    24  //  - CRIB
    25  //    - SerializedType: babyOutput
    26  //    - OriginalOutputType: HTLC
    27  //    - Awaiting: First-stage HTLC CLTV expiry
    28  //    - HeightIndexEntry: Absolute block height of CLTV expiry.
    29  //    - NextState: KNDR
    30  //  - PSCL
    31  //    - SerializedType: kidOutput
    32  //    - OriginalOutputType: Commitment
    33  //    - Awaiting: Confirmation of commitment txn
    34  //    - HeightIndexEntry: None.
    35  //    - NextState: KNDR
    36  //  - KNDR
    37  //    - SerializedType: kidOutput
    38  //    - OriginalOutputType: Commitment or HTLC
    39  //    - Awaiting: Commitment CSV expiry or second-stage HTLC CSV expiry.
    40  //    - HeightIndexEntry: Input confirmation height + relative CSV delay
    41  //    - NextState: GRAD
    42  //  - GRAD:
    43  //    - SerializedType: kidOutput
    44  //    - OriginalOutputType: Commitment or HTLC
    45  //    - Awaiting: All other outputs in channel to become GRAD.
    46  //    - NextState: Mark channel fully closed in channeldb and remove.
    47  //
    48  //                        DESCRIPTION OF OUTPUT STATES
    49  //
    50  // TODO(roasbeef): update comment with both new output types
    51  //
    52  //  - CRIB (babyOutput) outputs are two-stage htlc outputs that are initially
    53  //    locked using a CLTV delay, followed by a CSV delay. The first stage of a
    54  //    crib output requires broadcasting a presigned htlc timeout txn generated
    55  //    by the wallet after an absolute expiry height. Since the timeout txns are
    56  //    predetermined, they cannot be batched after-the-fact, meaning that all
    57  //    CRIB outputs are broadcast and confirmed independently. After the first
    58  //    stage is complete, a CRIB output is moved to the KNDR state, which will
    59  //    finishing sweeping the second-layer CSV delay.
    60  //
    61  //  - PSCL (kidOutput) outputs are commitment outputs locked under a CSV delay.
    62  //    These outputs are stored temporarily in this state until the commitment
    63  //    transaction confirms, as this solidifies an absolute height that the
    64  //    relative time lock will expire. Once this maturity height is determined,
    65  //    the PSCL output is moved into KNDR.
    66  //
    67  //  - KNDR (kidOutput) outputs are CSV delayed outputs for which the maturity
    68  //    height has been fully determined. This results from having received
    69  //    confirmation of the UTXO we are trying to spend, contained in either the
    70  //    commitment txn or htlc timeout txn. Once the maturity height is reached,
    71  //    the utxo nursery will sweep all KNDR outputs scheduled for that height
    72  //    using a single txn.
    73  //
    74  //  - GRAD (kidOutput) outputs are KNDR outputs that have successfully been
    75  //    swept into the user's wallet. A channel is considered mature once all of
    76  //    its outputs, including two-stage htlcs, have entered the GRAD state,
    77  //    indicating that it safe to mark the channel as fully closed.
    78  //
    79  //
    80  //                     OUTPUT STATE TRANSITIONS IN UTXO NURSERY
    81  //
    82  //      ┌────────────────┐            ┌──────────────┐
    83  //      │ Commit Outputs │            │ HTLC Outputs │
    84  //      └────────────────┘            └──────────────┘
    85  //               │                            │
    86  //               │                            │
    87  //               │                            │               UTXO NURSERY
    88  //   ┌───────────┼────────────────┬───────────┼───────────────────────────────┐
    89  //   │           │                            │                               │
    90  //   │           │                │           │                               │
    91  //   │           │                            │           CLTV-Delayed        │
    92  //   │           │                │           V            babyOutputs        │
    93  //   │           │                        ┌──────┐                            │
    94  //   │           │                │       │ CRIB │                            │
    95  //   │           │                        └──────┘                            │
    96  //   │           │                │           │                               │
    97  //   │           │                            │                               │
    98  //   │           │                │           |                               │
    99  //   │           │                            V    Wait CLTV                  │
   100  //   │           │                │          [ ]       +                      │
   101  //   │           │                            |   Publish Txn                 │
   102  //   │           │                │           │                               │
   103  //   │           │                            │                               │
   104  //   │           │                │           V ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┐        │
   105  //   │           │                           ( )  waitForTimeoutConf          │
   106  //   │           │                │           | └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘        │
   107  //   │           │                            │                               │
   108  //   │           │                │           │                               │
   109  //   │           │                            │                               │
   110  //   │           V                │           │                               │
   111  //   │       ┌──────┐                         │                               │
   112  //   │       │ PSCL │             └  ──  ──  ─┼  ──  ──  ──  ──  ──  ──  ──  ─┤
   113  //   │       └──────┘                         │                               │
   114  //   │           │                            │                               │
   115  //   │           │                            │                               │
   116  //   │           V ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┐     │            CSV-Delayed        │
   117  //   │          ( )  waitForCommitConf        │             kidOutputs        │
   118  //   │           | └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘     │                               │
   119  //   │           │                            │                               │
   120  //   │           │                            │                               │
   121  //   │           │                            V                               │
   122  //   │           │                        ┌──────┐                            │
   123  //   │           └─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─▶│ KNDR │                            │
   124  //   │                                    └──────┘                            │
   125  //   │                                        │                               │
   126  //   │                                        │                               │
   127  //   │                                        |                               │
   128  //   │                                        V     Wait CSV                  │
   129  //   │                                       [ ]       +                      │
   130  //   │                                        |   Publish Txn                 │
   131  //   │                                        │                               │
   132  //   │                                        │                               │
   133  //   │                                        V ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐         │
   134  //   │                                       ( )  waitForSweepConf            │
   135  //   │                                        | └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘         │
   136  //   │                                        │                               │
   137  //   │                                        │                               │
   138  //   │                                        V                               │
   139  //   │                                     ┌──────┐                           │
   140  //   │                                     │ GRAD │                           │
   141  //   │                                     └──────┘                           │
   142  //   │                                        │                               │
   143  //   │                                        │                               │
   144  //   │                                        │                               │
   145  //   └────────────────────────────────────────┼───────────────────────────────┘
   146  //                                            │
   147  //                                            │
   148  //                                            │
   149  //                                            │
   150  //                                            V
   151  //                                   ┌────────────────┐
   152  //                                   │ Wallet Outputs │
   153  //                                   └────────────────┘
   154  
   155  var byteOrder = binary.BigEndian
   156  
   157  const (
   158  	// kgtnOutputConfTarget is the default confirmation target we'll use for
   159  	// sweeps of CSV delayed outputs.
   160  	kgtnOutputConfTarget = 6
   161  )
   162  
   163  var (
   164  	// ErrContractNotFound is returned when the nursery is unable to
   165  	// retrieve information about a queried contract.
   166  	ErrContractNotFound = fmt.Errorf("unable to locate contract")
   167  )
   168  
   169  // NurseryConfig abstracts the required subsystems used by the utxo nursery. An
   170  // instance of NurseryConfig is passed to newUtxoNursery during instantiation.
   171  type NurseryConfig struct {
   172  	// ChainIO is used by the utxo nursery to determine the current block
   173  	// height, which drives the incubation of the nursery's outputs.
   174  	ChainIO lnwallet.BlockChainIO
   175  
   176  	// ConfDepth is the number of blocks the nursery store waits before
   177  	// determining outputs in the chain as confirmed.
   178  	ConfDepth uint32
   179  
   180  	// FetchClosedChannels provides access to a user's channels, such that
   181  	// they can be marked fully closed after incubation has concluded.
   182  	FetchClosedChannels func(pendingOnly bool) (
   183  		[]*channeldb.ChannelCloseSummary, error)
   184  
   185  	// FetchClosedChannel provides access to the close summary to extract a
   186  	// height hint from.
   187  	FetchClosedChannel func(chanID *wire.OutPoint) (
   188  		*channeldb.ChannelCloseSummary, error)
   189  
   190  	// Notifier provides the utxo nursery the ability to subscribe to
   191  	// transaction confirmation events, which advance outputs through their
   192  	// persistence state transitions.
   193  	Notifier chainntnfs.ChainNotifier
   194  
   195  	// PublishTransaction facilitates the process of broadcasting a signed
   196  	// transaction to the appropriate network.
   197  	PublishTransaction func(*wire.MsgTx, string) error
   198  
   199  	// Store provides access to and modification of the persistent state
   200  	// maintained about the utxo nursery's incubating outputs.
   201  	Store NurseryStorer
   202  
   203  	// Sweep sweeps an input back to the wallet.
   204  	SweepInput func(input.Input, sweep.Params) (chan sweep.Result, error)
   205  }
   206  
   207  // UtxoNursery is a system dedicated to incubating time-locked outputs created
   208  // by the broadcast of a commitment transaction either by us, or the remote
   209  // peer. The nursery accepts outputs and "incubates" them until they've reached
   210  // maturity, then sweep the outputs into the source wallet. An output is
   211  // considered mature after the relative time-lock within the pkScript has
   212  // passed. As outputs reach their maturity age, they're swept in batches into
   213  // the source wallet, returning the outputs so they can be used within future
   214  // channels, or regular Decred transactions.
   215  type UtxoNursery struct {
   216  	started uint32 // To be used atomically.
   217  	stopped uint32 // To be used atomically.
   218  
   219  	cfg *NurseryConfig
   220  
   221  	mu         sync.Mutex
   222  	bestHeight uint32
   223  
   224  	quit chan struct{}
   225  	wg   sync.WaitGroup
   226  }
   227  
   228  // NewUtxoNursery creates a new instance of the UtxoNursery from a
   229  // ChainNotifier and LightningWallet instance.
   230  func NewUtxoNursery(cfg *NurseryConfig) *UtxoNursery {
   231  	return &UtxoNursery{
   232  		cfg:  cfg,
   233  		quit: make(chan struct{}),
   234  	}
   235  }
   236  
   237  // Start launches all goroutines the UtxoNursery needs to properly carry out
   238  // its duties.
   239  func (u *UtxoNursery) Start() error {
   240  	if !atomic.CompareAndSwapUint32(&u.started, 0, 1) {
   241  		return nil
   242  	}
   243  
   244  	utxnLog.Tracef("Starting UTXO nursery")
   245  
   246  	// Retrieve the currently best known block. This is needed to have the
   247  	// state machine catch up with the blocks we missed when we were down.
   248  	bestHash, bestHeight, err := u.cfg.ChainIO.GetBestBlock()
   249  	if err != nil {
   250  		return err
   251  	}
   252  
   253  	// Set best known height to schedule late registrations properly.
   254  	atomic.StoreUint32(&u.bestHeight, uint32(bestHeight))
   255  
   256  	// 2. Flush all fully-graduated channels from the pipeline.
   257  
   258  	// Load any pending close channels, which represents the super set of
   259  	// all channels that may still be incubating.
   260  	pendingCloseChans, err := u.cfg.FetchClosedChannels(true)
   261  	if err != nil {
   262  		return err
   263  	}
   264  
   265  	// Ensure that all mature channels have been marked as fully closed in
   266  	// the channeldb.
   267  	for _, pendingClose := range pendingCloseChans {
   268  		err := u.closeAndRemoveIfMature(&pendingClose.ChanPoint)
   269  		if err != nil {
   270  			return err
   271  		}
   272  	}
   273  
   274  	// TODO(conner): check if any fully closed channels can be removed from
   275  	// utxn.
   276  
   277  	// 2. Restart spend ntfns for any preschool outputs, which are waiting
   278  	// for the force closed commitment txn to confirm, or any second-layer
   279  	// HTLC success transactions.
   280  	//
   281  	// NOTE: The next two steps *may* spawn go routines, thus from this
   282  	// point forward, we must close the nursery's quit channel if we detect
   283  	// any failures during startup to ensure they terminate.
   284  	if err := u.reloadPreschool(); err != nil {
   285  		close(u.quit)
   286  		return err
   287  	}
   288  
   289  	// 3. Replay all crib and kindergarten outputs up to the current best
   290  	// height.
   291  	if err := u.reloadClasses(uint32(bestHeight)); err != nil {
   292  		close(u.quit)
   293  		return err
   294  	}
   295  
   296  	// Start watching for new blocks, as this will drive the nursery store's
   297  	// state machine.
   298  	newBlockChan, err := u.cfg.Notifier.RegisterBlockEpochNtfn(&chainntnfs.BlockEpoch{
   299  		Height: bestHeight,
   300  		Hash:   bestHash,
   301  	})
   302  	if err != nil {
   303  		close(u.quit)
   304  		return err
   305  	}
   306  
   307  	u.wg.Add(1)
   308  	go u.incubator(newBlockChan)
   309  
   310  	return nil
   311  }
   312  
   313  // Stop gracefully shuts down any lingering goroutines launched during normal
   314  // operation of the UtxoNursery.
   315  func (u *UtxoNursery) Stop() error {
   316  	if !atomic.CompareAndSwapUint32(&u.stopped, 0, 1) {
   317  		return nil
   318  	}
   319  
   320  	utxnLog.Infof("UTXO nursery shutting down")
   321  
   322  	close(u.quit)
   323  	u.wg.Wait()
   324  
   325  	return nil
   326  }
   327  
   328  // IncubateOutputs sends a request to the UtxoNursery to incubate a set of
   329  // outputs from an existing commitment transaction. Outputs need to incubate if
   330  // they're CLTV absolute time locked, or if they're CSV relative time locked.
   331  // Once all outputs reach maturity, they'll be swept back into the wallet.
   332  func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
   333  	outgoingHtlcs []lnwallet.OutgoingHtlcResolution,
   334  	incomingHtlcs []lnwallet.IncomingHtlcResolution,
   335  	broadcastHeight uint32) error {
   336  
   337  	// Add to wait group because nursery might shut down during execution of
   338  	// this function. Otherwise it could happen that nursery thinks it is
   339  	// shut down, but in this function new goroutines were started and stay
   340  	// around.
   341  	u.wg.Add(1)
   342  	defer u.wg.Done()
   343  
   344  	// Check quit channel for the case where the waitgroup wait was finished
   345  	// right before this function's add call was made.
   346  	select {
   347  	case <-u.quit:
   348  		return fmt.Errorf("nursery shutting down")
   349  	default:
   350  	}
   351  
   352  	numHtlcs := len(incomingHtlcs) + len(outgoingHtlcs)
   353  	var (
   354  		// Kid outputs can be swept after an initial confirmation
   355  		// followed by a maturity period.Baby outputs are two stage and
   356  		// will need to wait for an absolute time out to reach a
   357  		// confirmation, then require a relative confirmation delay.
   358  		kidOutputs  = make([]kidOutput, 0, 1+len(incomingHtlcs))
   359  		babyOutputs = make([]babyOutput, 0, len(outgoingHtlcs))
   360  	)
   361  
   362  	// 1. Build all the spendable outputs that we will try to incubate.
   363  
   364  	// TODO(roasbeef): query and see if we already have, if so don't add?
   365  
   366  	// For each incoming HTLC, we'll register a kid output marked as a
   367  	// second-layer HTLC output. We effectively skip the baby stage (as the
   368  	// timelock is zero), and enter the kid stage.
   369  	for _, htlcRes := range incomingHtlcs {
   370  		htlcOutput := makeKidOutput(
   371  			&htlcRes.ClaimOutpoint, &chanPoint, htlcRes.CsvDelay,
   372  			input.HtlcAcceptedSuccessSecondLevel,
   373  			&htlcRes.SweepSignDesc, 0,
   374  		)
   375  
   376  		if htlcOutput.Amount() > 0 {
   377  			kidOutputs = append(kidOutputs, htlcOutput)
   378  		}
   379  	}
   380  
   381  	// For each outgoing HTLC, we'll create a baby output. If this is our
   382  	// commitment transaction, then we'll broadcast a second-layer
   383  	// transaction to transition to a kid output. Otherwise, we'll directly
   384  	// spend once the CLTV delay us up.
   385  	for _, htlcRes := range outgoingHtlcs {
   386  		// If this HTLC is on our commitment transaction, then it'll be
   387  		// a baby output as we need to go to the second level to sweep
   388  		// it.
   389  		if htlcRes.SignedTimeoutTx != nil {
   390  			htlcOutput := makeBabyOutput(&chanPoint, &htlcRes)
   391  
   392  			if htlcOutput.Amount() > 0 {
   393  				babyOutputs = append(babyOutputs, htlcOutput)
   394  			}
   395  			continue
   396  		}
   397  
   398  		// Otherwise, this is actually a kid output as we can sweep it
   399  		// once the commitment transaction confirms, and the absolute
   400  		// CLTV lock has expired. We set the CSV delay what the
   401  		// resolution encodes, since the sequence number must be set
   402  		// accordingly.
   403  		htlcOutput := makeKidOutput(
   404  			&htlcRes.ClaimOutpoint, &chanPoint, htlcRes.CsvDelay,
   405  			input.HtlcOfferedRemoteTimeout,
   406  			&htlcRes.SweepSignDesc, htlcRes.Expiry,
   407  		)
   408  		kidOutputs = append(kidOutputs, htlcOutput)
   409  	}
   410  
   411  	// TODO(roasbeef): if want to handle outgoing on remote commit
   412  	//  * need ability to cancel in the case that we learn of pre-image or
   413  	//    remote party pulls
   414  
   415  	utxnLog.Infof("Incubating Channel(%s) num-htlcs=%d",
   416  		chanPoint, numHtlcs)
   417  
   418  	u.mu.Lock()
   419  	defer u.mu.Unlock()
   420  
   421  	// 2. Persist the outputs we intended to sweep in the nursery store
   422  	if err := u.cfg.Store.Incubate(kidOutputs, babyOutputs); err != nil {
   423  		utxnLog.Errorf("unable to begin incubation of Channel(%s): %v",
   424  			chanPoint, err)
   425  		return err
   426  	}
   427  
   428  	// As an intermediate step, we'll now check to see if any of the baby
   429  	// outputs has actually _already_ expired. This may be the case if
   430  	// blocks were mined while we processed this message.
   431  	_, bestHeight, err := u.cfg.ChainIO.GetBestBlock()
   432  	if err != nil {
   433  		return err
   434  	}
   435  
   436  	// We'll examine all the baby outputs just inserted into the database,
   437  	// if the output has already expired, then we'll *immediately* sweep
   438  	// it. This may happen if the caller raced a block to call this method.
   439  	for i, babyOutput := range babyOutputs {
   440  		if uint32(bestHeight) >= babyOutput.expiry {
   441  			err = u.sweepCribOutput(
   442  				babyOutput.expiry, &babyOutputs[i],
   443  			)
   444  			if err != nil {
   445  				return err
   446  			}
   447  		}
   448  	}
   449  
   450  	// 3. If we are incubating any preschool outputs, register for a
   451  	// confirmation notification that will transition it to the
   452  	// kindergarten bucket.
   453  	if len(kidOutputs) != 0 {
   454  		for i := range kidOutputs {
   455  			err := u.registerPreschoolConf(
   456  				&kidOutputs[i], broadcastHeight,
   457  			)
   458  			if err != nil {
   459  				return err
   460  			}
   461  		}
   462  	}
   463  
   464  	return nil
   465  }
   466  
   467  // NurseryReport attempts to return a nursery report stored for the target
   468  // outpoint. A nursery report details the maturity/sweeping progress for a
   469  // contract that was previously force closed. If a report entry for the target
   470  // chanPoint is unable to be constructed, then an error will be returned.
   471  func (u *UtxoNursery) NurseryReport(
   472  	chanPoint *wire.OutPoint) (*ContractMaturityReport, error) {
   473  
   474  	u.mu.Lock()
   475  	defer u.mu.Unlock()
   476  
   477  	utxnLog.Debugf("NurseryReport: building nursery report for channel %v",
   478  		chanPoint)
   479  
   480  	var report *ContractMaturityReport
   481  
   482  	if err := u.cfg.Store.ForChanOutputs(chanPoint, func(k, v []byte) error {
   483  		switch {
   484  		case bytes.HasPrefix(k, cribPrefix):
   485  			// Cribs outputs are the only kind currently stored as
   486  			// baby outputs.
   487  			var baby babyOutput
   488  			err := baby.Decode(bytes.NewReader(v))
   489  			if err != nil {
   490  				return err
   491  			}
   492  
   493  			// Each crib output represents a stage one htlc, and
   494  			// will contribute towards the limbo balance.
   495  			report.AddLimboStage1TimeoutHtlc(&baby)
   496  
   497  		case bytes.HasPrefix(k, psclPrefix),
   498  			bytes.HasPrefix(k, kndrPrefix),
   499  			bytes.HasPrefix(k, gradPrefix):
   500  
   501  			// All others states can be deserialized as kid outputs.
   502  			var kid kidOutput
   503  			err := kid.Decode(bytes.NewReader(v))
   504  			if err != nil {
   505  				return err
   506  			}
   507  
   508  			// Now, use the state prefixes to determine how the
   509  			// this output should be represented in the nursery
   510  			// report.  An output's funds are always in limbo until
   511  			// reaching the graduate state.
   512  			switch {
   513  			case bytes.HasPrefix(k, psclPrefix):
   514  				// Preschool outputs are awaiting the
   515  				// confirmation of the commitment transaction.
   516  				switch kid.WitnessType() {
   517  
   518  				case input.HtlcAcceptedSuccessSecondLevel:
   519  					// An HTLC output on our commitment transaction
   520  					// where the second-layer transaction hasn't
   521  					// yet confirmed.
   522  					report.AddLimboStage1SuccessHtlc(&kid)
   523  
   524  				case input.HtlcOfferedRemoteTimeout:
   525  					// This is an HTLC output on the
   526  					// commitment transaction of the remote
   527  					// party. We are waiting for the CLTV
   528  					// timelock expire.
   529  					report.AddLimboDirectHtlc(&kid)
   530  				}
   531  
   532  			case bytes.HasPrefix(k, kndrPrefix):
   533  				// Kindergarten outputs may originate from
   534  				// either the commitment transaction or an htlc.
   535  				// We can distinguish them via their witness
   536  				// types.
   537  				switch kid.WitnessType() {
   538  
   539  				case input.HtlcOfferedRemoteTimeout:
   540  					// This is an HTLC output on the
   541  					// commitment transaction of the remote
   542  					// party. The CLTV timelock has
   543  					// expired, and we only need to sweep
   544  					// it.
   545  					report.AddLimboDirectHtlc(&kid)
   546  
   547  				case input.HtlcAcceptedSuccessSecondLevel:
   548  					fallthrough
   549  				case input.HtlcOfferedTimeoutSecondLevel:
   550  					// The htlc timeout or success
   551  					// transaction has confirmed, and the
   552  					// CSV delay has begun ticking.
   553  					report.AddLimboStage2Htlc(&kid)
   554  				}
   555  
   556  			case bytes.HasPrefix(k, gradPrefix):
   557  				// Graduate outputs are those whose funds have
   558  				// been swept back into the wallet. Each output
   559  				// will contribute towards the recovered
   560  				// balance.
   561  				switch kid.WitnessType() {
   562  
   563  				case input.HtlcAcceptedSuccessSecondLevel:
   564  					fallthrough
   565  				case input.HtlcOfferedTimeoutSecondLevel:
   566  					fallthrough
   567  				case input.HtlcOfferedRemoteTimeout:
   568  					// This htlc output successfully
   569  					// resides in a p2wkh output belonging
   570  					// to the user.
   571  					report.AddRecoveredHtlc(&kid)
   572  				}
   573  			}
   574  
   575  		default:
   576  		}
   577  
   578  		return nil
   579  	}, func() {
   580  		report = &ContractMaturityReport{}
   581  	}); err != nil {
   582  		return nil, err
   583  	}
   584  
   585  	return report, nil
   586  }
   587  
   588  // reloadPreschool re-initializes the chain notifier with all of the outputs
   589  // that had been saved to the "preschool" database bucket prior to shutdown.
   590  func (u *UtxoNursery) reloadPreschool() error {
   591  	psclOutputs, err := u.cfg.Store.FetchPreschools()
   592  	if err != nil {
   593  		return err
   594  	}
   595  
   596  	// For each of the preschool outputs stored in the nursery store, load
   597  	// its close summary from disk so that we can get an accurate height
   598  	// hint from which to start our range for spend notifications.
   599  	for i := range psclOutputs {
   600  		kid := &psclOutputs[i]
   601  		chanPoint := kid.OriginChanPoint()
   602  
   603  		// Load the close summary for this output's channel point.
   604  		closeSummary, err := u.cfg.FetchClosedChannel(chanPoint)
   605  		if err == channeldb.ErrClosedChannelNotFound {
   606  			// This should never happen since the close summary
   607  			// should only be removed after the channel has been
   608  			// swept completely.
   609  			utxnLog.Warnf("Close summary not found for "+
   610  				"chan_point=%v, can't determine height hint"+
   611  				"to sweep commit txn", chanPoint)
   612  			continue
   613  
   614  		} else if err != nil {
   615  			return err
   616  		}
   617  
   618  		// Use the close height from the channel summary as our height
   619  		// hint to drive our spend notifications, with our confirmation
   620  		// depth as a buffer for reorgs.
   621  		heightHint := closeSummary.CloseHeight - u.cfg.ConfDepth
   622  		err = u.registerPreschoolConf(kid, heightHint)
   623  		if err != nil {
   624  			return err
   625  		}
   626  	}
   627  
   628  	return nil
   629  }
   630  
   631  // reloadClasses reinitializes any height-dependent state transitions for which
   632  // the utxonursery has not received confirmation, and replays the graduation of
   633  // all kindergarten and crib outputs for all heights up to the current block.
   634  // This allows the nursery to reinitialize all state to continue sweeping
   635  // outputs, even in the event that we missed blocks while offline. reloadClasses
   636  // is called during the startup of the UTXO Nursery.
   637  func (u *UtxoNursery) reloadClasses(bestHeight uint32) error {
   638  	// Loading all active heights up to and including the current block.
   639  	activeHeights, err := u.cfg.Store.HeightsBelowOrEqual(bestHeight)
   640  	if err != nil {
   641  		return err
   642  	}
   643  
   644  	// Return early if nothing to sweep.
   645  	if len(activeHeights) == 0 {
   646  		return nil
   647  	}
   648  
   649  	utxnLog.Infof("(Re)-sweeping %d heights below height=%d",
   650  		len(activeHeights), bestHeight)
   651  
   652  	// Attempt to re-register notifications for any outputs still at these
   653  	// heights.
   654  	for _, classHeight := range activeHeights {
   655  		utxnLog.Debugf("Attempting to sweep outputs at height=%v",
   656  			classHeight)
   657  
   658  		if err = u.graduateClass(classHeight); err != nil {
   659  			utxnLog.Errorf("Failed to sweep outputs at "+
   660  				"height=%v: %v", classHeight, err)
   661  			return err
   662  		}
   663  	}
   664  
   665  	utxnLog.Infof("UTXO Nursery is now fully synced")
   666  
   667  	return nil
   668  }
   669  
   670  // incubator is tasked with driving all state transitions that are dependent on
   671  // the current height of the blockchain. As new blocks arrive, the incubator
   672  // will attempt spend outputs at the latest height. The asynchronous
   673  // confirmation of these spends will either 1) move a crib output into the
   674  // kindergarten bucket or 2) move a kindergarten output into the graduated
   675  // bucket.
   676  func (u *UtxoNursery) incubator(newBlockChan *chainntnfs.BlockEpochEvent) {
   677  	defer u.wg.Done()
   678  	defer newBlockChan.Cancel()
   679  
   680  	for {
   681  		select {
   682  		case epoch, ok := <-newBlockChan.Epochs:
   683  			// If the epoch channel has been closed, then the
   684  			// ChainNotifier is exiting which means the daemon is
   685  			// as well. Therefore, we exit early also in order to
   686  			// ensure the daemon shuts down gracefully, yet
   687  			// swiftly.
   688  			if !ok {
   689  				return
   690  			}
   691  
   692  			// TODO(roasbeef): if the BlockChainIO is rescanning
   693  			// will give stale data
   694  
   695  			// A new block has just been connected to the main
   696  			// chain, which means we might be able to graduate crib
   697  			// or kindergarten outputs at this height. This involves
   698  			// broadcasting any presigned htlc timeout txns, as well
   699  			// as signing and broadcasting a sweep txn that spends
   700  			// from all kindergarten outputs at this height.
   701  			height := uint32(epoch.Height)
   702  
   703  			// Update best known block height for late registrations
   704  			// to be scheduled properly.
   705  			atomic.StoreUint32(&u.bestHeight, height)
   706  
   707  			if err := u.graduateClass(height); err != nil {
   708  				utxnLog.Errorf("error while graduating "+
   709  					"class at height=%d: %v", height, err)
   710  
   711  				// TODO(conner): signal fatal error to daemon
   712  			}
   713  
   714  		case <-u.quit:
   715  			return
   716  		}
   717  	}
   718  }
   719  
   720  // graduateClass handles the steps involved in spending outputs whose CSV or
   721  // CLTV delay expires at the nursery's current height. This method is called
   722  // each time a new block arrives, or during startup to catch up on heights we
   723  // may have missed while the nursery was offline.
   724  func (u *UtxoNursery) graduateClass(classHeight uint32) error {
   725  	// Record this height as the nursery's current best height.
   726  	u.mu.Lock()
   727  	defer u.mu.Unlock()
   728  
   729  	// Fetch all information about the crib and kindergarten outputs at
   730  	// this height.
   731  	kgtnOutputs, cribOutputs, err := u.cfg.Store.FetchClass(
   732  		classHeight)
   733  	if err != nil {
   734  		return err
   735  	}
   736  
   737  	utxnLog.Infof("Attempting to graduate height=%v: num_kids=%v, "+
   738  		"num_babies=%v", classHeight, len(kgtnOutputs), len(cribOutputs))
   739  
   740  	// Offer the outputs to the sweeper and set up notifications that will
   741  	// transition the swept kindergarten outputs and cltvCrib into graduated
   742  	// outputs.
   743  	if len(kgtnOutputs) > 0 {
   744  		if err := u.sweepMatureOutputs(classHeight, kgtnOutputs); err != nil {
   745  			utxnLog.Errorf("Failed to sweep %d kindergarten "+
   746  				"outputs at height=%d: %v",
   747  				len(kgtnOutputs), classHeight, err)
   748  			return err
   749  		}
   750  	}
   751  
   752  	// Now, we broadcast all pre-signed htlc txns from the csv crib outputs
   753  	// at this height.
   754  	for i := range cribOutputs {
   755  		err := u.sweepCribOutput(classHeight, &cribOutputs[i])
   756  		if err != nil {
   757  			utxnLog.Errorf("Failed to sweep first-stage HTLC "+
   758  				"(CLTV-delayed) output %v",
   759  				cribOutputs[i].OutPoint())
   760  			return err
   761  		}
   762  	}
   763  
   764  	return nil
   765  }
   766  
   767  // sweepMatureOutputs generates and broadcasts the transaction that transfers
   768  // control of funds from a prior channel commitment transaction to the user's
   769  // wallet. The outputs swept were previously time locked (either absolute or
   770  // relative), but are not mature enough to sweep into the wallet.
   771  func (u *UtxoNursery) sweepMatureOutputs(classHeight uint32,
   772  	kgtnOutputs []kidOutput) error {
   773  
   774  	utxnLog.Infof("Sweeping %v CSV-delayed outputs with sweep tx for "+
   775  		"height %v", len(kgtnOutputs), classHeight)
   776  
   777  	feePref := sweep.FeePreference{ConfTarget: kgtnOutputConfTarget}
   778  	for _, output := range kgtnOutputs {
   779  		// Create local copy to prevent pointer to loop variable to be
   780  		// passed in with disastrous consequences.
   781  		local := output
   782  
   783  		resultChan, err := u.cfg.SweepInput(
   784  			&local, sweep.Params{Fee: feePref},
   785  		)
   786  		if err != nil {
   787  			return err
   788  		}
   789  		u.wg.Add(1)
   790  		go u.waitForSweepConf(classHeight, &local, resultChan)
   791  	}
   792  
   793  	return nil
   794  }
   795  
   796  // waitForSweepConf watches for the confirmation of a sweep transaction
   797  // containing a batch of kindergarten outputs. Once confirmation has been
   798  // received, the nursery will mark those outputs as fully graduated, and proceed
   799  // to mark any mature channels as fully closed in channeldb.
   800  // NOTE(conner): this method MUST be called as a go routine.
   801  func (u *UtxoNursery) waitForSweepConf(classHeight uint32,
   802  	output *kidOutput, resultChan chan sweep.Result) {
   803  
   804  	defer u.wg.Done()
   805  
   806  	select {
   807  	case result, ok := <-resultChan:
   808  		if !ok {
   809  			utxnLog.Errorf("Notification chan closed, can't" +
   810  				" advance graduating output")
   811  			return
   812  		}
   813  
   814  		// In case of a remote spend, still graduate the output. There
   815  		// is no way to sweep it anymore.
   816  		if result.Err == sweep.ErrRemoteSpend {
   817  			utxnLog.Infof("Output %v was spend by remote party",
   818  				output.OutPoint())
   819  			break
   820  		}
   821  
   822  		if result.Err != nil {
   823  			utxnLog.Errorf("Failed to sweep %v at "+
   824  				"height=%d", output.OutPoint(),
   825  				classHeight)
   826  			return
   827  		}
   828  
   829  	case <-u.quit:
   830  		return
   831  	}
   832  
   833  	u.mu.Lock()
   834  	defer u.mu.Unlock()
   835  
   836  	// TODO(conner): add retry logic?
   837  
   838  	// Mark the confirmed kindergarten output as graduated.
   839  	if err := u.cfg.Store.GraduateKinder(classHeight, output); err != nil {
   840  		utxnLog.Errorf("Unable to graduate kindergarten output %v: %v",
   841  			output.OutPoint(), err)
   842  		return
   843  	}
   844  
   845  	utxnLog.Infof("Graduated kindergarten output from height=%d",
   846  		classHeight)
   847  
   848  	// Attempt to close the channel, only doing so if all of the channel's
   849  	// outputs have been graduated.
   850  	chanPoint := output.OriginChanPoint()
   851  	if err := u.closeAndRemoveIfMature(chanPoint); err != nil {
   852  		utxnLog.Errorf("Failed to close and remove channel %v",
   853  			*chanPoint)
   854  		return
   855  	}
   856  }
   857  
   858  // sweepCribOutput broadcasts the crib output's htlc timeout txn, and sets up a
   859  // notification that will advance it to the kindergarten bucket upon
   860  // confirmation.
   861  func (u *UtxoNursery) sweepCribOutput(classHeight uint32, baby *babyOutput) error {
   862  	utxnLog.Infof("Publishing CLTV-delayed HTLC output using timeout tx "+
   863  		"(txid=%v): %v", baby.timeoutTx.TxHash(),
   864  		newLogClosure(func() string {
   865  			return spew.Sdump(baby.timeoutTx)
   866  		}),
   867  	)
   868  
   869  	// We'll now broadcast the HTLC transaction, then wait for it to be
   870  	// confirmed before transitioning it to kindergarten.
   871  	label := labels.MakeLabel(labels.LabelTypeSweepTransaction, nil)
   872  	err := u.cfg.PublishTransaction(baby.timeoutTx, label)
   873  	if err != nil && err != lnwallet.ErrDoubleSpend {
   874  		utxnLog.Errorf("Unable to broadcast baby tx: "+
   875  			"%v, %v", err, spew.Sdump(baby.timeoutTx))
   876  		return err
   877  	}
   878  
   879  	return u.registerTimeoutConf(baby, classHeight)
   880  }
   881  
   882  // registerTimeoutConf is responsible for subscribing to confirmation
   883  // notification for an htlc timeout transaction. If successful, a goroutine
   884  // will be spawned that will transition the provided baby output into the
   885  // kindergarten state within the nursery store.
   886  func (u *UtxoNursery) registerTimeoutConf(baby *babyOutput, heightHint uint32) error {
   887  
   888  	birthTxID := baby.timeoutTx.TxHash()
   889  
   890  	// Register for the confirmation of presigned htlc txn.
   891  	confChan, err := u.cfg.Notifier.RegisterConfirmationsNtfn(
   892  		&birthTxID, baby.timeoutTx.TxOut[0].PkScript, u.cfg.ConfDepth,
   893  		heightHint,
   894  	)
   895  	if err != nil {
   896  		return err
   897  	}
   898  
   899  	utxnLog.Infof("Htlc output %v registered for promotion "+
   900  		"notification.", baby.OutPoint())
   901  
   902  	u.wg.Add(1)
   903  	go u.waitForTimeoutConf(baby, confChan)
   904  
   905  	return nil
   906  }
   907  
   908  // waitForTimeoutConf watches for the confirmation of an htlc timeout
   909  // transaction, and attempts to move the htlc output from the crib bucket to the
   910  // kindergarten bucket upon success.
   911  func (u *UtxoNursery) waitForTimeoutConf(baby *babyOutput,
   912  	confChan *chainntnfs.ConfirmationEvent) {
   913  
   914  	defer u.wg.Done()
   915  
   916  	select {
   917  	case txConfirmation, ok := <-confChan.Confirmed:
   918  		if !ok {
   919  			utxnLog.Debugf("Notification chan "+
   920  				"closed, can't advance baby output %v",
   921  				baby.OutPoint())
   922  			return
   923  		}
   924  
   925  		baby.SetConfHeight(txConfirmation.BlockHeight)
   926  
   927  	case <-u.quit:
   928  		return
   929  	}
   930  
   931  	u.mu.Lock()
   932  	defer u.mu.Unlock()
   933  
   934  	// TODO(conner): add retry logic?
   935  
   936  	err := u.cfg.Store.CribToKinder(baby)
   937  	if err != nil {
   938  		utxnLog.Errorf("Unable to move htlc output from "+
   939  			"crib to kindergarten bucket: %v", err)
   940  		return
   941  	}
   942  
   943  	utxnLog.Infof("Htlc output %v promoted to "+
   944  		"kindergarten", baby.OutPoint())
   945  }
   946  
   947  // registerPreschoolConf is responsible for subscribing to the confirmation of
   948  // a commitment transaction, or an htlc success transaction for an incoming
   949  // HTLC on our commitment transaction.. If successful, the provided preschool
   950  // output will be moved persistently into the kindergarten state within the
   951  // nursery store.
   952  func (u *UtxoNursery) registerPreschoolConf(kid *kidOutput, heightHint uint32) error {
   953  	txID := kid.OutPoint().Hash
   954  
   955  	// TODO(roasbeef): ensure we don't already have one waiting, need to
   956  	// de-duplicate
   957  	//  * need to do above?
   958  
   959  	pkScript := kid.signDesc.Output.PkScript
   960  	confChan, err := u.cfg.Notifier.RegisterConfirmationsNtfn(
   961  		&txID, pkScript, u.cfg.ConfDepth, heightHint,
   962  	)
   963  	if err != nil {
   964  		return err
   965  	}
   966  
   967  	var outputType string
   968  	if kid.isHtlc {
   969  		outputType = "HTLC"
   970  	} else {
   971  		outputType = "Commitment"
   972  	}
   973  
   974  	utxnLog.Infof("%v outpoint %v registered for "+
   975  		"confirmation notification.", outputType, kid.OutPoint())
   976  
   977  	u.wg.Add(1)
   978  	go u.waitForPreschoolConf(kid, confChan)
   979  
   980  	return nil
   981  }
   982  
   983  // waitForPreschoolConf is intended to be run as a goroutine that will wait until
   984  // a channel force close commitment transaction, or a second layer HTLC success
   985  // transaction has been included in a confirmed block. Once the transaction has
   986  // been confirmed (as reported by the Chain Notifier), waitForPreschoolConf
   987  // will delete the output from the "preschool" database bucket and atomically
   988  // add it to the "kindergarten" database bucket.  This is the second step in
   989  // the output incubation process.
   990  func (u *UtxoNursery) waitForPreschoolConf(kid *kidOutput,
   991  	confChan *chainntnfs.ConfirmationEvent) {
   992  
   993  	defer u.wg.Done()
   994  
   995  	select {
   996  	case txConfirmation, ok := <-confChan.Confirmed:
   997  		if !ok {
   998  			utxnLog.Errorf("Notification chan "+
   999  				"closed, can't advance output %v",
  1000  				kid.OutPoint())
  1001  			return
  1002  		}
  1003  
  1004  		kid.SetConfHeight(txConfirmation.BlockHeight)
  1005  
  1006  	case <-u.quit:
  1007  		return
  1008  	}
  1009  
  1010  	u.mu.Lock()
  1011  	defer u.mu.Unlock()
  1012  
  1013  	// TODO(conner): add retry logic?
  1014  
  1015  	var outputType string
  1016  	if kid.isHtlc {
  1017  		outputType = "HTLC"
  1018  	} else {
  1019  		outputType = "Commitment"
  1020  	}
  1021  
  1022  	bestHeight := atomic.LoadUint32(&u.bestHeight)
  1023  	err := u.cfg.Store.PreschoolToKinder(kid, bestHeight)
  1024  	if err != nil {
  1025  		utxnLog.Errorf("Unable to move %v output "+
  1026  			"from preschool to kindergarten bucket: %v",
  1027  			outputType, err)
  1028  		return
  1029  	}
  1030  }
  1031  
  1032  // RemoveChannel channel erases all entries from the channel bucket for the
  1033  // provided channel point.
  1034  func (u *UtxoNursery) RemoveChannel(op *wire.OutPoint) error {
  1035  	return u.cfg.Store.RemoveChannel(op)
  1036  
  1037  }
  1038  
  1039  // ContractMaturityReport is a report that details the maturity progress of a
  1040  // particular force closed contract.
  1041  type ContractMaturityReport struct {
  1042  	// LimboBalance is the total number of frozen coins within this
  1043  	// contract.
  1044  	LimboBalance dcrutil.Amount
  1045  
  1046  	// RecoveredBalance is the total value that has been successfully swept
  1047  	// back to the user's wallet.
  1048  	RecoveredBalance dcrutil.Amount
  1049  
  1050  	// htlcs records a maturity report for each htlc output in this channel.
  1051  	Htlcs []HtlcMaturityReport
  1052  }
  1053  
  1054  // HtlcMaturityReport provides a summary of a single htlc output, and is
  1055  // embedded as party of the overarching ContractMaturityReport
  1056  type HtlcMaturityReport struct {
  1057  	// Outpoint is the final output that will be swept back to the wallet.
  1058  	Outpoint wire.OutPoint
  1059  
  1060  	// amount is the final value that will be swept in back to the wallet.
  1061  	Amount dcrutil.Amount
  1062  
  1063  	// MaturityHeight is the absolute block height that this output will
  1064  	// mature at.
  1065  	MaturityHeight uint32
  1066  
  1067  	// Stage indicates whether the htlc is in the CLTV-timeout stage (1) or
  1068  	// the CSV-delay stage (2). A stage 1 htlc's maturity height will be set
  1069  	// to its expiry height, while a stage 2 htlc's maturity height will be
  1070  	// set to its confirmation height plus the maturity requirement.
  1071  	Stage uint32
  1072  }
  1073  
  1074  // AddLimboStage1TimeoutHtlc adds an htlc crib output to the maturity report's
  1075  // htlcs, and contributes its amount to the limbo balance.
  1076  func (c *ContractMaturityReport) AddLimboStage1TimeoutHtlc(baby *babyOutput) {
  1077  	c.LimboBalance += baby.Amount()
  1078  
  1079  	// TODO(roasbeef): bool to indicate stage 1 vs stage 2?
  1080  	c.Htlcs = append(c.Htlcs, HtlcMaturityReport{
  1081  		Outpoint:       *baby.OutPoint(),
  1082  		Amount:         baby.Amount(),
  1083  		MaturityHeight: baby.expiry,
  1084  		Stage:          1,
  1085  	})
  1086  }
  1087  
  1088  // AddLimboDirectHtlc adds a direct HTLC on the commitment transaction of the
  1089  // remote party to the maturity report. This a CLTV time-locked output that
  1090  // has or hasn't expired yet.
  1091  func (c *ContractMaturityReport) AddLimboDirectHtlc(kid *kidOutput) {
  1092  	c.LimboBalance += kid.Amount()
  1093  
  1094  	htlcReport := HtlcMaturityReport{
  1095  		Outpoint:       *kid.OutPoint(),
  1096  		Amount:         kid.Amount(),
  1097  		MaturityHeight: kid.absoluteMaturity,
  1098  		Stage:          2,
  1099  	}
  1100  
  1101  	c.Htlcs = append(c.Htlcs, htlcReport)
  1102  }
  1103  
  1104  // AddLimboStage1SuccessHtlcHtlc adds an htlc crib output to the maturity
  1105  // report's set of HTLC's. We'll use this to report any incoming HTLC sweeps
  1106  // where the second level transaction hasn't yet confirmed.
  1107  func (c *ContractMaturityReport) AddLimboStage1SuccessHtlc(kid *kidOutput) {
  1108  	c.LimboBalance += kid.Amount()
  1109  
  1110  	c.Htlcs = append(c.Htlcs, HtlcMaturityReport{
  1111  		Outpoint: *kid.OutPoint(),
  1112  		Amount:   kid.Amount(),
  1113  		Stage:    1,
  1114  	})
  1115  }
  1116  
  1117  // AddLimboStage2Htlc adds an htlc kindergarten output to the maturity report's
  1118  // htlcs, and contributes its amount to the limbo balance.
  1119  func (c *ContractMaturityReport) AddLimboStage2Htlc(kid *kidOutput) {
  1120  	c.LimboBalance += kid.Amount()
  1121  
  1122  	htlcReport := HtlcMaturityReport{
  1123  		Outpoint: *kid.OutPoint(),
  1124  		Amount:   kid.Amount(),
  1125  		Stage:    2,
  1126  	}
  1127  
  1128  	// If the confirmation height is set, then this means the first stage
  1129  	// has been confirmed, and we know the final maturity height of the CSV
  1130  	// delay.
  1131  	if kid.ConfHeight() != 0 {
  1132  		htlcReport.MaturityHeight = kid.ConfHeight() + kid.BlocksToMaturity()
  1133  	}
  1134  
  1135  	c.Htlcs = append(c.Htlcs, htlcReport)
  1136  }
  1137  
  1138  // AddRecoveredHtlc adds a graduate output to the maturity report's htlcs, and
  1139  // contributes its amount to the recovered balance.
  1140  func (c *ContractMaturityReport) AddRecoveredHtlc(kid *kidOutput) {
  1141  	c.RecoveredBalance += kid.Amount()
  1142  
  1143  	c.Htlcs = append(c.Htlcs, HtlcMaturityReport{
  1144  		Outpoint:       *kid.OutPoint(),
  1145  		Amount:         kid.Amount(),
  1146  		MaturityHeight: kid.ConfHeight() + kid.BlocksToMaturity(),
  1147  	})
  1148  }
  1149  
  1150  // closeAndRemoveIfMature removes a particular channel from the channel index
  1151  // if and only if all of its outputs have been marked graduated. If the channel
  1152  // still has ungraduated outputs, the method will succeed without altering the
  1153  // database state.
  1154  func (u *UtxoNursery) closeAndRemoveIfMature(chanPoint *wire.OutPoint) error {
  1155  	isMature, err := u.cfg.Store.IsMatureChannel(chanPoint)
  1156  	if err == ErrContractNotFound {
  1157  		return nil
  1158  	} else if err != nil {
  1159  		utxnLog.Errorf("Unable to determine maturity of "+
  1160  			"channel=%s", chanPoint)
  1161  		return err
  1162  	}
  1163  
  1164  	// Nothing to do if we are still incubating.
  1165  	if !isMature {
  1166  		return nil
  1167  	}
  1168  
  1169  	// Now that the channel is fully closed, we remove the channel from the
  1170  	// nursery store here. This preserves the invariant that we never remove
  1171  	// a channel unless it is mature, as this is the only place the utxo
  1172  	// nursery removes a channel.
  1173  	if err := u.cfg.Store.RemoveChannel(chanPoint); err != nil {
  1174  		utxnLog.Errorf("Unable to remove channel=%s from "+
  1175  			"nursery store: %v", chanPoint, err)
  1176  		return err
  1177  	}
  1178  
  1179  	utxnLog.Infof("Removed channel %v from nursery store", chanPoint)
  1180  
  1181  	return nil
  1182  }
  1183  
  1184  // babyOutput represents a two-stage CSV locked output, and is used to track
  1185  // htlc outputs through incubation. The first stage requires broadcasting a
  1186  // presigned timeout txn that spends from the CLTV locked output on the
  1187  // commitment txn. A babyOutput is treated as a subset of CsvSpendableOutputs,
  1188  // with the additional constraint that a transaction must be broadcast before
  1189  // it can be spent. Each baby transaction embeds the kidOutput that can later
  1190  // be used to spend the CSV output contained in the timeout txn.
  1191  //
  1192  // TODO(roasbeef): re-rename to timeout tx
  1193  //   - create CltvCsvSpendableOutput
  1194  type babyOutput struct {
  1195  	// expiry is the absolute block height at which the secondLevelTx
  1196  	// should be broadcast to the network.
  1197  	//
  1198  	// NOTE: This value will be zero if this is a baby output for a prior
  1199  	// incoming HTLC.
  1200  	expiry uint32
  1201  
  1202  	// timeoutTx is a fully-signed transaction that, upon confirmation,
  1203  	// transitions the htlc into the delay+claim stage.
  1204  	timeoutTx *wire.MsgTx
  1205  
  1206  	// kidOutput represents the CSV output to be swept from the
  1207  	// secondLevelTx after it has been broadcast and confirmed.
  1208  	kidOutput
  1209  }
  1210  
  1211  // makeBabyOutput constructs a baby output that wraps a future kidOutput. The
  1212  // provided sign descriptors and witness types will be used once the output
  1213  // reaches the delay and claim stage.
  1214  func makeBabyOutput(chanPoint *wire.OutPoint,
  1215  	htlcResolution *lnwallet.OutgoingHtlcResolution) babyOutput {
  1216  
  1217  	htlcOutpoint := htlcResolution.ClaimOutpoint
  1218  	blocksToMaturity := htlcResolution.CsvDelay
  1219  	witnessType := input.HtlcOfferedTimeoutSecondLevel
  1220  
  1221  	kid := makeKidOutput(
  1222  		&htlcOutpoint, chanPoint, blocksToMaturity, witnessType,
  1223  		&htlcResolution.SweepSignDesc, 0,
  1224  	)
  1225  
  1226  	return babyOutput{
  1227  		kidOutput: kid,
  1228  		expiry:    htlcResolution.Expiry,
  1229  		timeoutTx: htlcResolution.SignedTimeoutTx,
  1230  	}
  1231  }
  1232  
  1233  // Encode writes the baby output to the given io.Writer.
  1234  func (bo *babyOutput) Encode(w io.Writer) error {
  1235  	var scratch [4]byte
  1236  	byteOrder.PutUint32(scratch[:], bo.expiry)
  1237  	if _, err := w.Write(scratch[:]); err != nil {
  1238  		return err
  1239  	}
  1240  
  1241  	if err := bo.timeoutTx.Serialize(w); err != nil {
  1242  		return err
  1243  	}
  1244  
  1245  	return bo.kidOutput.Encode(w)
  1246  }
  1247  
  1248  // Decode reconstructs a baby output using the provided io.Reader.
  1249  func (bo *babyOutput) Decode(r io.Reader) error {
  1250  	var scratch [4]byte
  1251  	if _, err := r.Read(scratch[:]); err != nil {
  1252  		return err
  1253  	}
  1254  	bo.expiry = byteOrder.Uint32(scratch[:])
  1255  
  1256  	bo.timeoutTx = new(wire.MsgTx)
  1257  	if err := bo.timeoutTx.Deserialize(r); err != nil {
  1258  		return err
  1259  	}
  1260  
  1261  	return bo.kidOutput.Decode(r)
  1262  }
  1263  
  1264  // kidOutput represents an output that's waiting for a required blockheight
  1265  // before its funds will be available to be moved into the user's wallet.  The
  1266  // struct includes a WitnessGenerator closure which will be used to generate
  1267  // the witness required to sweep the output once it's mature.
  1268  //
  1269  // TODO(roasbeef): rename to immatureOutput?
  1270  type kidOutput struct {
  1271  	breachedOutput
  1272  
  1273  	originChanPoint wire.OutPoint
  1274  
  1275  	// isHtlc denotes if this kid output is an HTLC output or not. This
  1276  	// value will be used to determine how to report this output within the
  1277  	// nursery report.
  1278  	isHtlc bool
  1279  
  1280  	// blocksToMaturity is the relative CSV delay required after initial
  1281  	// confirmation of the commitment transaction before we can sweep this
  1282  	// output.
  1283  	//
  1284  	// NOTE: This will be set for: commitment outputs, and incoming HTLC's.
  1285  	// Otherwise, this will be zero. It will also be non-zero for
  1286  	// commitment types which requires confirmed spends.
  1287  	blocksToMaturity uint32
  1288  
  1289  	// absoluteMaturity is the absolute height that this output will be
  1290  	// mature at. In order to sweep the output after this height, the
  1291  	// locktime of sweep transaction will need to be set to this value.
  1292  	//
  1293  	// NOTE: This will only be set for: outgoing HTLC's on the commitment
  1294  	// transaction of the remote party.
  1295  	absoluteMaturity uint32
  1296  }
  1297  
  1298  func makeKidOutput(outpoint, originChanPoint *wire.OutPoint,
  1299  	blocksToMaturity uint32, witnessType input.StandardWitnessType,
  1300  	signDescriptor *input.SignDescriptor,
  1301  	absoluteMaturity uint32) kidOutput {
  1302  
  1303  	// This is an HTLC either if it's an incoming HTLC on our commitment
  1304  	// transaction, or is an outgoing HTLC on the commitment transaction of
  1305  	// the remote peer.
  1306  	isHtlc := (witnessType == input.HtlcAcceptedSuccessSecondLevel ||
  1307  		witnessType == input.HtlcOfferedRemoteTimeout)
  1308  
  1309  	// heightHint can be safely set to zero here, because after this
  1310  	// function returns, nursery will set a proper confirmation height in
  1311  	// waitForTimeoutConf or waitForPreschoolConf.
  1312  	heightHint := uint32(0)
  1313  
  1314  	return kidOutput{
  1315  		breachedOutput: makeBreachedOutput(
  1316  			outpoint, witnessType, nil, signDescriptor, heightHint,
  1317  		),
  1318  		isHtlc:           isHtlc,
  1319  		originChanPoint:  *originChanPoint,
  1320  		blocksToMaturity: blocksToMaturity,
  1321  		absoluteMaturity: absoluteMaturity,
  1322  	}
  1323  }
  1324  
  1325  func (k *kidOutput) OriginChanPoint() *wire.OutPoint {
  1326  	return &k.originChanPoint
  1327  }
  1328  
  1329  func (k *kidOutput) BlocksToMaturity() uint32 {
  1330  	return k.blocksToMaturity
  1331  }
  1332  
  1333  func (k *kidOutput) SetConfHeight(height uint32) {
  1334  	k.confHeight = height
  1335  }
  1336  
  1337  func (k *kidOutput) ConfHeight() uint32 {
  1338  	return k.confHeight
  1339  }
  1340  
  1341  // Encode converts a KidOutput struct into a form suitable for on-disk database
  1342  // storage. Note that the signDescriptor struct field is included so that the
  1343  // output's witness can be generated by createSweepTx() when the output becomes
  1344  // spendable.
  1345  func (k *kidOutput) Encode(w io.Writer) error {
  1346  	var scratch [8]byte
  1347  	byteOrder.PutUint64(scratch[:], uint64(k.Amount()))
  1348  	if _, err := w.Write(scratch[:]); err != nil {
  1349  		return err
  1350  	}
  1351  
  1352  	if err := writeOutpoint(w, k.OutPoint()); err != nil {
  1353  		return err
  1354  	}
  1355  	if err := writeOutpoint(w, k.OriginChanPoint()); err != nil {
  1356  		return err
  1357  	}
  1358  
  1359  	if err := binary.Write(w, byteOrder, k.isHtlc); err != nil {
  1360  		return err
  1361  	}
  1362  
  1363  	byteOrder.PutUint32(scratch[:4], k.BlocksToMaturity())
  1364  	if _, err := w.Write(scratch[:4]); err != nil {
  1365  		return err
  1366  	}
  1367  
  1368  	byteOrder.PutUint32(scratch[:4], k.absoluteMaturity)
  1369  	if _, err := w.Write(scratch[:4]); err != nil {
  1370  		return err
  1371  	}
  1372  
  1373  	byteOrder.PutUint32(scratch[:4], k.ConfHeight())
  1374  	if _, err := w.Write(scratch[:4]); err != nil {
  1375  		return err
  1376  	}
  1377  
  1378  	byteOrder.PutUint16(scratch[:2], uint16(k.witnessType))
  1379  	if _, err := w.Write(scratch[:2]); err != nil {
  1380  		return err
  1381  	}
  1382  
  1383  	return input.WriteSignDescriptor(w, k.SignDesc())
  1384  }
  1385  
  1386  // Decode takes a byte array representation of a kidOutput and converts it to an
  1387  // struct. Note that the witnessFunc method isn't added during deserialization
  1388  // and must be added later based on the value of the witnessType field.
  1389  func (k *kidOutput) Decode(r io.Reader) error {
  1390  	var scratch [8]byte
  1391  
  1392  	if _, err := r.Read(scratch[:]); err != nil {
  1393  		return err
  1394  	}
  1395  	k.amt = dcrutil.Amount(byteOrder.Uint64(scratch[:]))
  1396  
  1397  	if err := readOutpoint(io.LimitReader(r, 40), &k.outpoint); err != nil {
  1398  		return err
  1399  	}
  1400  
  1401  	err := readOutpoint(io.LimitReader(r, 40), &k.originChanPoint)
  1402  	if err != nil {
  1403  		return err
  1404  	}
  1405  
  1406  	if err := binary.Read(r, byteOrder, &k.isHtlc); err != nil {
  1407  		return err
  1408  	}
  1409  
  1410  	if _, err := r.Read(scratch[:4]); err != nil {
  1411  		return err
  1412  	}
  1413  	k.blocksToMaturity = byteOrder.Uint32(scratch[:4])
  1414  
  1415  	if _, err := r.Read(scratch[:4]); err != nil {
  1416  		return err
  1417  	}
  1418  	k.absoluteMaturity = byteOrder.Uint32(scratch[:4])
  1419  
  1420  	if _, err := r.Read(scratch[:4]); err != nil {
  1421  		return err
  1422  	}
  1423  	k.confHeight = byteOrder.Uint32(scratch[:4])
  1424  
  1425  	if _, err := r.Read(scratch[:2]); err != nil {
  1426  		return err
  1427  	}
  1428  	k.witnessType = input.StandardWitnessType(byteOrder.Uint16(scratch[:2]))
  1429  
  1430  	return input.ReadSignDescriptor(r, &k.signDesc)
  1431  }
  1432  
  1433  // TODO(bvu): copied from channeldb, remove repetition
  1434  //
  1435  // Note(decred): this cannot be moved to use the channeldb version because it
  1436  // does not include the outpoint's tree field.
  1437  func writeOutpoint(w io.Writer, o *wire.OutPoint) error {
  1438  	// TODO(roasbeef): make all scratch buffers on the stack
  1439  	scratch := make([]byte, 4)
  1440  
  1441  	// TODO(roasbeef): write raw 32 bytes instead of wasting the extra
  1442  	// byte.
  1443  	if err := wire.WriteVarBytes(w, 0, o.Hash[:]); err != nil {
  1444  		return err
  1445  	}
  1446  
  1447  	byteOrder.PutUint32(scratch, o.Index)
  1448  	_, err := w.Write(scratch)
  1449  
  1450  	// Note(decred): this does not include the Tree field
  1451  	return err
  1452  }
  1453  
  1454  // TODO(bvu): copied from channeldb, remove repetition
  1455  //
  1456  // Note(decred): this cannot be moved to use the channeldb version because it
  1457  // does not include the outpoint's tree field.
  1458  func readOutpoint(r io.Reader, o *wire.OutPoint) error {
  1459  	scratch := make([]byte, 4)
  1460  
  1461  	txid, err := wire.ReadVarBytes(r, 0, 32, "prevout")
  1462  	if err != nil {
  1463  		return err
  1464  	}
  1465  	copy(o.Hash[:], txid)
  1466  
  1467  	if _, err := r.Read(scratch); err != nil {
  1468  		return err
  1469  	}
  1470  	o.Index = byteOrder.Uint32(scratch)
  1471  
  1472  	// Note(decred): this does not include the Tree field
  1473  	return nil
  1474  }
  1475  
  1476  // Compile-time constraint to ensure kidOutput implements the
  1477  // Input interface.
  1478  
  1479  var _ input.Input = (*kidOutput)(nil)