github.com/decred/dcrlnd@v0.7.6/channeldb/migration/lnwire21/channel_reestablish.go (about)

     1  package lnwire
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
     7  )
     8  
     9  // ChannelReestablish is a message sent between peers that have an existing
    10  // open channel upon connection reestablishment. This message allows both sides
    11  // to report their local state, and their current knowledge of the state of the
    12  // remote commitment chain. If a deviation is detected and can be recovered
    13  // from, then the necessary messages will be retransmitted. If the level of
    14  // desynchronization is irreconcilable, then the channel will be force closed.
    15  type ChannelReestablish struct {
    16  	// ChanID is the channel ID of the channel state we're attempting to
    17  	// synchronize with the remote party.
    18  	ChanID ChannelID
    19  
    20  	// NextLocalCommitHeight is the next local commitment height of the
    21  	// sending party. If the height of the sender's commitment chain from
    22  	// the receiver's Pov is one less that this number, then the sender
    23  	// should re-send the *exact* same proposed commitment.
    24  	//
    25  	// In other words, the receiver should re-send their last sent
    26  	// commitment iff:
    27  	//
    28  	//  * NextLocalCommitHeight == remoteCommitChain.Height
    29  	//
    30  	// This covers the case of a lost commitment which was sent by the
    31  	// sender of this message, but never received by the receiver of this
    32  	// message.
    33  	NextLocalCommitHeight uint64
    34  
    35  	// RemoteCommitTailHeight is the height of the receiving party's
    36  	// unrevoked commitment from the PoV of the sender of this message. If
    37  	// the height of the receiver's commitment is *one more* than this
    38  	// value, then their prior RevokeAndAck message should be
    39  	// retransmitted.
    40  	//
    41  	// In other words, the receiver should re-send their last sent
    42  	// RevokeAndAck message iff:
    43  	//
    44  	//  * localCommitChain.tail().Height == RemoteCommitTailHeight + 1
    45  	//
    46  	// This covers the case of a lost revocation, wherein the receiver of
    47  	// the message sent a revocation for a prior state, but the sender of
    48  	// the message never fully processed it.
    49  	RemoteCommitTailHeight uint64
    50  
    51  	// LastRemoteCommitSecret is the last commitment secret that the
    52  	// receiving node has sent to the sending party. This will be the
    53  	// secret of the last revoked commitment transaction. Including this
    54  	// provides proof that the sending node at least knows of this state,
    55  	// as they couldn't have produced it if it wasn't sent, as the value
    56  	// can be authenticated by querying the shachain or the receiving
    57  	// party.
    58  	LastRemoteCommitSecret [32]byte
    59  
    60  	// LocalUnrevokedCommitPoint is the commitment point used in the
    61  	// current un-revoked commitment transaction of the sending party.
    62  	LocalUnrevokedCommitPoint *secp256k1.PublicKey
    63  }
    64  
    65  // A compile time check to ensure ChannelReestablish implements the
    66  // lnwire.Message interface.
    67  var _ Message = (*ChannelReestablish)(nil)
    68  
    69  // Encode serializes the target ChannelReestablish into the passed io.Writer
    70  // observing the protocol version specified.
    71  //
    72  // This is part of the lnwire.Message interface.
    73  func (a *ChannelReestablish) Encode(w io.Writer, pver uint32) error {
    74  	err := WriteElements(w,
    75  		a.ChanID,
    76  		a.NextLocalCommitHeight,
    77  		a.RemoteCommitTailHeight,
    78  	)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	// If the commit point wasn't sent, then we won't write out any of the
    84  	// remaining fields as they're optional.
    85  	if a.LocalUnrevokedCommitPoint == nil {
    86  		return nil
    87  	}
    88  
    89  	// Otherwise, we'll write out the remaining elements.
    90  	return WriteElements(w, a.LastRemoteCommitSecret[:],
    91  		a.LocalUnrevokedCommitPoint)
    92  }
    93  
    94  // Decode deserializes a serialized ChannelReestablish stored in the passed
    95  // io.Reader observing the specified protocol version.
    96  //
    97  // This is part of the lnwire.Message interface.
    98  func (a *ChannelReestablish) Decode(r io.Reader, pver uint32) error {
    99  	err := ReadElements(r,
   100  		&a.ChanID,
   101  		&a.NextLocalCommitHeight,
   102  		&a.RemoteCommitTailHeight,
   103  	)
   104  	if err != nil {
   105  		return err
   106  	}
   107  
   108  	// This message has currently defined optional fields. As a result,
   109  	// we'll only proceed if there's still bytes remaining within the
   110  	// reader.
   111  	//
   112  	// We'll manually parse out the optional fields in order to be able to
   113  	// still utilize the io.Reader interface.
   114  
   115  	// We'll first attempt to read the optional commit secret, if we're at
   116  	// the EOF, then this means the field wasn't included so we can exit
   117  	// early.
   118  	var buf [32]byte
   119  	_, err = io.ReadFull(r, buf[:32])
   120  	if err == io.EOF {
   121  		return nil
   122  	} else if err != nil {
   123  		return err
   124  	}
   125  
   126  	// If the field is present, then we'll copy it over and proceed.
   127  	copy(a.LastRemoteCommitSecret[:], buf[:])
   128  
   129  	// We'll conclude by parsing out the commitment point. We don't check
   130  	// the error in this case, as it has included the commit secret, then
   131  	// they MUST also include the commit point.
   132  	return ReadElement(r, &a.LocalUnrevokedCommitPoint)
   133  }
   134  
   135  // MsgType returns the integer uniquely identifying this message type on the
   136  // wire.
   137  //
   138  // This is part of the lnwire.Message interface.
   139  func (a *ChannelReestablish) MsgType() MessageType {
   140  	return MsgChannelReestablish
   141  }
   142  
   143  // MaxPayloadLength returns the maximum allowed payload size for this message
   144  // observing the specified protocol version.
   145  //
   146  // This is part of the lnwire.Message interface.
   147  func (a *ChannelReestablish) MaxPayloadLength(pver uint32) uint32 {
   148  	var length uint32
   149  
   150  	// ChanID - 32 bytes
   151  	length += 32
   152  
   153  	// NextLocalCommitHeight - 8 bytes
   154  	length += 8
   155  
   156  	// RemoteCommitTailHeight - 8 bytes
   157  	length += 8
   158  
   159  	// LastRemoteCommitSecret - 32 bytes
   160  	length += 32
   161  
   162  	// LocalUnrevokedCommitPoint - 33 bytes
   163  	length += 33
   164  
   165  	return length
   166  }