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  }