mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
dd5273c88c
We rename `ChanUpdateOptionMaxHtlc` to `ChanUpdateRequiredMaxHtlc` as with the latest changes it is now required. Similarly, rename `validateOptionalFields` to `ValidateChannelUpdateFields`, export it to use it in a later commit.
282 lines
8.0 KiB
Go
282 lines
8.0 KiB
Go
package lnwire
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
)
|
|
|
|
// ChanUpdateMsgFlags is a bitfield that signals whether optional fields are
|
|
// present in the ChannelUpdate.
|
|
type ChanUpdateMsgFlags uint8
|
|
|
|
const (
|
|
// ChanUpdateRequiredMaxHtlc is a bit that indicates whether the
|
|
// required htlc_maximum_msat field is present in this ChannelUpdate.
|
|
ChanUpdateRequiredMaxHtlc ChanUpdateMsgFlags = 1 << iota
|
|
)
|
|
|
|
// String returns the bitfield flags as a string.
|
|
func (c ChanUpdateMsgFlags) String() string {
|
|
return fmt.Sprintf("%08b", c)
|
|
}
|
|
|
|
// HasMaxHtlc returns true if the htlc_maximum_msat option bit is set in the
|
|
// message flags.
|
|
func (c ChanUpdateMsgFlags) HasMaxHtlc() bool {
|
|
return c&ChanUpdateRequiredMaxHtlc != 0
|
|
}
|
|
|
|
// ChanUpdateChanFlags is a bitfield that signals various options concerning a
|
|
// particular channel edge. Each bit is to be examined in order to determine
|
|
// how the ChannelUpdate message is to be interpreted.
|
|
type ChanUpdateChanFlags uint8
|
|
|
|
const (
|
|
// ChanUpdateDirection indicates the direction of a channel update. If
|
|
// this bit is set to 0 if Node1 (the node with the "smaller" Node ID)
|
|
// is updating the channel, and to 1 otherwise.
|
|
ChanUpdateDirection ChanUpdateChanFlags = 1 << iota
|
|
|
|
// ChanUpdateDisabled is a bit that indicates if the channel edge
|
|
// selected by the ChanUpdateDirection bit is to be treated as being
|
|
// disabled.
|
|
ChanUpdateDisabled
|
|
)
|
|
|
|
// IsDisabled determines whether the channel flags has the disabled bit set.
|
|
func (c ChanUpdateChanFlags) IsDisabled() bool {
|
|
return c&ChanUpdateDisabled == ChanUpdateDisabled
|
|
}
|
|
|
|
// String returns the bitfield flags as a string.
|
|
func (c ChanUpdateChanFlags) String() string {
|
|
return fmt.Sprintf("%08b", c)
|
|
}
|
|
|
|
// ChannelUpdate message is used after channel has been initially announced.
|
|
// Each side independently announces its fees and minimum expiry for HTLCs and
|
|
// other parameters. Also this message is used to redeclare initially set
|
|
// channel parameters.
|
|
type ChannelUpdate struct {
|
|
// Signature is used to validate the announced data and prove the
|
|
// ownership of node id.
|
|
Signature Sig
|
|
|
|
// ChainHash denotes the target chain that this channel was opened
|
|
// within. This value should be the genesis hash of the target chain.
|
|
// Along with the short channel ID, this uniquely identifies the
|
|
// channel globally in a blockchain.
|
|
ChainHash chainhash.Hash
|
|
|
|
// ShortChannelID is the unique description of the funding transaction.
|
|
ShortChannelID ShortChannelID
|
|
|
|
// Timestamp allows ordering in the case of multiple announcements. We
|
|
// should ignore the message if timestamp is not greater than
|
|
// the last-received.
|
|
Timestamp uint32
|
|
|
|
// MessageFlags is a bitfield that describes whether optional fields
|
|
// are present in this update. Currently, the least-significant bit
|
|
// must be set to 1 if the optional field MaxHtlc is present.
|
|
MessageFlags ChanUpdateMsgFlags
|
|
|
|
// ChannelFlags is a bitfield that describes additional meta-data
|
|
// concerning how the update is to be interpreted. Currently, the
|
|
// least-significant bit must be set to 0 if the creating node
|
|
// corresponds to the first node in the previously sent channel
|
|
// announcement and 1 otherwise. If the second bit is set, then the
|
|
// channel is set to be disabled.
|
|
ChannelFlags ChanUpdateChanFlags
|
|
|
|
// TimeLockDelta is the minimum number of blocks this node requires to
|
|
// be added to the expiry of HTLCs. This is a security parameter
|
|
// determined by the node operator. This value represents the required
|
|
// gap between the time locks of the incoming and outgoing HTLC's set
|
|
// to this node.
|
|
TimeLockDelta uint16
|
|
|
|
// HtlcMinimumMsat is the minimum HTLC value which will be accepted.
|
|
HtlcMinimumMsat MilliSatoshi
|
|
|
|
// BaseFee is the base fee that must be used for incoming HTLC's to
|
|
// this particular channel. This value will be tacked onto the required
|
|
// for a payment independent of the size of the payment.
|
|
BaseFee uint32
|
|
|
|
// FeeRate is the fee rate that will be charged per millionth of a
|
|
// satoshi.
|
|
FeeRate uint32
|
|
|
|
// HtlcMaximumMsat is the maximum HTLC value which will be accepted.
|
|
HtlcMaximumMsat MilliSatoshi
|
|
|
|
// ExtraData is the set of data that was appended to this message to
|
|
// fill out the full maximum transport message size. These fields can
|
|
// be used to specify optional data such as custom TLV fields.
|
|
ExtraOpaqueData ExtraOpaqueData
|
|
}
|
|
|
|
// A compile time check to ensure ChannelUpdate implements the lnwire.Message
|
|
// interface.
|
|
var _ Message = (*ChannelUpdate)(nil)
|
|
|
|
// Decode deserializes a serialized ChannelUpdate stored in the passed
|
|
// io.Reader observing the specified protocol version.
|
|
//
|
|
// This is part of the lnwire.Message interface.
|
|
func (a *ChannelUpdate) Decode(r io.Reader, pver uint32) error {
|
|
err := ReadElements(r,
|
|
&a.Signature,
|
|
a.ChainHash[:],
|
|
&a.ShortChannelID,
|
|
&a.Timestamp,
|
|
&a.MessageFlags,
|
|
&a.ChannelFlags,
|
|
&a.TimeLockDelta,
|
|
&a.HtlcMinimumMsat,
|
|
&a.BaseFee,
|
|
&a.FeeRate,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Now check whether the max HTLC field is present and read it if so.
|
|
if a.MessageFlags.HasMaxHtlc() {
|
|
if err := ReadElements(r, &a.HtlcMaximumMsat); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return a.ExtraOpaqueData.Decode(r)
|
|
}
|
|
|
|
// Encode serializes the target ChannelUpdate into the passed io.Writer
|
|
// observing the protocol version specified.
|
|
//
|
|
// This is part of the lnwire.Message interface.
|
|
func (a *ChannelUpdate) Encode(w *bytes.Buffer, pver uint32) error {
|
|
if err := WriteSig(w, a.Signature); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteBytes(w, a.ChainHash[:]); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteShortChannelID(w, a.ShortChannelID); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteUint32(w, a.Timestamp); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteChanUpdateMsgFlags(w, a.MessageFlags); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteChanUpdateChanFlags(w, a.ChannelFlags); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteUint16(w, a.TimeLockDelta); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteMilliSatoshi(w, a.HtlcMinimumMsat); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteUint32(w, a.BaseFee); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := WriteUint32(w, a.FeeRate); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Now append optional fields if they are set. Currently, the only
|
|
// optional field is max HTLC.
|
|
if a.MessageFlags.HasMaxHtlc() {
|
|
err := WriteMilliSatoshi(w, a.HtlcMaximumMsat)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Finally, append any extra opaque data.
|
|
return WriteBytes(w, a.ExtraOpaqueData)
|
|
}
|
|
|
|
// MsgType returns the integer uniquely identifying this message type on the
|
|
// wire.
|
|
//
|
|
// This is part of the lnwire.Message interface.
|
|
func (a *ChannelUpdate) MsgType() MessageType {
|
|
return MsgChannelUpdate
|
|
}
|
|
|
|
// DataToSign is used to retrieve part of the announcement message which should
|
|
// be signed.
|
|
func (a *ChannelUpdate) DataToSign() ([]byte, error) {
|
|
// We should not include the signatures itself.
|
|
b := make([]byte, 0, MaxMsgBody)
|
|
buf := bytes.NewBuffer(b)
|
|
if err := WriteBytes(buf, a.ChainHash[:]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteShortChannelID(buf, a.ShortChannelID); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteUint32(buf, a.Timestamp); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteChanUpdateMsgFlags(buf, a.MessageFlags); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteChanUpdateChanFlags(buf, a.ChannelFlags); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteUint16(buf, a.TimeLockDelta); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteMilliSatoshi(buf, a.HtlcMinimumMsat); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteUint32(buf, a.BaseFee); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := WriteUint32(buf, a.FeeRate); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Now append optional fields if they are set. Currently, the only
|
|
// optional field is max HTLC.
|
|
if a.MessageFlags.HasMaxHtlc() {
|
|
err := WriteMilliSatoshi(buf, a.HtlcMaximumMsat)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// Finally, append any extra opaque data.
|
|
if err := WriteBytes(buf, a.ExtraOpaqueData); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return buf.Bytes(), nil
|
|
}
|