github.com/decred/dcrlnd@v0.7.6/channeldb/migration21/common/enclosed_types.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"io"
     7  
     8  	"github.com/decred/dcrd/chaincfg/chainhash"
     9  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
    10  	"github.com/decred/dcrd/dcrutil/v4"
    11  	"github.com/decred/dcrd/wire"
    12  	lnwire "github.com/decred/dcrlnd/channeldb/migration/lnwire21"
    13  	"github.com/decred/dcrlnd/keychain"
    14  )
    15  
    16  // CircuitKey is used by a channel to uniquely identify the HTLCs it receives
    17  // from the switch, and is used to purge our in-memory state of HTLCs that have
    18  // already been processed by a link. Two list of CircuitKeys are included in
    19  // each CommitDiff to allow a link to determine which in-memory htlcs directed
    20  // the opening and closing of circuits in the switch's circuit map.
    21  type CircuitKey struct {
    22  	// ChanID is the short chanid indicating the HTLC's origin.
    23  	//
    24  	// NOTE: It is fine for this value to be blank, as this indicates a
    25  	// locally-sourced payment.
    26  	ChanID lnwire.ShortChannelID
    27  
    28  	// HtlcID is the unique htlc index predominately assigned by links,
    29  	// though can also be assigned by switch in the case of locally-sourced
    30  	// payments.
    31  	HtlcID uint64
    32  }
    33  
    34  // HTLC is the on-disk representation of a hash time-locked contract. HTLCs are
    35  // contained within ChannelDeltas which encode the current state of the
    36  // commitment between state updates.
    37  //
    38  // TODO(roasbeef): save space by using smaller ints at tail end?
    39  type HTLC struct {
    40  	// Signature is the signature for the second level covenant transaction
    41  	// for this HTLC. The second level transaction is a timeout tx in the
    42  	// case that this is an outgoing HTLC, and a success tx in the case
    43  	// that this is an incoming HTLC.
    44  	//
    45  	// TODO(roasbeef): make [64]byte instead?
    46  	Signature []byte
    47  
    48  	// RHash is the payment hash of the HTLC.
    49  	RHash [32]byte
    50  
    51  	// Amt is the amount of milli-atoms this HTLC escrows.
    52  	Amt lnwire.MilliAtom
    53  
    54  	// RefundTimeout is the absolute timeout on the HTLC that the sender
    55  	// must wait before reclaiming the funds in limbo.
    56  	RefundTimeout uint32
    57  
    58  	// OutputIndex is the output index for this particular HTLC output
    59  	// within the commitment transaction.
    60  	OutputIndex int32
    61  
    62  	// Incoming denotes whether we're the receiver or the sender of this
    63  	// HTLC.
    64  	Incoming bool
    65  
    66  	// OnionBlob is an opaque blob which is used to complete multi-hop
    67  	// routing.
    68  	OnionBlob []byte
    69  
    70  	// HtlcIndex is the HTLC counter index of this active, outstanding
    71  	// HTLC. This differs from the LogIndex, as the HtlcIndex is only
    72  	// incremented for each offered HTLC, while they LogIndex is
    73  	// incremented for each update (includes settle+fail).
    74  	HtlcIndex uint64
    75  
    76  	// LogIndex is the cumulative log index of this HTLC. This differs
    77  	// from the HtlcIndex as this will be incremented for each new log
    78  	// update added.
    79  	LogIndex uint64
    80  }
    81  
    82  // ChannelCommitment is a snapshot of the commitment state at a particular
    83  // point in the commitment chain. With each state transition, a snapshot of the
    84  // current state along with all non-settled HTLCs are recorded. These snapshots
    85  // detail the state of the _remote_ party's commitment at a particular state
    86  // number.  For ourselves (the local node) we ONLY store our most recent
    87  // (unrevoked) state for safety purposes.
    88  type ChannelCommitment struct {
    89  	// CommitHeight is the update number that this ChannelDelta represents
    90  	// the total number of commitment updates to this point. This can be
    91  	// viewed as sort of a "commitment height" as this number is
    92  	// monotonically increasing.
    93  	CommitHeight uint64
    94  
    95  	// LocalLogIndex is the cumulative log index index of the local node at
    96  	// this point in the commitment chain. This value will be incremented
    97  	// for each _update_ added to the local update log.
    98  	LocalLogIndex uint64
    99  
   100  	// LocalHtlcIndex is the current local running HTLC index. This value
   101  	// will be incremented for each outgoing HTLC the local node offers.
   102  	LocalHtlcIndex uint64
   103  
   104  	// RemoteLogIndex is the cumulative log index index of the remote node
   105  	// at this point in the commitment chain. This value will be
   106  	// incremented for each _update_ added to the remote update log.
   107  	RemoteLogIndex uint64
   108  
   109  	// RemoteHtlcIndex is the current remote running HTLC index. This value
   110  	// will be incremented for each outgoing HTLC the remote node offers.
   111  	RemoteHtlcIndex uint64
   112  
   113  	// LocalBalance is the current available settled balance within the
   114  	// channel directly spendable by us.
   115  	//
   116  	// NOTE: This is the balance *after* subtracting any commitment fee,
   117  	// AND anchor output values.
   118  	LocalBalance lnwire.MilliAtom
   119  
   120  	// RemoteBalance is the current available settled balance within the
   121  	// channel directly spendable by the remote node.
   122  	//
   123  	// NOTE: This is the balance *after* subtracting any commitment fee,
   124  	// AND anchor output values.
   125  	RemoteBalance lnwire.MilliAtom
   126  
   127  	// CommitFee is the amount calculated to be paid in fees for the
   128  	// current set of commitment transactions. The fee amount is persisted
   129  	// with the channel in order to allow the fee amount to be removed and
   130  	// recalculated with each channel state update, including updates that
   131  	// happen after a system restart.
   132  	CommitFee dcrutil.Amount
   133  
   134  	// FeePerKB is the min atoms/kilobyte that should be paid within the
   135  	// commitment transaction for the entire duration of the channel's
   136  	// lifetime. This field may be updated during normal operation of the
   137  	// channel as on-chain conditions change.
   138  	//
   139  	// TODO(halseth): make this AtomsPerKByte. Cannot be done atm because
   140  	// this will cause the import cycle lnwallet<->channeldb. Fee
   141  	// estimation stuff should be in its own package.
   142  	FeePerKB dcrutil.Amount
   143  
   144  	// CommitTx is the latest version of the commitment state, broadcast
   145  	// able by us.
   146  	CommitTx *wire.MsgTx
   147  
   148  	// CommitSig is one half of the signature required to fully complete
   149  	// the script for the commitment transaction above. This is the
   150  	// signature signed by the remote party for our version of the
   151  	// commitment transactions.
   152  	CommitSig []byte
   153  
   154  	// Htlcs is the set of HTLC's that are pending at this particular
   155  	// commitment height.
   156  	Htlcs []HTLC
   157  
   158  	// TODO(roasbeef): pending commit pointer?
   159  	//  * lets just walk through
   160  }
   161  
   162  // LogUpdate represents a pending update to the remote commitment chain. The
   163  // log update may be an add, fail, or settle entry. We maintain this data in
   164  // order to be able to properly retransmit our proposed
   165  // state if necessary.
   166  type LogUpdate struct {
   167  	// LogIndex is the log index of this proposed commitment update entry.
   168  	LogIndex uint64
   169  
   170  	// UpdateMsg is the update message that was included within the our
   171  	// local update log. The LogIndex value denotes the log index of this
   172  	// update which will be used when restoring our local update log if
   173  	// we're left with a dangling update on restart.
   174  	UpdateMsg lnwire.Message
   175  }
   176  
   177  // AddRef is used to identify a particular Add in a FwdPkg. The short channel ID
   178  // is assumed to be that of the packager.
   179  type AddRef struct {
   180  	// Height is the remote commitment height that locked in the Add.
   181  	Height uint64
   182  
   183  	// Index is the index of the Add within the fwd pkg's Adds.
   184  	//
   185  	// NOTE: This index is static over the lifetime of a forwarding package.
   186  	Index uint16
   187  }
   188  
   189  // SettleFailRef is used to locate a Settle/Fail in another channel's FwdPkg. A
   190  // channel does not remove its own Settle/Fail htlcs, so the source is provided
   191  // to locate a db bucket belonging to another channel.
   192  type SettleFailRef struct {
   193  	// Source identifies the outgoing link that locked in the settle or
   194  	// fail. This is then used by the *incoming* link to find the settle
   195  	// fail in another link's forwarding packages.
   196  	Source lnwire.ShortChannelID
   197  
   198  	// Height is the remote commitment height that locked in this
   199  	// Settle/Fail.
   200  	Height uint64
   201  
   202  	// Index is the index of the Add with the fwd pkg's SettleFails.
   203  	//
   204  	// NOTE: This index is static over the lifetime of a forwarding package.
   205  	Index uint16
   206  }
   207  
   208  // CommitDiff represents the delta needed to apply the state transition between
   209  // two subsequent commitment states. Given state N and state N+1, one is able
   210  // to apply the set of messages contained within the CommitDiff to N to arrive
   211  // at state N+1. Each time a new commitment is extended, we'll write a new
   212  // commitment (along with the full commitment state) to disk so we can
   213  // re-transmit the state in the case of a connection loss or message drop.
   214  type CommitDiff struct {
   215  	// ChannelCommitment is the full commitment state that one would arrive
   216  	// at by applying the set of messages contained in the UpdateDiff to
   217  	// the prior accepted commitment.
   218  	Commitment ChannelCommitment
   219  
   220  	// LogUpdates is the set of messages sent prior to the commitment state
   221  	// transition in question. Upon reconnection, if we detect that they
   222  	// don't have the commitment, then we re-send this along with the
   223  	// proper signature.
   224  	LogUpdates []LogUpdate
   225  
   226  	// CommitSig is the exact CommitSig message that should be sent after
   227  	// the set of LogUpdates above has been retransmitted. The signatures
   228  	// within this message should properly cover the new commitment state
   229  	// and also the HTLC's within the new commitment state.
   230  	CommitSig *lnwire.CommitSig
   231  
   232  	// OpenedCircuitKeys is a set of unique identifiers for any downstream
   233  	// Add packets included in this commitment txn. After a restart, this
   234  	// set of htlcs is acked from the link's incoming mailbox to ensure
   235  	// there isn't an attempt to re-add them to this commitment txn.
   236  	OpenedCircuitKeys []CircuitKey
   237  
   238  	// ClosedCircuitKeys records the unique identifiers for any settle/fail
   239  	// packets that were resolved by this commitment txn. After a restart,
   240  	// this is used to ensure those circuits are removed from the circuit
   241  	// map, and the downstream packets in the link's mailbox are removed.
   242  	ClosedCircuitKeys []CircuitKey
   243  
   244  	// AddAcks specifies the locations (commit height, pkg index) of any
   245  	// Adds that were failed/settled in this commit diff. This will ack
   246  	// entries in *this* channel's forwarding packages.
   247  	//
   248  	// NOTE: This value is not serialized, it is used to atomically mark the
   249  	// resolution of adds, such that they will not be reprocessed after a
   250  	// restart.
   251  	AddAcks []AddRef
   252  
   253  	// SettleFailAcks specifies the locations (chan id, commit height, pkg
   254  	// index) of any Settles or Fails that were locked into this commit
   255  	// diff, and originate from *another* channel, i.e. the outgoing link.
   256  	//
   257  	// NOTE: This value is not serialized, it is used to atomically acks
   258  	// settles and fails from the forwarding packages of other channels,
   259  	// such that they will not be reforwarded internally after a restart.
   260  	SettleFailAcks []SettleFailRef
   261  }
   262  
   263  // NetworkResult is the raw result received from the network after a payment
   264  // attempt has been made. Since the switch doesn't always have the necessary
   265  // data to decode the raw message, we store it together with some meta data,
   266  // and decode it when the router query for the final result.
   267  type NetworkResult struct {
   268  	// Msg is the received result. This should be of type UpdateFulfillHTLC
   269  	// or UpdateFailHTLC.
   270  	Msg lnwire.Message
   271  
   272  	// unencrypted indicates whether the failure encoded in the message is
   273  	// unencrypted, and hence doesn't need to be decrypted.
   274  	Unencrypted bool
   275  
   276  	// IsResolution indicates whether this is a resolution message, in
   277  	// which the failure reason might not be included.
   278  	IsResolution bool
   279  }
   280  
   281  // ClosureType is an enum like structure that details exactly _how_ a channel
   282  // was closed. Three closure types are currently possible: none, cooperative,
   283  // local force close, remote force close, and (remote) breach.
   284  type ClosureType uint8
   285  
   286  // ChannelConstraints represents a set of constraints meant to allow a node to
   287  // limit their exposure, enact flow control and ensure that all HTLCs are
   288  // economically relevant. This struct will be mirrored for both sides of the
   289  // channel, as each side will enforce various constraints that MUST be adhered
   290  // to for the life time of the channel. The parameters for each of these
   291  // constraints are static for the duration of the channel, meaning the channel
   292  // must be torn down for them to change.
   293  type ChannelConstraints struct {
   294  	// DustLimit is the threhsold (in atoms) below which any outputs
   295  	// should be trimmed. When an output is trimmed, it isn't materialized
   296  	// as an actual output, but is instead burned to miner's fees.
   297  	DustLimit dcrutil.Amount
   298  
   299  	// ChanReserve is an absolute reservation on the channel for the
   300  	// owner of this set of constraints. This means that the current
   301  	// settled balance for this node CANNOT dip below the reservation
   302  	// amount. This acts as a defense against costless attacks when
   303  	// either side no longer has any skin in the game.
   304  	ChanReserve dcrutil.Amount
   305  
   306  	// MaxPendingAmount is the maximum pending HTLC value that the
   307  	// owner of these constraints can offer the remote node at a
   308  	// particular time.
   309  	MaxPendingAmount lnwire.MilliAtom
   310  
   311  	// MinHTLC is the minimum HTLC value that the owner of these
   312  	// constraints can offer the remote node. If any HTLCs below this
   313  	// amount are offered, then the HTLC will be rejected. This, in
   314  	// tandem with the dust limit allows a node to regulate the
   315  	// smallest HTLC that it deems economically relevant.
   316  	MinHTLC lnwire.MilliAtom
   317  
   318  	// MaxAcceptedHtlcs is the maximum number of HTLCs that the owner of
   319  	// this set of constraints can offer the remote node. This allows each
   320  	// node to limit their over all exposure to HTLCs that may need to be
   321  	// acted upon in the case of a unilateral channel closure or a contract
   322  	// breach.
   323  	MaxAcceptedHtlcs uint16
   324  
   325  	// CsvDelay is the relative time lock delay expressed in blocks. Any
   326  	// settled outputs that pay to the owner of this channel configuration
   327  	// MUST ensure that the delay branch uses this value as the relative
   328  	// time lock. Similarly, any HTLC's offered by this node should use
   329  	// this value as well.
   330  	CsvDelay uint16
   331  }
   332  
   333  // ChannelConfig is a struct that houses the various configuration opens for
   334  // channels. Each side maintains an instance of this configuration file as it
   335  // governs: how the funding and commitment transaction to be created, the
   336  // nature of HTLC's allotted, the keys to be used for delivery, and relative
   337  // time lock parameters.
   338  type ChannelConfig struct {
   339  	// ChannelConstraints is the set of constraints that must be upheld for
   340  	// the duration of the channel for the owner of this channel
   341  	// configuration. Constraints govern a number of flow control related
   342  	// parameters, also including the smallest HTLC that will be accepted
   343  	// by a participant.
   344  	ChannelConstraints
   345  
   346  	// MultiSigKey is the key to be used within the 2-of-2 output script
   347  	// for the owner of this channel config.
   348  	MultiSigKey keychain.KeyDescriptor
   349  
   350  	// RevocationBasePoint is the base public key to be used when deriving
   351  	// revocation keys for the remote node's commitment transaction. This
   352  	// will be combined along with a per commitment secret to derive a
   353  	// unique revocation key for each state.
   354  	RevocationBasePoint keychain.KeyDescriptor
   355  
   356  	// PaymentBasePoint is the base public key to be used when deriving
   357  	// the key used within the non-delayed pay-to-self output on the
   358  	// commitment transaction for a node. This will be combined with a
   359  	// tweak derived from the per-commitment point to ensure unique keys
   360  	// for each commitment transaction.
   361  	PaymentBasePoint keychain.KeyDescriptor
   362  
   363  	// DelayBasePoint is the base public key to be used when deriving the
   364  	// key used within the delayed pay-to-self output on the commitment
   365  	// transaction for a node. This will be combined with a tweak derived
   366  	// from the per-commitment point to ensure unique keys for each
   367  	// commitment transaction.
   368  	DelayBasePoint keychain.KeyDescriptor
   369  
   370  	// HtlcBasePoint is the base public key to be used when deriving the
   371  	// local HTLC key. The derived key (combined with the tweak derived
   372  	// from the per-commitment point) is used within the "to self" clause
   373  	// within any HTLC output scripts.
   374  	HtlcBasePoint keychain.KeyDescriptor
   375  }
   376  
   377  // ChannelCloseSummary contains the final state of a channel at the point it
   378  // was closed. Once a channel is closed, all the information pertaining to that
   379  // channel within the openChannelBucket is deleted, and a compact summary is
   380  // put in place instead.
   381  type ChannelCloseSummary struct {
   382  	// ChanPoint is the outpoint for this channel's funding transaction,
   383  	// and is used as a unique identifier for the channel.
   384  	ChanPoint wire.OutPoint
   385  
   386  	// ShortChanID encodes the exact location in the chain in which the
   387  	// channel was initially confirmed. This includes: the block height,
   388  	// transaction index, and the output within the target transaction.
   389  	ShortChanID lnwire.ShortChannelID
   390  
   391  	// ChainHash is the hash of the genesis block that this channel resides
   392  	// within.
   393  	ChainHash chainhash.Hash
   394  
   395  	// ClosingTXID is the txid of the transaction which ultimately closed
   396  	// this channel.
   397  	ClosingTXID chainhash.Hash
   398  
   399  	// RemotePub is the public key of the remote peer that we formerly had
   400  	// a channel with.
   401  	RemotePub *secp256k1.PublicKey
   402  
   403  	// Capacity was the total capacity of the channel.
   404  	Capacity dcrutil.Amount
   405  
   406  	// CloseHeight is the height at which the funding transaction was
   407  	// spent.
   408  	CloseHeight uint32
   409  
   410  	// SettledBalance is our total balance settled balance at the time of
   411  	// channel closure. This _does not_ include the sum of any outputs that
   412  	// have been time-locked as a result of the unilateral channel closure.
   413  	SettledBalance dcrutil.Amount
   414  
   415  	// TimeLockedBalance is the sum of all the time-locked outputs at the
   416  	// time of channel closure. If we triggered the force closure of this
   417  	// channel, then this value will be non-zero if our settled output is
   418  	// above the dust limit. If we were on the receiving side of a channel
   419  	// force closure, then this value will be non-zero if we had any
   420  	// outstanding outgoing HTLC's at the time of channel closure.
   421  	TimeLockedBalance dcrutil.Amount
   422  
   423  	// CloseType details exactly _how_ the channel was closed. Five closure
   424  	// types are possible: cooperative, local force, remote force, breach
   425  	// and funding canceled.
   426  	CloseType ClosureType
   427  
   428  	// IsPending indicates whether this channel is in the 'pending close'
   429  	// state, which means the channel closing transaction has been
   430  	// confirmed, but not yet been fully resolved. In the case of a channel
   431  	// that has been cooperatively closed, it will go straight into the
   432  	// fully resolved state as soon as the closing transaction has been
   433  	// confirmed. However, for channels that have been force closed, they'll
   434  	// stay marked as "pending" until _all_ the pending funds have been
   435  	// swept.
   436  	IsPending bool
   437  
   438  	// RemoteCurrentRevocation is the current revocation for their
   439  	// commitment transaction. However, since this is the derived public key,
   440  	// we don't yet have the private key so we aren't yet able to verify
   441  	// that it's actually in the hash chain.
   442  	RemoteCurrentRevocation *secp256k1.PublicKey
   443  
   444  	// RemoteNextRevocation is the revocation key to be used for the *next*
   445  	// commitment transaction we create for the local node. Within the
   446  	// specification, this value is referred to as the
   447  	// per-commitment-point.
   448  	RemoteNextRevocation *secp256k1.PublicKey
   449  
   450  	// LocalChanCfg is the channel configuration for the local node.
   451  	LocalChanConfig ChannelConfig
   452  
   453  	// LastChanSyncMsg is the ChannelReestablish message for this channel
   454  	// for the state at the point where it was closed.
   455  	LastChanSyncMsg *lnwire.ChannelReestablish
   456  }
   457  
   458  // FwdState is an enum used to describe the lifecycle of a FwdPkg.
   459  type FwdState byte
   460  
   461  const (
   462  	// FwdStateLockedIn is the starting state for all forwarding packages.
   463  	// Packages in this state have not yet committed to the exact set of
   464  	// Adds to forward to the switch.
   465  	FwdStateLockedIn FwdState = iota
   466  
   467  	// FwdStateProcessed marks the state in which all Adds have been
   468  	// locally processed and the forwarding decision to the switch has been
   469  	// persisted.
   470  	FwdStateProcessed
   471  
   472  	// FwdStateCompleted signals that all Adds have been acked, and that all
   473  	// settles and fails have been delivered to their sources. Packages in
   474  	// this state can be removed permanently.
   475  	FwdStateCompleted
   476  )
   477  
   478  // PkgFilter is used to compactly represent a particular subset of the Adds in a
   479  // forwarding package. Each filter is represented as a simple, statically-sized
   480  // bitvector, where the elements are intended to be the indices of the Adds as
   481  // they are written in the FwdPkg.
   482  type PkgFilter struct {
   483  	count  uint16
   484  	filter []byte
   485  }
   486  
   487  // NewPkgFilter initializes an empty PkgFilter supporting `count` elements.
   488  func NewPkgFilter(count uint16) *PkgFilter {
   489  	// We add 7 to ensure that the integer division yields properly rounded
   490  	// values.
   491  	filterLen := (count + 7) / 8
   492  
   493  	return &PkgFilter{
   494  		count:  count,
   495  		filter: make([]byte, filterLen),
   496  	}
   497  }
   498  
   499  // Count returns the number of elements represented by this PkgFilter.
   500  func (f *PkgFilter) Count() uint16 {
   501  	return f.count
   502  }
   503  
   504  // Set marks the `i`-th element as included by this filter.
   505  // NOTE: It is assumed that i is always less than count.
   506  func (f *PkgFilter) Set(i uint16) {
   507  	byt := i / 8
   508  	bit := i % 8
   509  
   510  	// Set the i-th bit in the filter.
   511  	// TODO(conner): ignore if > count to prevent panic?
   512  	f.filter[byt] |= byte(1 << (7 - bit))
   513  }
   514  
   515  // Contains queries the filter for membership of index `i`.
   516  // NOTE: It is assumed that i is always less than count.
   517  func (f *PkgFilter) Contains(i uint16) bool {
   518  	byt := i / 8
   519  	bit := i % 8
   520  
   521  	// Read the i-th bit in the filter.
   522  	// TODO(conner): ignore if > count to prevent panic?
   523  	return f.filter[byt]&(1<<(7-bit)) != 0
   524  }
   525  
   526  // Equal checks two PkgFilters for equality.
   527  func (f *PkgFilter) Equal(f2 *PkgFilter) bool {
   528  	if f == f2 {
   529  		return true
   530  	}
   531  	if f.count != f2.count {
   532  		return false
   533  	}
   534  
   535  	return bytes.Equal(f.filter, f2.filter)
   536  }
   537  
   538  // IsFull returns true if every element in the filter has been Set, and false
   539  // otherwise.
   540  func (f *PkgFilter) IsFull() bool {
   541  	// Batch validate bytes that are fully used.
   542  	for i := uint16(0); i < f.count/8; i++ {
   543  		if f.filter[i] != 0xFF {
   544  			return false
   545  		}
   546  	}
   547  
   548  	// If the count is not a multiple of 8, check that the filter contains
   549  	// all remaining bits.
   550  	rem := f.count % 8
   551  	for idx := f.count - rem; idx < f.count; idx++ {
   552  		if !f.Contains(idx) {
   553  			return false
   554  		}
   555  	}
   556  
   557  	return true
   558  }
   559  
   560  // Size returns number of bytes produced when the PkgFilter is serialized.
   561  func (f *PkgFilter) Size() uint16 {
   562  	// 2 bytes for uint16 `count`, then round up number of bytes required to
   563  	// represent `count` bits.
   564  	return 2 + (f.count+7)/8
   565  }
   566  
   567  // Encode writes the filter to the provided io.Writer.
   568  func (f *PkgFilter) Encode(w io.Writer) error {
   569  	if err := binary.Write(w, binary.BigEndian, f.count); err != nil {
   570  		return err
   571  	}
   572  
   573  	_, err := w.Write(f.filter)
   574  
   575  	return err
   576  }
   577  
   578  // Decode reads the filter from the provided io.Reader.
   579  func (f *PkgFilter) Decode(r io.Reader) error {
   580  	if err := binary.Read(r, binary.BigEndian, &f.count); err != nil {
   581  		return err
   582  	}
   583  
   584  	f.filter = make([]byte, f.Size()-2)
   585  	_, err := io.ReadFull(r, f.filter)
   586  
   587  	return err
   588  }
   589  
   590  // FwdPkg records all adds, settles, and fails that were locked in as a result
   591  // of the remote peer sending us a revocation. Each package is identified by
   592  // the short chanid and remote commitment height corresponding to the revocation
   593  // that locked in the HTLCs. For everything except a locally initiated payment,
   594  // settles and fails in a forwarding package must have a corresponding Add in
   595  // another package, and can be removed individually once the source link has
   596  // received the fail/settle.
   597  //
   598  // Adds cannot be removed, as we need to present the same batch of Adds to
   599  // properly handle replay protection. Instead, we use a PkgFilter to mark that
   600  // we have finished processing a particular Add. A FwdPkg should only be deleted
   601  // after the AckFilter is full and all settles and fails have been persistently
   602  // removed.
   603  type FwdPkg struct {
   604  	// Source identifies the channel that wrote this forwarding package.
   605  	Source lnwire.ShortChannelID
   606  
   607  	// Height is the height of the remote commitment chain that locked in
   608  	// this forwarding package.
   609  	Height uint64
   610  
   611  	// State signals the persistent condition of the package and directs how
   612  	// to reprocess the package in the event of failures.
   613  	State FwdState
   614  
   615  	// Adds contains all add messages which need to be processed and
   616  	// forwarded to the switch. Adds does not change over the life of a
   617  	// forwarding package.
   618  	Adds []LogUpdate
   619  
   620  	// FwdFilter is a filter containing the indices of all Adds that were
   621  	// forwarded to the switch.
   622  	FwdFilter *PkgFilter
   623  
   624  	// AckFilter is a filter containing the indices of all Adds for which
   625  	// the source has received a settle or fail and is reflected in the next
   626  	// commitment txn. A package should not be removed until IsFull()
   627  	// returns true.
   628  	AckFilter *PkgFilter
   629  
   630  	// SettleFails contains all settle and fail messages that should be
   631  	// forwarded to the switch.
   632  	SettleFails []LogUpdate
   633  
   634  	// SettleFailFilter is a filter containing the indices of all Settle or
   635  	// Fails originating in this package that have been received and locked
   636  	// into the incoming link's commitment state.
   637  	SettleFailFilter *PkgFilter
   638  }
   639  
   640  // NewFwdPkg initializes a new forwarding package in FwdStateLockedIn. This
   641  // should be used to create a package at the time we receive a revocation.
   642  func NewFwdPkg(source lnwire.ShortChannelID, height uint64,
   643  	addUpdates, settleFailUpdates []LogUpdate) *FwdPkg {
   644  
   645  	nAddUpdates := uint16(len(addUpdates))
   646  	nSettleFailUpdates := uint16(len(settleFailUpdates))
   647  
   648  	return &FwdPkg{
   649  		Source:           source,
   650  		Height:           height,
   651  		State:            FwdStateLockedIn,
   652  		Adds:             addUpdates,
   653  		FwdFilter:        NewPkgFilter(nAddUpdates),
   654  		AckFilter:        NewPkgFilter(nAddUpdates),
   655  		SettleFails:      settleFailUpdates,
   656  		SettleFailFilter: NewPkgFilter(nSettleFailUpdates),
   657  	}
   658  }