diff --git a/lnwire/channel_update.go b/lnwire/channel_update.go index 02dfa5dbdc..1788cdc7f5 100644 --- a/lnwire/channel_update.go +++ b/lnwire/channel_update.go @@ -13,6 +13,12 @@ import ( // present in the ChannelUpdate. type ChanUpdateMsgFlags uint8 +const ( + // ChanUpdateOptionMaxHtlc is a bit that indicates whether the + // optional htlc_maximum_msat field is present in this ChannelUpdate. + ChanUpdateOptionMaxHtlc ChanUpdateMsgFlags = 1 << iota +) + // String returns the bitfield flags as a string. func (c ChanUpdateMsgFlags) String() string { return fmt.Sprintf("%08b", c) @@ -95,6 +101,9 @@ type ChannelUpdate struct { // satoshi. FeeRate uint32 + // HtlcMaximumMsat is the maximum HTLC value which will be accepted. + HtlcMaximumMsat MilliSatoshi + // ExtraOpaqueData is the set of data that was appended to this // message, some of which we may not actually know how to iterate or // parse. By holding onto this data, we ensure that we're able to @@ -129,6 +138,13 @@ func (a *ChannelUpdate) Decode(r io.Reader, pver uint32) error { return err } + // Now check whether the max HTLC field is present and read it if so. + if a.MessageFlags&ChanUpdateOptionMaxHtlc != 0 { + if err := ReadElements(r, &a.HtlcMaximumMsat); err != nil { + return err + } + } + // Now that we've read out all the fields that we explicitly know of, // we'll collect the remainder into the ExtraOpaqueData field. If there // aren't any bytes, then we'll snip off the slice to avoid carrying @@ -149,7 +165,7 @@ func (a *ChannelUpdate) Decode(r io.Reader, pver uint32) error { // // This is part of the lnwire.Message interface. func (a *ChannelUpdate) Encode(w io.Writer, pver uint32) error { - return WriteElements(w, + err := WriteElements(w, a.Signature, a.ChainHash[:], a.ShortChannelID, @@ -160,8 +176,21 @@ func (a *ChannelUpdate) Encode(w io.Writer, pver uint32) error { a.HtlcMinimumMsat, a.BaseFee, a.FeeRate, - a.ExtraOpaqueData, ) + if err != nil { + return err + } + + // Now append optional fields if they are set. Currently, the only + // optional field is max HTLC. + if a.MessageFlags&ChanUpdateOptionMaxHtlc != 0 { + if err := WriteElements(w, a.HtlcMaximumMsat); err != nil { + return err + } + } + + // Finally, append any extra opaque data. + return WriteElements(w, a.ExtraOpaqueData) } // MsgType returns the integer uniquely identifying this message type on the @@ -196,11 +225,23 @@ func (a *ChannelUpdate) DataToSign() ([]byte, error) { a.HtlcMinimumMsat, a.BaseFee, a.FeeRate, - a.ExtraOpaqueData, ) if err != nil { return nil, err } + // Now append optional fields if they are set. Currently, the only + // optional field is max HTLC. + if a.MessageFlags&ChanUpdateOptionMaxHtlc != 0 { + if err := WriteElements(&w, a.HtlcMaximumMsat); err != nil { + return nil, err + } + } + + // Finally, append any extra opaque data. + if err := WriteElements(&w, a.ExtraOpaqueData); err != nil { + return nil, err + } + return w.Bytes(), nil } diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 91de511b27..c4f9c26b75 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -656,6 +656,7 @@ func TestLightningWireProtocol(t *testing.T) { ChannelFlags: ChanUpdateChanFlags(r.Int31()), TimeLockDelta: uint16(r.Int31()), HtlcMinimumMsat: MilliSatoshi(r.Int63()), + HtlcMaximumMsat: MilliSatoshi(r.Int63()), BaseFee: uint32(r.Int31()), FeeRate: uint32(r.Int31()), }