/ lnwire / channel_ready.go
channel_ready.go
  1  package lnwire
  2  
  3  import (
  4  	"bytes"
  5  	"io"
  6  
  7  	"github.com/btcsuite/btcd/btcec/v2"
  8  	"github.com/lightningnetwork/lnd/tlv"
  9  )
 10  
 11  // ChannelReady is the message that both parties to a new channel creation
 12  // send once they have observed the funding transaction being confirmed on the
 13  // blockchain. ChannelReady contains the signatures necessary for the channel
 14  // participants to advertise the existence of the channel to the rest of the
 15  // network.
 16  type ChannelReady struct {
 17  	// ChanID is the outpoint of the channel's funding transaction. This
 18  	// can be used to query for the channel in the database.
 19  	ChanID ChannelID
 20  
 21  	// NextPerCommitmentPoint is the secret that can be used to revoke the
 22  	// next commitment transaction for the channel.
 23  	NextPerCommitmentPoint *btcec.PublicKey
 24  
 25  	// AliasScid is an alias ShortChannelID used to refer to the underlying
 26  	// channel. It can be used instead of the confirmed on-chain
 27  	// ShortChannelID for forwarding.
 28  	AliasScid *ShortChannelID
 29  
 30  	// NextLocalNonce is an optional field that stores a local musig2 nonce.
 31  	// This will only be populated if the simple taproot channels type was
 32  	// negotiated. This is the local nonce that will be used by the sender
 33  	// to accept a new commitment state transition.
 34  	NextLocalNonce OptMusig2NonceTLV
 35  
 36  	// AnnouncementNodeNonce is an optional field that stores a public
 37  	// nonce that will be used along with the node's ID key during signing
 38  	// of the ChannelAnnouncement2 message.
 39  	AnnouncementNodeNonce tlv.OptionalRecordT[tlv.TlvType0, Musig2Nonce]
 40  
 41  	// AnnouncementBitcoinNonce is an optional field that stores a public
 42  	// nonce that will be used along with the node's bitcoin key during
 43  	// signing of the ChannelAnnouncement2 message.
 44  	AnnouncementBitcoinNonce tlv.OptionalRecordT[tlv.TlvType2, Musig2Nonce]
 45  
 46  	// ExtraData is the set of data that was appended to this message to
 47  	// fill out the full maximum transport message size. These fields can
 48  	// be used to specify optional data such as custom TLV fields.
 49  	ExtraData ExtraOpaqueData
 50  }
 51  
 52  // NewChannelReady creates a new ChannelReady message, populating it with the
 53  // necessary IDs and revocation secret.
 54  func NewChannelReady(cid ChannelID, npcp *btcec.PublicKey) *ChannelReady {
 55  	return &ChannelReady{
 56  		ChanID:                 cid,
 57  		NextPerCommitmentPoint: npcp,
 58  		ExtraData:              nil,
 59  	}
 60  }
 61  
 62  // A compile time check to ensure ChannelReady implements the lnwire.Message
 63  // interface.
 64  var _ Message = (*ChannelReady)(nil)
 65  
 66  // A compile time check to ensure ChannelReady implements the
 67  // lnwire.SizeableMessage interface.
 68  var _ SizeableMessage = (*ChannelReady)(nil)
 69  
 70  // Decode deserializes the serialized ChannelReady message stored in the
 71  // passed io.Reader into the target ChannelReady using the deserialization
 72  // rules defined by the passed protocol version.
 73  //
 74  // This is part of the lnwire.Message interface.
 75  func (c *ChannelReady) Decode(r io.Reader, _ uint32) error {
 76  	// Read all the mandatory fields in the message.
 77  	err := ReadElements(r,
 78  		&c.ChanID,
 79  		&c.NextPerCommitmentPoint,
 80  	)
 81  	if err != nil {
 82  		return err
 83  	}
 84  
 85  	var tlvRecords ExtraOpaqueData
 86  	if err := ReadElements(r, &tlvRecords); err != nil {
 87  		return err
 88  	}
 89  
 90  	// Next we'll parse out the set of known records. For now, this is just
 91  	// the AliasScidRecordType.
 92  	var (
 93  		aliasScid  ShortChannelID
 94  		localNonce = c.NextLocalNonce.Zero()
 95  		nodeNonce  = tlv.ZeroRecordT[tlv.TlvType0, Musig2Nonce]()
 96  		btcNonce   = tlv.ZeroRecordT[tlv.TlvType2, Musig2Nonce]()
 97  	)
 98  	typeMap, err := tlvRecords.ExtractRecords(
 99  		&btcNonce, &aliasScid, &nodeNonce, &localNonce,
100  	)
101  	if err != nil {
102  		return err
103  	}
104  
105  	// We'll only set AliasScid if the corresponding TLV type was included
106  	// in the stream.
107  	if val, ok := typeMap[AliasScidRecordType]; ok && val == nil {
108  		c.AliasScid = &aliasScid
109  	}
110  	if val, ok := typeMap[c.NextLocalNonce.TlvType()]; ok && val == nil {
111  		c.NextLocalNonce = tlv.SomeRecordT(localNonce)
112  	}
113  	val, ok := typeMap[c.AnnouncementBitcoinNonce.TlvType()]
114  	if ok && val == nil {
115  		c.AnnouncementBitcoinNonce = tlv.SomeRecordT(btcNonce)
116  	}
117  	val, ok = typeMap[c.AnnouncementNodeNonce.TlvType()]
118  	if ok && val == nil {
119  		c.AnnouncementNodeNonce = tlv.SomeRecordT(nodeNonce)
120  	}
121  
122  	if len(tlvRecords) != 0 {
123  		c.ExtraData = tlvRecords
124  	}
125  
126  	return nil
127  }
128  
129  // Encode serializes the target ChannelReady message into the passed io.Writer
130  // implementation. Serialization will observe the rules defined by the passed
131  // protocol version.
132  //
133  // This is part of the lnwire.Message interface.
134  func (c *ChannelReady) Encode(w *bytes.Buffer, _ uint32) error {
135  	if err := WriteChannelID(w, c.ChanID); err != nil {
136  		return err
137  	}
138  
139  	if err := WritePublicKey(w, c.NextPerCommitmentPoint); err != nil {
140  		return err
141  	}
142  
143  	// We'll only encode the AliasScid in a TLV segment if it exists.
144  	recordProducers := make([]tlv.RecordProducer, 0, 4)
145  	if c.AliasScid != nil {
146  		recordProducers = append(recordProducers, c.AliasScid)
147  	}
148  	c.NextLocalNonce.WhenSome(func(localNonce Musig2NonceTLV) {
149  		recordProducers = append(recordProducers, &localNonce)
150  	})
151  	c.AnnouncementBitcoinNonce.WhenSome(
152  		func(nonce tlv.RecordT[tlv.TlvType2, Musig2Nonce]) {
153  			recordProducers = append(recordProducers, &nonce)
154  		},
155  	)
156  	c.AnnouncementNodeNonce.WhenSome(
157  		func(nonce tlv.RecordT[tlv.TlvType0, Musig2Nonce]) {
158  			recordProducers = append(recordProducers, &nonce)
159  		},
160  	)
161  
162  	err := EncodeMessageExtraData(&c.ExtraData, recordProducers...)
163  	if err != nil {
164  		return err
165  	}
166  
167  	return WriteBytes(w, c.ExtraData)
168  }
169  
170  // MsgType returns the uint32 code which uniquely identifies this message as a
171  // ChannelReady message on the wire.
172  //
173  // This is part of the lnwire.Message interface.
174  func (c *ChannelReady) MsgType() MessageType {
175  	return MsgChannelReady
176  }
177  
178  // SerializedSize returns the serialized size of the message in bytes.
179  //
180  // This is part of the lnwire.SizeableMessage interface.
181  func (c *ChannelReady) SerializedSize() (uint32, error) {
182  	return MessageSerializedSize(c)
183  }