github.com/decred/dcrlnd@v0.7.6/channeldb/migration/lnwire21/channel_update.go (about)

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