github.com/decred/dcrlnd@v0.7.6/lnwire/channel_update.go (about) 1 package lnwire 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 8 "github.com/decred/dcrd/chaincfg/chainhash" 9 ) 10 11 // ChanUpdateMsgFlags is a bitfield that signals whether optional fields are 12 // present in the ChannelUpdate. 13 type ChanUpdateMsgFlags uint8 14 15 const ( 16 // ChanUpdateOptionMaxHtlc is a bit that indicates whether the 17 // optional htlc_maximum_msat field is present in this ChannelUpdate. 18 ChanUpdateOptionMaxHtlc ChanUpdateMsgFlags = 1 << iota 19 ) 20 21 // String returns the bitfield flags as a string. 22 func (c ChanUpdateMsgFlags) String() string { 23 return fmt.Sprintf("%08b", c) 24 } 25 26 // HasMaxHtlc returns true if the htlc_maximum_msat option bit is set in the 27 // message flags. 28 func (c ChanUpdateMsgFlags) HasMaxHtlc() bool { 29 return c&ChanUpdateOptionMaxHtlc != 0 30 } 31 32 // ChanUpdateChanFlags is a bitfield that signals various options concerning a 33 // particular channel edge. Each bit is to be examined in order to determine 34 // how the ChannelUpdate message is to be interpreted. 35 type ChanUpdateChanFlags uint8 36 37 const ( 38 // ChanUpdateDirection indicates the direction of a channel update. If 39 // this bit is set to 0 if Node1 (the node with the "smaller" Node ID) 40 // is updating the channel, and to 1 otherwise. 41 ChanUpdateDirection ChanUpdateChanFlags = 1 << iota 42 43 // ChanUpdateDisabled is a bit that indicates if the channel edge 44 // selected by the ChanUpdateDirection bit is to be treated as being 45 // disabled. 46 ChanUpdateDisabled 47 ) 48 49 // IsDisabled determines whether the channel flags has the disabled bit set. 50 func (c ChanUpdateChanFlags) IsDisabled() bool { 51 return c&ChanUpdateDisabled == ChanUpdateDisabled 52 } 53 54 // String returns the bitfield flags as a string. 55 func (c ChanUpdateChanFlags) String() string { 56 return fmt.Sprintf("%08b", c) 57 } 58 59 // ChannelUpdate message is used after channel has been initially announced. 60 // Each side independently announces its fees and minimum expiry for HTLCs and 61 // other parameters. Also this message is used to redeclare initially set 62 // channel parameters. 63 type ChannelUpdate struct { 64 // Signature is used to validate the announced data and prove the 65 // ownership of node id. 66 Signature Sig 67 68 // ChainHash denotes the target chain that this channel was opened 69 // within. This value should be the genesis hash of the target chain. 70 // Along with the short channel ID, this uniquely identifies the 71 // channel globally in a blockchain. 72 ChainHash chainhash.Hash 73 74 // ShortChannelID is the unique description of the funding transaction. 75 ShortChannelID ShortChannelID 76 77 // Timestamp allows ordering in the case of multiple announcements. We 78 // should ignore the message if timestamp is not greater than 79 // the last-received. 80 Timestamp uint32 81 82 // MessageFlags is a bitfield that describes whether optional fields 83 // are present in this update. Currently, the least-significant bit 84 // must be set to 1 if the optional field MaxHtlc is present. 85 MessageFlags ChanUpdateMsgFlags 86 87 // ChannelFlags is a bitfield that describes additional meta-data 88 // concerning how the update is to be interpreted. Currently, the 89 // least-significant bit must be set to 0 if the creating node 90 // corresponds to the first node in the previously sent channel 91 // announcement and 1 otherwise. If the second bit is set, then the 92 // channel is set to be disabled. 93 ChannelFlags ChanUpdateChanFlags 94 95 // TimeLockDelta is the minimum number of blocks this node requires to 96 // be added to the expiry of HTLCs. This is a security parameter 97 // determined by the node operator. This value represents the required 98 // gap between the time locks of the incoming and outgoing HTLC's set 99 // to this node. 100 TimeLockDelta uint16 101 102 // HtlcMinimumMAtoms is the minimum HTLC value which will be accepted. 103 HtlcMinimumMAtoms MilliAtom 104 105 // BaseFee is the base fee that must be used for incoming HTLC's to 106 // this particular channel. This value will be tacked onto the required 107 // for a payment independent of the size of the payment. 108 BaseFee uint32 109 110 // FeeRate is the fee rate that will be charged per millionth of an 111 // atom. 112 FeeRate uint32 113 114 // HtlcMaximumMAtoms is the maximum HTLC value which will be accepted. 115 HtlcMaximumMAtoms MilliAtom 116 117 // ExtraData is the set of data that was appended to this message to 118 // fill out the full maximum transport message size. These fields can 119 // be used to specify optional data such as custom TLV fields. 120 ExtraOpaqueData ExtraOpaqueData 121 } 122 123 // A compile time check to ensure ChannelUpdate implements the lnwire.Message 124 // interface. 125 var _ Message = (*ChannelUpdate)(nil) 126 127 // Decode deserializes a serialized ChannelUpdate stored in the passed 128 // io.Reader observing the specified protocol version. 129 // 130 // This is part of the lnwire.Message interface. 131 func (a *ChannelUpdate) Decode(r io.Reader, pver uint32) error { 132 err := ReadElements(r, 133 &a.Signature, 134 a.ChainHash[:], 135 &a.ShortChannelID, 136 &a.Timestamp, 137 &a.MessageFlags, 138 &a.ChannelFlags, 139 &a.TimeLockDelta, 140 &a.HtlcMinimumMAtoms, 141 &a.BaseFee, 142 &a.FeeRate, 143 ) 144 if err != nil { 145 return err 146 } 147 148 // Now check whether the max HTLC field is present and read it if so. 149 if a.MessageFlags.HasMaxHtlc() { 150 if err := ReadElements(r, &a.HtlcMaximumMAtoms); err != nil { 151 return err 152 } 153 } 154 155 return a.ExtraOpaqueData.Decode(r) 156 } 157 158 // Encode serializes the target ChannelUpdate into the passed io.Writer 159 // observing the protocol version specified. 160 // 161 // This is part of the lnwire.Message interface. 162 func (a *ChannelUpdate) Encode(w *bytes.Buffer, pver uint32) error { 163 if err := WriteSig(w, a.Signature); err != nil { 164 return err 165 } 166 167 if err := WriteBytes(w, a.ChainHash[:]); err != nil { 168 return err 169 } 170 171 if err := WriteShortChannelID(w, a.ShortChannelID); err != nil { 172 return err 173 } 174 175 if err := WriteUint32(w, a.Timestamp); err != nil { 176 return err 177 } 178 179 if err := WriteChanUpdateMsgFlags(w, a.MessageFlags); err != nil { 180 return err 181 } 182 183 if err := WriteChanUpdateChanFlags(w, a.ChannelFlags); err != nil { 184 return err 185 } 186 187 if err := WriteUint16(w, a.TimeLockDelta); err != nil { 188 return err 189 } 190 191 if err := WriteMilliAtom(w, a.HtlcMinimumMAtoms); err != nil { 192 return err 193 } 194 195 if err := WriteUint32(w, a.BaseFee); err != nil { 196 return err 197 } 198 199 if err := WriteUint32(w, a.FeeRate); err != nil { 200 return err 201 } 202 203 // Now append optional fields if they are set. Currently, the only 204 // optional field is max HTLC. 205 if a.MessageFlags.HasMaxHtlc() { 206 err := WriteMilliAtom(w, a.HtlcMaximumMAtoms) 207 if err != nil { 208 return err 209 } 210 } 211 212 // Finally, append any extra opaque data. 213 return WriteBytes(w, a.ExtraOpaqueData) 214 } 215 216 // MsgType returns the integer uniquely identifying this message type on the 217 // wire. 218 // 219 // This is part of the lnwire.Message interface. 220 func (a *ChannelUpdate) MsgType() MessageType { 221 return MsgChannelUpdate 222 } 223 224 // DataToSign is used to retrieve part of the announcement message which should 225 // be signed. 226 func (a *ChannelUpdate) DataToSign() ([]byte, error) { 227 // We should not include the signatures itself. 228 b := make([]byte, 0, MaxMsgBody) 229 buf := bytes.NewBuffer(b) 230 if err := WriteBytes(buf, a.ChainHash[:]); err != nil { 231 return nil, err 232 } 233 234 if err := WriteShortChannelID(buf, a.ShortChannelID); err != nil { 235 return nil, err 236 } 237 238 if err := WriteUint32(buf, a.Timestamp); err != nil { 239 return nil, err 240 } 241 242 if err := WriteChanUpdateMsgFlags(buf, a.MessageFlags); err != nil { 243 return nil, err 244 } 245 246 if err := WriteChanUpdateChanFlags(buf, a.ChannelFlags); err != nil { 247 return nil, err 248 } 249 250 if err := WriteUint16(buf, a.TimeLockDelta); err != nil { 251 return nil, err 252 } 253 254 if err := WriteMilliAtom(buf, a.HtlcMinimumMAtoms); err != nil { 255 return nil, err 256 } 257 258 if err := WriteUint32(buf, a.BaseFee); err != nil { 259 return nil, err 260 } 261 262 if err := WriteUint32(buf, a.FeeRate); err != nil { 263 return nil, err 264 } 265 266 // Now append optional fields if they are set. Currently, the only 267 // optional field is max HTLC. 268 if a.MessageFlags.HasMaxHtlc() { 269 err := WriteMilliAtom(buf, a.HtlcMaximumMAtoms) 270 if err != nil { 271 return nil, err 272 } 273 } 274 275 // Finally, append any extra opaque data. 276 if err := WriteBytes(buf, a.ExtraOpaqueData); err != nil { 277 return nil, err 278 } 279 280 return buf.Bytes(), nil 281 }