lnwire: add new ChannelType field as TLV record to Open/AcceptChannel

In this commit, we add a new ChannelType field as a new TLV record to
the OpenChannel message. During this change, we make a few tweaks to the
generic TLV encode/decode methods for the ExtraOpaqueData struct to have
it work on the level of tlv.RecordProducer instead of tlv.Record, as
this reduces line noise a bit.

We also partially undo existing logic that would attempt to "prepend"
any new TLV records to the end of the ExtraOpaqueData if one was already
present within the struct. This is based on the assumption that if we've
read a message from disk to order to re-send/transmit it, then the
ExtraOpaqueData is fully populated so we'll write that as is. Otherwise,
a message is being encoded for the first time, and we expect all fields
that are known TLV fields to be specified within the struct itself.

This change required the unit tests to be modified slightly, as we'll
always encode a fresh set of TLV records if none was already specified
within the struct.
This commit is contained in:
Olaoluwa Osuntokun committed 2021-08-30 19:17:21 -07:00
1 parent 988d01de0d
commit 57b7a668c0
8 files changed
+116 -108

No files matched your search

+23 -9
View File
@@ -7,6 +7,7 @@ import (
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/tlv"
)
// FundingFlag represents the possible bit mask values for the ChannelFlags
@@ -130,6 +131,10 @@ type OpenChannel struct {
// and its length followed by the script will be written if it is set.
UpfrontShutdownScript DeliveryAddress
// ChannelType is the explicit channel type the initiator wishes to
// open.
ChannelType *ChannelType
// 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.
@@ -150,13 +155,12 @@ var _ Message = (*OpenChannel)(nil)
// implementation. Serialization will observe the rules defined by the passed
// protocol version.
//
// This is part of the lnwire.Message interface.
func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error {
// Since the upfront script is encoded as a TLV record, concatenate it
// with the ExtraData, and write them as one.
tlvRecords, err := packShutdownScript(
o.UpfrontShutdownScript, o.ExtraData,
)
recordProducers := []tlv.RecordProducer{&o.UpfrontShutdownScript}
if o.ChannelType != nil {
recordProducers = append(recordProducers, o.ChannelType)
}
err := EncodeMessageExtraData(&o.ExtraData, recordProducers...)
if err != nil {
return err
}
@@ -234,7 +238,7 @@ func (o *OpenChannel) Encode(w *bytes.Buffer, pver uint32) error {
return err
}
return WriteBytes(w, tlvRecords)
return WriteBytes(w, o.ExtraData)
}
// Decode deserializes the serialized OpenChannel stored in the passed
@@ -276,13 +280,23 @@ func (o *OpenChannel) Decode(r io.Reader, pver uint32) error {
return err
}
o.UpfrontShutdownScript, o.ExtraData, err = parseShutdownScript(
tlvRecords,
// Next we'll parse out the set of known records, keeping the raw tlv
// bytes untouched to ensure we don't drop any bytes erroneously.
var chanType ChannelType
typeMap, err := tlvRecords.ExtractRecords(
&o.UpfrontShutdownScript, &chanType,
)
if err != nil {
return err
}
// Set the corresponding TLV types if they were included in the stream.
if val, ok := typeMap[ChannelTypeRecordType]; ok && val == nil {
o.ChannelType = &chanType
}
o.ExtraData = tlvRecords
return nil
}