github.com/decred/dcrlnd@v0.7.6/channeldb/migration21/current/current_encoding.go (about)

     1  package current
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  
    10  	lnwire "github.com/decred/dcrlnd/channeldb/migration/lnwire21"
    11  	"github.com/decred/dcrlnd/channeldb/migration21/common"
    12  	"github.com/decred/dcrlnd/kvdb"
    13  )
    14  
    15  func serializeChanCommit(w io.Writer, c *common.ChannelCommitment) error { // nolint: dupl
    16  	if err := WriteElements(w,
    17  		c.CommitHeight, c.LocalLogIndex, c.LocalHtlcIndex,
    18  		c.RemoteLogIndex, c.RemoteHtlcIndex, c.LocalBalance,
    19  		c.RemoteBalance, c.CommitFee, c.FeePerKB, c.CommitTx,
    20  		c.CommitSig,
    21  	); err != nil {
    22  		return err
    23  	}
    24  
    25  	return serializeHtlcs(w, c.Htlcs...)
    26  }
    27  
    28  func SerializeLogUpdates(w io.Writer, logUpdates []common.LogUpdate) error { // nolint: dupl
    29  	numUpdates := uint16(len(logUpdates))
    30  	if err := binary.Write(w, byteOrder, numUpdates); err != nil {
    31  		return err
    32  	}
    33  
    34  	for _, diff := range logUpdates {
    35  		err := WriteElements(w, diff.LogIndex, diff.UpdateMsg)
    36  		if err != nil {
    37  			return err
    38  		}
    39  	}
    40  
    41  	return nil
    42  }
    43  
    44  func serializeHtlcs(b io.Writer, htlcs ...common.HTLC) error { // nolint: dupl
    45  	numHtlcs := uint16(len(htlcs))
    46  	if err := WriteElement(b, numHtlcs); err != nil {
    47  		return err
    48  	}
    49  
    50  	for _, htlc := range htlcs {
    51  		if err := WriteElements(b,
    52  			htlc.Signature, htlc.RHash, htlc.Amt, htlc.RefundTimeout,
    53  			htlc.OutputIndex, htlc.Incoming, htlc.OnionBlob,
    54  			htlc.HtlcIndex, htlc.LogIndex,
    55  		); err != nil {
    56  			return err
    57  		}
    58  	}
    59  
    60  	return nil
    61  }
    62  
    63  func SerializeCommitDiff(w io.Writer, diff *common.CommitDiff) error { // nolint: dupl
    64  	if err := serializeChanCommit(w, &diff.Commitment); err != nil {
    65  		return err
    66  	}
    67  
    68  	if err := WriteElements(w, diff.CommitSig); err != nil {
    69  		return err
    70  	}
    71  
    72  	if err := SerializeLogUpdates(w, diff.LogUpdates); err != nil {
    73  		return err
    74  	}
    75  
    76  	numOpenRefs := uint16(len(diff.OpenedCircuitKeys))
    77  	if err := binary.Write(w, byteOrder, numOpenRefs); err != nil {
    78  		return err
    79  	}
    80  
    81  	for _, openRef := range diff.OpenedCircuitKeys {
    82  		err := WriteElements(w, openRef.ChanID, openRef.HtlcID)
    83  		if err != nil {
    84  			return err
    85  		}
    86  	}
    87  
    88  	numClosedRefs := uint16(len(diff.ClosedCircuitKeys))
    89  	if err := binary.Write(w, byteOrder, numClosedRefs); err != nil {
    90  		return err
    91  	}
    92  
    93  	for _, closedRef := range diff.ClosedCircuitKeys {
    94  		err := WriteElements(w, closedRef.ChanID, closedRef.HtlcID)
    95  		if err != nil {
    96  			return err
    97  		}
    98  	}
    99  
   100  	return nil
   101  }
   102  
   103  func deserializeHtlcs(r io.Reader) ([]common.HTLC, error) { // nolint: dupl
   104  	var numHtlcs uint16
   105  	if err := ReadElement(r, &numHtlcs); err != nil {
   106  		return nil, err
   107  	}
   108  
   109  	var htlcs []common.HTLC
   110  	if numHtlcs == 0 {
   111  		return htlcs, nil
   112  	}
   113  
   114  	htlcs = make([]common.HTLC, numHtlcs)
   115  	for i := uint16(0); i < numHtlcs; i++ {
   116  		if err := ReadElements(r,
   117  			&htlcs[i].Signature, &htlcs[i].RHash, &htlcs[i].Amt,
   118  			&htlcs[i].RefundTimeout, &htlcs[i].OutputIndex,
   119  			&htlcs[i].Incoming, &htlcs[i].OnionBlob,
   120  			&htlcs[i].HtlcIndex, &htlcs[i].LogIndex,
   121  		); err != nil {
   122  			return htlcs, err
   123  		}
   124  	}
   125  
   126  	return htlcs, nil
   127  }
   128  
   129  func deserializeChanCommit(r io.Reader) (common.ChannelCommitment, error) { // nolint: dupl
   130  	var c common.ChannelCommitment
   131  
   132  	err := ReadElements(r,
   133  		&c.CommitHeight, &c.LocalLogIndex, &c.LocalHtlcIndex, &c.RemoteLogIndex,
   134  		&c.RemoteHtlcIndex, &c.LocalBalance, &c.RemoteBalance,
   135  		&c.CommitFee, &c.FeePerKB, &c.CommitTx, &c.CommitSig,
   136  	)
   137  	if err != nil {
   138  		return c, err
   139  	}
   140  
   141  	c.Htlcs, err = deserializeHtlcs(r)
   142  	if err != nil {
   143  		return c, err
   144  	}
   145  
   146  	return c, nil
   147  }
   148  
   149  func DeserializeLogUpdates(r io.Reader) ([]common.LogUpdate, error) { // nolint: dupl
   150  	var numUpdates uint16
   151  	if err := binary.Read(r, byteOrder, &numUpdates); err != nil {
   152  		return nil, err
   153  	}
   154  
   155  	logUpdates := make([]common.LogUpdate, numUpdates)
   156  	for i := 0; i < int(numUpdates); i++ {
   157  		err := ReadElements(r,
   158  			&logUpdates[i].LogIndex, &logUpdates[i].UpdateMsg,
   159  		)
   160  		if err != nil {
   161  			return nil, err
   162  		}
   163  	}
   164  	return logUpdates, nil
   165  }
   166  
   167  func DeserializeCommitDiff(r io.Reader) (*common.CommitDiff, error) { // nolint: dupl
   168  	var (
   169  		d   common.CommitDiff
   170  		err error
   171  	)
   172  
   173  	d.Commitment, err = deserializeChanCommit(r)
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  
   178  	var msg lnwire.Message
   179  	if err := ReadElements(r, &msg); err != nil {
   180  		return nil, err
   181  	}
   182  	commitSig, ok := msg.(*lnwire.CommitSig)
   183  	if !ok {
   184  		return nil, fmt.Errorf("expected lnwire.CommitSig, instead "+
   185  			"read: %T", msg)
   186  	}
   187  	d.CommitSig = commitSig
   188  
   189  	d.LogUpdates, err = DeserializeLogUpdates(r)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  
   194  	var numOpenRefs uint16
   195  	if err := binary.Read(r, byteOrder, &numOpenRefs); err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	d.OpenedCircuitKeys = make([]common.CircuitKey, numOpenRefs)
   200  	for i := 0; i < int(numOpenRefs); i++ {
   201  		err := ReadElements(r,
   202  			&d.OpenedCircuitKeys[i].ChanID,
   203  			&d.OpenedCircuitKeys[i].HtlcID)
   204  		if err != nil {
   205  			return nil, err
   206  		}
   207  	}
   208  
   209  	var numClosedRefs uint16
   210  	if err := binary.Read(r, byteOrder, &numClosedRefs); err != nil {
   211  		return nil, err
   212  	}
   213  
   214  	d.ClosedCircuitKeys = make([]common.CircuitKey, numClosedRefs)
   215  	for i := 0; i < int(numClosedRefs); i++ {
   216  		err := ReadElements(r,
   217  			&d.ClosedCircuitKeys[i].ChanID,
   218  			&d.ClosedCircuitKeys[i].HtlcID)
   219  		if err != nil {
   220  			return nil, err
   221  		}
   222  	}
   223  
   224  	return &d, nil
   225  }
   226  
   227  func SerializeNetworkResult(w io.Writer, n *common.NetworkResult) error { // nolint: dupl
   228  	return WriteElements(w, n.Msg, n.Unencrypted, n.IsResolution)
   229  }
   230  
   231  func DeserializeNetworkResult(r io.Reader) (*common.NetworkResult, error) { // nolint: dupl
   232  	n := &common.NetworkResult{}
   233  
   234  	if err := ReadElements(r,
   235  		&n.Msg, &n.Unencrypted, &n.IsResolution,
   236  	); err != nil {
   237  		return nil, err
   238  	}
   239  
   240  	return n, nil
   241  }
   242  
   243  func writeChanConfig(b io.Writer, c *common.ChannelConfig) error { // nolint: dupl
   244  	return WriteElements(b,
   245  		c.DustLimit, c.MaxPendingAmount, c.ChanReserve, c.MinHTLC,
   246  		c.MaxAcceptedHtlcs, c.CsvDelay, c.MultiSigKey,
   247  		c.RevocationBasePoint, c.PaymentBasePoint, c.DelayBasePoint,
   248  		c.HtlcBasePoint,
   249  	)
   250  }
   251  
   252  func SerializeChannelCloseSummary(w io.Writer, cs *common.ChannelCloseSummary) error { // nolint: dupl
   253  	err := WriteElements(w,
   254  		cs.ChanPoint, cs.ShortChanID, cs.ChainHash, cs.ClosingTXID,
   255  		cs.CloseHeight, cs.RemotePub, cs.Capacity, cs.SettledBalance,
   256  		cs.TimeLockedBalance, cs.CloseType, cs.IsPending,
   257  	)
   258  	if err != nil {
   259  		return err
   260  	}
   261  
   262  	// If this is a close channel summary created before the addition of
   263  	// the new fields, then we can exit here.
   264  	if cs.RemoteCurrentRevocation == nil {
   265  		return WriteElements(w, false)
   266  	}
   267  
   268  	// If fields are present, write boolean to indicate this, and continue.
   269  	if err := WriteElements(w, true); err != nil {
   270  		return err
   271  	}
   272  
   273  	if err := WriteElements(w, cs.RemoteCurrentRevocation); err != nil {
   274  		return err
   275  	}
   276  
   277  	if err := writeChanConfig(w, &cs.LocalChanConfig); err != nil {
   278  		return err
   279  	}
   280  
   281  	// The RemoteNextRevocation field is optional, as it's possible for a
   282  	// channel to be closed before we learn of the next unrevoked
   283  	// revocation point for the remote party. Write a boolen indicating
   284  	// whether this field is present or not.
   285  	if err := WriteElements(w, cs.RemoteNextRevocation != nil); err != nil {
   286  		return err
   287  	}
   288  
   289  	// Write the field, if present.
   290  	if cs.RemoteNextRevocation != nil {
   291  		if err = WriteElements(w, cs.RemoteNextRevocation); err != nil {
   292  			return err
   293  		}
   294  	}
   295  
   296  	// Write whether the channel sync message is present.
   297  	if err := WriteElements(w, cs.LastChanSyncMsg != nil); err != nil {
   298  		return err
   299  	}
   300  
   301  	// Write the channel sync message, if present.
   302  	if cs.LastChanSyncMsg != nil {
   303  		if err := WriteElements(w, cs.LastChanSyncMsg); err != nil {
   304  			return err
   305  		}
   306  	}
   307  
   308  	return nil
   309  }
   310  
   311  func readChanConfig(b io.Reader, c *common.ChannelConfig) error {
   312  	return ReadElements(b,
   313  		&c.DustLimit, &c.MaxPendingAmount, &c.ChanReserve,
   314  		&c.MinHTLC, &c.MaxAcceptedHtlcs, &c.CsvDelay,
   315  		&c.MultiSigKey, &c.RevocationBasePoint,
   316  		&c.PaymentBasePoint, &c.DelayBasePoint,
   317  		&c.HtlcBasePoint,
   318  	)
   319  }
   320  
   321  func DeserializeCloseChannelSummary(r io.Reader) (*common.ChannelCloseSummary, error) { // nolint: dupl
   322  	c := &common.ChannelCloseSummary{}
   323  
   324  	err := ReadElements(r,
   325  		&c.ChanPoint, &c.ShortChanID, &c.ChainHash, &c.ClosingTXID,
   326  		&c.CloseHeight, &c.RemotePub, &c.Capacity, &c.SettledBalance,
   327  		&c.TimeLockedBalance, &c.CloseType, &c.IsPending,
   328  	)
   329  	if err != nil {
   330  		return nil, err
   331  	}
   332  
   333  	// We'll now check to see if the channel close summary was encoded with
   334  	// any of the additional optional fields.
   335  	var hasNewFields bool
   336  	err = ReadElements(r, &hasNewFields)
   337  	if err != nil {
   338  		return nil, err
   339  	}
   340  
   341  	// If fields are not present, we can return.
   342  	if !hasNewFields {
   343  		return c, nil
   344  	}
   345  
   346  	// Otherwise read the new fields.
   347  	if err := ReadElements(r, &c.RemoteCurrentRevocation); err != nil {
   348  		return nil, err
   349  	}
   350  
   351  	if err := readChanConfig(r, &c.LocalChanConfig); err != nil {
   352  		return nil, err
   353  	}
   354  
   355  	// Finally, we'll attempt to read the next unrevoked commitment point
   356  	// for the remote party. If we closed the channel before receiving a
   357  	// funding locked message then this might not be present. A boolean
   358  	// indicating whether the field is present will come first.
   359  	var hasRemoteNextRevocation bool
   360  	err = ReadElements(r, &hasRemoteNextRevocation)
   361  	if err != nil {
   362  		return nil, err
   363  	}
   364  
   365  	// If this field was written, read it.
   366  	if hasRemoteNextRevocation {
   367  		err = ReadElements(r, &c.RemoteNextRevocation)
   368  		if err != nil {
   369  			return nil, err
   370  		}
   371  	}
   372  
   373  	// Check if we have a channel sync message to read.
   374  	var hasChanSyncMsg bool
   375  	err = ReadElements(r, &hasChanSyncMsg)
   376  	if err == io.EOF {
   377  		return c, nil
   378  	} else if err != nil {
   379  		return nil, err
   380  	}
   381  
   382  	// If a chan sync message is present, read it.
   383  	if hasChanSyncMsg {
   384  		// We must pass in reference to a lnwire.Message for the codec
   385  		// to support it.
   386  		var msg lnwire.Message
   387  		if err := ReadElements(r, &msg); err != nil {
   388  			return nil, err
   389  		}
   390  
   391  		chanSync, ok := msg.(*lnwire.ChannelReestablish)
   392  		if !ok {
   393  			return nil, errors.New("unable cast db Message to " +
   394  				"ChannelReestablish")
   395  		}
   396  		c.LastChanSyncMsg = chanSync
   397  	}
   398  
   399  	return c, nil
   400  }
   401  
   402  // ErrCorruptedFwdPkg signals that the on-disk structure of the forwarding
   403  // package has potentially been mangled.
   404  var ErrCorruptedFwdPkg = errors.New("fwding package db has been corrupted")
   405  
   406  var (
   407  	// fwdPackagesKey is the root-level bucket that all forwarding packages
   408  	// are written. This bucket is further subdivided based on the short
   409  	// channel ID of each channel.
   410  	fwdPackagesKey = []byte("fwd-packages")
   411  
   412  	// addBucketKey is the bucket to which all Add log updates are written.
   413  	addBucketKey = []byte("add-updates")
   414  
   415  	// failSettleBucketKey is the bucket to which all Settle/Fail log
   416  	// updates are written.
   417  	failSettleBucketKey = []byte("fail-settle-updates")
   418  
   419  	// fwdFilterKey is a key used to write the set of Adds that passed
   420  	// validation and are to be forwarded to the switch.
   421  	// NOTE: The presence of this key within a forwarding package indicates
   422  	// that the package has reached FwdStateProcessed.
   423  	fwdFilterKey = []byte("fwd-filter-key")
   424  
   425  	// ackFilterKey is a key used to access the PkgFilter indicating which
   426  	// Adds have received a Settle/Fail. This response may come from a
   427  	// number of sources, including: exitHop settle/fails, switch failures,
   428  	// chain arbiter interjections, as well as settle/fails from the
   429  	// next hop in the route.
   430  	ackFilterKey = []byte("ack-filter-key")
   431  
   432  	// settleFailFilterKey is a key used to access the PkgFilter indicating
   433  	// which Settles/Fails in have been received and processed by the link
   434  	// that originally received the Add.
   435  	settleFailFilterKey = []byte("settle-fail-filter-key")
   436  )
   437  
   438  func makeLogKey(updateNum uint64) [8]byte {
   439  	var key [8]byte
   440  	byteOrder.PutUint64(key[:], updateNum)
   441  	return key
   442  }
   443  
   444  // uint16Key writes the provided 16-bit unsigned integer to a 2-byte slice.
   445  func uint16Key(i uint16) []byte {
   446  	key := make([]byte, 2)
   447  	byteOrder.PutUint16(key, i)
   448  	return key
   449  }
   450  
   451  // ChannelPackager is used by a channel to manage the lifecycle of its forwarding
   452  // packages. The packager is tied to a particular source channel ID, allowing it
   453  // to create and edit its own packages. Each packager also has the ability to
   454  // remove fail/settle htlcs that correspond to an add contained in one of
   455  // source's packages.
   456  type ChannelPackager struct {
   457  	source lnwire.ShortChannelID
   458  }
   459  
   460  // NewChannelPackager creates a new packager for a single channel.
   461  func NewChannelPackager(source lnwire.ShortChannelID) *ChannelPackager {
   462  	return &ChannelPackager{
   463  		source: source,
   464  	}
   465  }
   466  
   467  // AddFwdPkg writes a newly locked in forwarding package to disk.
   468  func (*ChannelPackager) AddFwdPkg(tx kvdb.RwTx, fwdPkg *common.FwdPkg) error { // nolint: dupl
   469  	fwdPkgBkt, err := tx.CreateTopLevelBucket(fwdPackagesKey)
   470  	if err != nil {
   471  		return err
   472  	}
   473  
   474  	source := makeLogKey(fwdPkg.Source.ToUint64())
   475  	sourceBkt, err := fwdPkgBkt.CreateBucketIfNotExists(source[:])
   476  	if err != nil {
   477  		return err
   478  	}
   479  
   480  	heightKey := makeLogKey(fwdPkg.Height)
   481  	heightBkt, err := sourceBkt.CreateBucketIfNotExists(heightKey[:])
   482  	if err != nil {
   483  		return err
   484  	}
   485  
   486  	// Write ADD updates we received at this commit height.
   487  	addBkt, err := heightBkt.CreateBucketIfNotExists(addBucketKey)
   488  	if err != nil {
   489  		return err
   490  	}
   491  
   492  	// Write SETTLE/FAIL updates we received at this commit height.
   493  	failSettleBkt, err := heightBkt.CreateBucketIfNotExists(failSettleBucketKey)
   494  	if err != nil {
   495  		return err
   496  	}
   497  
   498  	for i := range fwdPkg.Adds {
   499  		err = putLogUpdate(addBkt, uint16(i), &fwdPkg.Adds[i])
   500  		if err != nil {
   501  			return err
   502  		}
   503  	}
   504  
   505  	// Persist the initialized pkg filter, which will be used to determine
   506  	// when we can remove this forwarding package from disk.
   507  	var ackFilterBuf bytes.Buffer
   508  	if err := fwdPkg.AckFilter.Encode(&ackFilterBuf); err != nil {
   509  		return err
   510  	}
   511  
   512  	if err := heightBkt.Put(ackFilterKey, ackFilterBuf.Bytes()); err != nil {
   513  		return err
   514  	}
   515  
   516  	for i := range fwdPkg.SettleFails {
   517  		err = putLogUpdate(failSettleBkt, uint16(i), &fwdPkg.SettleFails[i])
   518  		if err != nil {
   519  			return err
   520  		}
   521  	}
   522  
   523  	var settleFailFilterBuf bytes.Buffer
   524  	err = fwdPkg.SettleFailFilter.Encode(&settleFailFilterBuf)
   525  	if err != nil {
   526  		return err
   527  	}
   528  
   529  	return heightBkt.Put(settleFailFilterKey, settleFailFilterBuf.Bytes())
   530  }
   531  
   532  // putLogUpdate writes an htlc to the provided `bkt`, using `index` as the key.
   533  func putLogUpdate(bkt kvdb.RwBucket, idx uint16, htlc *common.LogUpdate) error {
   534  	var b bytes.Buffer
   535  	if err := serializeLogUpdate(&b, htlc); err != nil {
   536  		return err
   537  	}
   538  
   539  	return bkt.Put(uint16Key(idx), b.Bytes())
   540  }
   541  
   542  // LoadFwdPkgs scans the forwarding log for any packages that haven't been
   543  // processed, and returns their deserialized log updates in a map indexed by the
   544  // remote commitment height at which the updates were locked in.
   545  func (p *ChannelPackager) LoadFwdPkgs(tx kvdb.RTx) ([]*common.FwdPkg, error) {
   546  	return loadChannelFwdPkgs(tx, p.source)
   547  }
   548  
   549  // loadChannelFwdPkgs loads all forwarding packages owned by `source`.
   550  func loadChannelFwdPkgs(tx kvdb.RTx, source lnwire.ShortChannelID) ([]*common.FwdPkg, error) { // nolint: dupl
   551  	fwdPkgBkt := tx.ReadBucket(fwdPackagesKey)
   552  	if fwdPkgBkt == nil {
   553  		return nil, nil
   554  	}
   555  
   556  	sourceKey := makeLogKey(source.ToUint64())
   557  	sourceBkt := fwdPkgBkt.NestedReadBucket(sourceKey[:])
   558  	if sourceBkt == nil {
   559  		return nil, nil
   560  	}
   561  
   562  	var heights []uint64
   563  	if err := sourceBkt.ForEach(func(k, _ []byte) error {
   564  		if len(k) != 8 {
   565  			return ErrCorruptedFwdPkg
   566  		}
   567  
   568  		heights = append(heights, byteOrder.Uint64(k))
   569  
   570  		return nil
   571  	}); err != nil {
   572  		return nil, err
   573  	}
   574  
   575  	// Load the forwarding package for each retrieved height.
   576  	fwdPkgs := make([]*common.FwdPkg, 0, len(heights))
   577  	for _, height := range heights {
   578  		fwdPkg, err := loadFwdPkg(fwdPkgBkt, source, height)
   579  		if err != nil {
   580  			return nil, err
   581  		}
   582  
   583  		fwdPkgs = append(fwdPkgs, fwdPkg)
   584  	}
   585  
   586  	return fwdPkgs, nil
   587  }
   588  
   589  // loadFwdPkg reads the packager's fwd pkg at a given height, and determines the
   590  // appropriate FwdState.
   591  func loadFwdPkg(fwdPkgBkt kvdb.RBucket, source lnwire.ShortChannelID,
   592  	height uint64) (*common.FwdPkg, error) {
   593  
   594  	sourceKey := makeLogKey(source.ToUint64())
   595  	sourceBkt := fwdPkgBkt.NestedReadBucket(sourceKey[:])
   596  	if sourceBkt == nil {
   597  		return nil, ErrCorruptedFwdPkg
   598  	}
   599  
   600  	heightKey := makeLogKey(height)
   601  	heightBkt := sourceBkt.NestedReadBucket(heightKey[:])
   602  	if heightBkt == nil {
   603  		return nil, ErrCorruptedFwdPkg
   604  	}
   605  
   606  	// Load ADDs from disk.
   607  	addBkt := heightBkt.NestedReadBucket(addBucketKey)
   608  	if addBkt == nil {
   609  		return nil, ErrCorruptedFwdPkg
   610  	}
   611  
   612  	adds, err := loadHtlcs(addBkt)
   613  	if err != nil {
   614  		return nil, err
   615  	}
   616  
   617  	// Load ack filter from disk.
   618  	ackFilterBytes := heightBkt.Get(ackFilterKey)
   619  	if ackFilterBytes == nil {
   620  		return nil, ErrCorruptedFwdPkg
   621  	}
   622  	ackFilterReader := bytes.NewReader(ackFilterBytes)
   623  
   624  	ackFilter := &common.PkgFilter{}
   625  	if err := ackFilter.Decode(ackFilterReader); err != nil {
   626  		return nil, err
   627  	}
   628  
   629  	// Load SETTLE/FAILs from disk.
   630  	failSettleBkt := heightBkt.NestedReadBucket(failSettleBucketKey)
   631  	if failSettleBkt == nil {
   632  		return nil, ErrCorruptedFwdPkg
   633  	}
   634  
   635  	failSettles, err := loadHtlcs(failSettleBkt)
   636  	if err != nil {
   637  		return nil, err
   638  	}
   639  
   640  	// Load settle fail filter from disk.
   641  	settleFailFilterBytes := heightBkt.Get(settleFailFilterKey)
   642  	if settleFailFilterBytes == nil {
   643  		return nil, ErrCorruptedFwdPkg
   644  	}
   645  	settleFailFilterReader := bytes.NewReader(settleFailFilterBytes)
   646  
   647  	settleFailFilter := &common.PkgFilter{}
   648  	if err := settleFailFilter.Decode(settleFailFilterReader); err != nil {
   649  		return nil, err
   650  	}
   651  
   652  	// Initialize the fwding package, which always starts in the
   653  	// FwdStateLockedIn. We can determine what state the package was left in
   654  	// by examining constraints on the information loaded from disk.
   655  	fwdPkg := &common.FwdPkg{
   656  		Source:           source,
   657  		State:            common.FwdStateLockedIn,
   658  		Height:           height,
   659  		Adds:             adds,
   660  		AckFilter:        ackFilter,
   661  		SettleFails:      failSettles,
   662  		SettleFailFilter: settleFailFilter,
   663  	}
   664  
   665  	// Check to see if we have written the set exported filter adds to
   666  	// disk. If we haven't, processing of this package was never started, or
   667  	// failed during the last attempt.
   668  	fwdFilterBytes := heightBkt.Get(fwdFilterKey)
   669  	if fwdFilterBytes == nil {
   670  		nAdds := uint16(len(adds))
   671  		fwdPkg.FwdFilter = common.NewPkgFilter(nAdds)
   672  		return fwdPkg, nil
   673  	}
   674  
   675  	fwdFilterReader := bytes.NewReader(fwdFilterBytes)
   676  	fwdPkg.FwdFilter = &common.PkgFilter{}
   677  	if err := fwdPkg.FwdFilter.Decode(fwdFilterReader); err != nil {
   678  		return nil, err
   679  	}
   680  
   681  	// Otherwise, a complete round of processing was completed, and we
   682  	// advance the package to FwdStateProcessed.
   683  	fwdPkg.State = common.FwdStateProcessed
   684  
   685  	// If every add, settle, and fail has been fully acknowledged, we can
   686  	// safely set the package's state to FwdStateCompleted, signalling that
   687  	// it can be garbage collected.
   688  	if fwdPkg.AckFilter.IsFull() && fwdPkg.SettleFailFilter.IsFull() {
   689  		fwdPkg.State = common.FwdStateCompleted
   690  	}
   691  
   692  	return fwdPkg, nil
   693  }
   694  
   695  // loadHtlcs retrieves all serialized htlcs in a bucket, returning
   696  // them in order of the indexes they were written under.
   697  func loadHtlcs(bkt kvdb.RBucket) ([]common.LogUpdate, error) {
   698  	var htlcs []common.LogUpdate
   699  	if err := bkt.ForEach(func(_, v []byte) error {
   700  		htlc, err := deserializeLogUpdate(bytes.NewReader(v))
   701  		if err != nil {
   702  			return err
   703  		}
   704  
   705  		htlcs = append(htlcs, *htlc)
   706  
   707  		return nil
   708  	}); err != nil {
   709  		return nil, err
   710  	}
   711  
   712  	return htlcs, nil
   713  }
   714  
   715  // serializeLogUpdate writes a log update to the provided io.Writer.
   716  func serializeLogUpdate(w io.Writer, l *common.LogUpdate) error {
   717  	return WriteElements(w, l.LogIndex, l.UpdateMsg)
   718  }
   719  
   720  // deserializeLogUpdate reads a log update from the provided io.Reader.
   721  func deserializeLogUpdate(r io.Reader) (*common.LogUpdate, error) {
   722  	l := &common.LogUpdate{}
   723  	if err := ReadElements(r, &l.LogIndex, &l.UpdateMsg); err != nil {
   724  		return nil, err
   725  	}
   726  
   727  	return l, nil
   728  }