123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- 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
- }
|