github.com/decred/dcrlnd@v0.7.6/channeldb/migration21/legacy/legacy_decoding.go (about)

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