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