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 }