lnd.xprv/lnwire/extra_bytes.go

85 lines
2.3 KiB
Go
Raw Normal View History

package lnwire
import (
"bytes"
"io"
"io/ioutil"
"github.com/lightningnetwork/lnd/tlv"
)
// ExtraOpaqueData is the set of data that was appended to this message, some
// of which we may not actually know how to iterate or parse. By holding onto
// this data, we ensure that we're able to properly validate the set of
// signatures that cover these new fields, and ensure we're able to make
// upgrades to the network in a forwards compatible manner.
type ExtraOpaqueData []byte
// Encode attempts to encode the raw extra bytes into the passed io.Writer.
func (e *ExtraOpaqueData) Encode(w io.Writer) error {
eBytes := []byte((*e)[:])
if err := WriteElements(w, eBytes); err != nil {
return err
}
return nil
}
// Decode attempts to unpack the raw bytes encoded in the passed io.Reader as a
// set of extra opaque data.
func (e *ExtraOpaqueData) Decode(r io.Reader) error {
// First, we'll attempt to read a set of bytes contained within the
// passed io.Reader (if any exist).
rawBytes, err := ioutil.ReadAll(r)
if err != nil {
return err
}
// If we _do_ have some bytes, then we'll swap out our backing pointer.
// This ensures that any struct that embeds this type will properly
// store the bytes once this method exits.
if len(rawBytes) > 0 {
*e = ExtraOpaqueData(rawBytes)
} else {
*e = make([]byte, 0)
}
return nil
}
// PackRecords attempts to encode the set of tlv records into the target
// ExtraOpaqueData instance. The records will be encoded as a raw TLV stream
// and stored within the backing slice pointer.
func (e *ExtraOpaqueData) PackRecords(records ...tlv.Record) error {
tlvStream, err := tlv.NewStream(records...)
if err != nil {
return err
}
var extraBytesWriter bytes.Buffer
if err := tlvStream.Encode(&extraBytesWriter); err != nil {
return err
}
*e = ExtraOpaqueData(extraBytesWriter.Bytes())
return nil
}
// ExtractRecords attempts to decode any types in the internal raw bytes as if
// it were a tlv stream. The set of raw parsed types is returned, and any
// passed records (if found in the stream) will be parsed into the proper
// tlv.Record.
func (e *ExtraOpaqueData) ExtractRecords(records ...tlv.Record) (
tlv.TypeMap, error) {
extraBytesReader := bytes.NewReader(*e)
tlvStream, err := tlv.NewStream(records...)
if err != nil {
return nil, err
}
return tlvStream.DecodeWithParsedTypes(extraBytesReader)
}