lnwire: update AnnounceSigs2 to use pure TLV
This commit is contained in:
3 files changed
+165
-36
No files matched your search
@@ -3,6 +3,8 @@ package lnwire
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AnnounceSignatures2 is a direct message between two endpoints of a
|
// AnnounceSignatures2 is a direct message between two endpoints of a
|
||||||
@@ -14,27 +16,40 @@ type AnnounceSignatures2 struct {
|
|||||||
// Channel id is better for users and debugging and short channel id is
|
// Channel id is better for users and debugging and short channel id is
|
||||||
// used for quick test on existence of the particular utxo inside the
|
// used for quick test on existence of the particular utxo inside the
|
||||||
// blockchain, because it contains information about block.
|
// blockchain, because it contains information about block.
|
||||||
ChannelID ChannelID
|
ChannelID tlv.RecordT[tlv.TlvType0, ChannelID]
|
||||||
|
|
||||||
// ShortChannelID is the unique description of the funding transaction.
|
// ShortChannelID is the unique description of the funding transaction.
|
||||||
// It is constructed with the most significant 3 bytes as the block
|
// It is constructed with the most significant 3 bytes as the block
|
||||||
// height, the next 3 bytes indicating the transaction index within the
|
// height, the next 3 bytes indicating the transaction index within the
|
||||||
// block, and the least significant two bytes indicating the output
|
// block, and the least significant two bytes indicating the output
|
||||||
// index which pays to the channel.
|
// index which pays to the channel.
|
||||||
ShortChannelID ShortChannelID
|
ShortChannelID tlv.RecordT[tlv.TlvType2, ShortChannelID]
|
||||||
|
|
||||||
// PartialSignature is the combination of the partial Schnorr signature
|
// PartialSignature is the combination of the partial Schnorr signature
|
||||||
// created for the node's bitcoin key with the partial signature created
|
// created for the node's bitcoin key with the partial signature created
|
||||||
// for the node's node ID key.
|
// for the node's node ID key.
|
||||||
PartialSignature PartialSig
|
PartialSignature tlv.RecordT[tlv.TlvType4, PartialSig]
|
||||||
|
|
||||||
// ExtraOpaqueData is the set of data that was appended to this
|
// Any extra fields in the signed range that we do not yet know about,
|
||||||
// message, some of which we may not actually know how to iterate or
|
// but we need to keep them for signature validation and to produce a
|
||||||
// parse. By holding onto this data, we ensure that we're able to
|
// valid message.
|
||||||
// properly validate the set of signatures that cover these new fields,
|
ExtraSignedFields
|
||||||
// and ensure we're able to make upgrades to the network in a forwards
|
}
|
||||||
// compatible manner.
|
|
||||||
ExtraOpaqueData ExtraOpaqueData
|
// NewAnnSigs2 is a constructor for AnnounceSignatures2.
|
||||||
|
func NewAnnSigs2(chanID ChannelID, scid ShortChannelID,
|
||||||
|
partialSig PartialSig) *AnnounceSignatures2 {
|
||||||
|
|
||||||
|
return &AnnounceSignatures2{
|
||||||
|
ChannelID: tlv.NewRecordT[tlv.TlvType0, ChannelID](chanID),
|
||||||
|
ShortChannelID: tlv.NewRecordT[tlv.TlvType2, ShortChannelID](
|
||||||
|
scid,
|
||||||
|
),
|
||||||
|
PartialSignature: tlv.NewRecordT[tlv.TlvType4, PartialSig](
|
||||||
|
partialSig,
|
||||||
|
),
|
||||||
|
ExtraSignedFields: make(ExtraSignedFields),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile time check to ensure AnnounceSignatures2 implements the
|
// A compile time check to ensure AnnounceSignatures2 implements the
|
||||||
@@ -45,17 +60,30 @@ var _ Message = (*AnnounceSignatures2)(nil)
|
|||||||
// lnwire.SizeableMessage interface.
|
// lnwire.SizeableMessage interface.
|
||||||
var _ SizeableMessage = (*AnnounceSignatures2)(nil)
|
var _ SizeableMessage = (*AnnounceSignatures2)(nil)
|
||||||
|
|
||||||
|
// A compile time check to ensure ChannelAnnouncement2 implements the
|
||||||
|
// lnwire.PureTLVMessage interface.
|
||||||
|
var _ PureTLVMessage = (*AnnounceSignatures2)(nil)
|
||||||
|
|
||||||
// Decode deserializes a serialized AnnounceSignatures2 stored in the passed
|
// Decode deserializes a serialized AnnounceSignatures2 stored in the passed
|
||||||
// io.Reader observing the specified protocol version.
|
// io.Reader observing the specified protocol version.
|
||||||
//
|
//
|
||||||
// This is part of the lnwire.Message interface.
|
// This is part of the lnwire.Message interface.
|
||||||
func (a *AnnounceSignatures2) Decode(r io.Reader, _ uint32) error {
|
func (a *AnnounceSignatures2) Decode(r io.Reader, _ uint32) error {
|
||||||
return ReadElements(r,
|
stream, err := tlv.NewStream(ProduceRecordsSorted(
|
||||||
&a.ChannelID,
|
&a.ChannelID, &a.ShortChannelID, &a.PartialSignature,
|
||||||
&a.ShortChannelID,
|
)...)
|
||||||
&a.PartialSignature,
|
if err != nil {
|
||||||
&a.ExtraOpaqueData,
|
return err
|
||||||
)
|
}
|
||||||
|
|
||||||
|
typeMap, err := stream.DecodeWithParsedTypesP2P(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
|
// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
|
||||||
@@ -63,19 +91,7 @@ func (a *AnnounceSignatures2) Decode(r io.Reader, _ uint32) error {
|
|||||||
//
|
//
|
||||||
// This is part of the lnwire.Message interface.
|
// This is part of the lnwire.Message interface.
|
||||||
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
|
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
|
||||||
if err := WriteChannelID(w, a.ChannelID); err != nil {
|
return EncodePureTLVMessage(a, w)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := WriteShortChannelID(w, a.ShortChannelID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := WriteElement(w, a.PartialSignature); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return WriteBytes(w, a.ExtraOpaqueData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgType returns the integer uniquely identifying this message type on the
|
// MsgType returns the integer uniquely identifying this message type on the
|
||||||
@@ -93,16 +109,34 @@ func (a *AnnounceSignatures2) SerializedSize() (uint32, error) {
|
|||||||
return MessageSerializedSize(a)
|
return MessageSerializedSize(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllRecords returns all the TLV records for the message. This will include all
|
||||||
|
// the records we know about along with any that we don't know about but that
|
||||||
|
// fall in the signed TLV range.
|
||||||
|
//
|
||||||
|
// NOTE: this is part of the PureTLVMessage interface.
|
||||||
|
func (a *AnnounceSignatures2) AllRecords() []tlv.Record {
|
||||||
|
recordProducers := []tlv.RecordProducer{
|
||||||
|
&a.ChannelID, &a.ShortChannelID,
|
||||||
|
&a.PartialSignature,
|
||||||
|
}
|
||||||
|
|
||||||
|
recordProducers = append(recordProducers, RecordsAsProducers(
|
||||||
|
tlv.MapToRecords(a.ExtraSignedFields),
|
||||||
|
)...)
|
||||||
|
|
||||||
|
return ProduceRecordsSorted(recordProducers...)
|
||||||
|
}
|
||||||
|
|
||||||
// SCID returns the ShortChannelID of the channel.
|
// SCID returns the ShortChannelID of the channel.
|
||||||
//
|
//
|
||||||
// NOTE: this is part of the AnnounceSignatures interface.
|
// NOTE: this is part of the AnnounceSignatures interface.
|
||||||
func (a *AnnounceSignatures2) SCID() ShortChannelID {
|
func (a *AnnounceSignatures2) SCID() ShortChannelID {
|
||||||
return a.ShortChannelID
|
return a.ShortChannelID.Val
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChanID returns the ChannelID identifying the channel.
|
// ChanID returns the ChannelID identifying the channel.
|
||||||
//
|
//
|
||||||
// NOTE: this is part of the AnnounceSignatures interface.
|
// NOTE: this is part of the AnnounceSignatures interface.
|
||||||
func (a *AnnounceSignatures2) ChanID() ChannelID {
|
func (a *AnnounceSignatures2) ChanID() ChannelID {
|
||||||
return a.ChannelID
|
return a.ChannelID.Val
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package lnwire
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestAnnSigs2EncodeDecode tests the encoding and decoding of the
|
||||||
|
// AnnounceSignatures2 message using hardcoded byte slices.
|
||||||
|
func TestAnnSigs2EncodeDecode(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// We'll create a raw byte stream that represents a valid
|
||||||
|
// AnnounceSignatures2 message with various known and unknown fields in
|
||||||
|
// the signed TLV ranges.
|
||||||
|
var rawBytes []byte
|
||||||
|
|
||||||
|
// ChannelID.
|
||||||
|
rawBytes = append(rawBytes, []byte{
|
||||||
|
0x00, // type
|
||||||
|
0x20, // length
|
||||||
|
}...)
|
||||||
|
rawBytes = append(rawBytes, make([]byte, 32)...) // value
|
||||||
|
|
||||||
|
// ShortChannelID.
|
||||||
|
rawBytes = append(rawBytes, []byte{
|
||||||
|
0x02, // type
|
||||||
|
0x08, // length
|
||||||
|
0, 0, 1, 0, 0, 2, 0, 3, // value
|
||||||
|
}...)
|
||||||
|
|
||||||
|
// PartialSignature.
|
||||||
|
rawBytes = append(rawBytes, []byte{
|
||||||
|
0x04, // type
|
||||||
|
0x20, // length
|
||||||
|
}...)
|
||||||
|
rawBytes = append(rawBytes, make([]byte, 32)...) // value
|
||||||
|
|
||||||
|
// Extra field in the first signed range.
|
||||||
|
rawBytes = append(rawBytes, []byte{
|
||||||
|
0x30, // type
|
||||||
|
0x02, // length
|
||||||
|
0xab, 0xcd, // value
|
||||||
|
}...)
|
||||||
|
|
||||||
|
w := new(bytes.Buffer)
|
||||||
|
var buf [8]byte
|
||||||
|
err := tlv.WriteVarInt(w, pureTLVSignedSecondRangeStart+1, &buf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Extra field in the second signed range.
|
||||||
|
rawBytes = append(rawBytes, w.Bytes()...) // type
|
||||||
|
rawBytes = append(rawBytes, []byte{
|
||||||
|
0x02, // length
|
||||||
|
0x79, 0x79, // value
|
||||||
|
}...)
|
||||||
|
|
||||||
|
// Now, create a new empty message and decode the raw bytes into it.
|
||||||
|
msg := &AnnounceSignatures2{}
|
||||||
|
r := bytes.NewReader(rawBytes)
|
||||||
|
err = msg.Decode(r, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// At this point, we expect 2 extra signed fields.
|
||||||
|
require.Len(t, msg.ExtraSignedFields, 2)
|
||||||
|
|
||||||
|
// Next, encode the message back into a new byte buffer.
|
||||||
|
var b bytes.Buffer
|
||||||
|
err = msg.Encode(&b, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// The re-encoded bytes should be exactly the same as the original raw
|
||||||
|
// bytes.
|
||||||
|
require.Equal(t, rawBytes, b.Bytes())
|
||||||
|
}
|
||||||
+22
-5
@@ -129,12 +129,29 @@ var _ TestMessage = (*AnnounceSignatures2)(nil)
|
|||||||
//
|
//
|
||||||
// This is part of the TestMessage interface.
|
// This is part of the TestMessage interface.
|
||||||
func (a *AnnounceSignatures2) RandTestMessage(t *rapid.T) Message {
|
func (a *AnnounceSignatures2) RandTestMessage(t *rapid.T) Message {
|
||||||
return &AnnounceSignatures2{
|
var (
|
||||||
ChannelID: RandChannelID(t),
|
chanID = RandChannelID(t)
|
||||||
ShortChannelID: RandShortChannelID(t),
|
scid = RandShortChannelID(t)
|
||||||
PartialSignature: *RandPartialSig(t),
|
pSig = RandPartialSig(t)
|
||||||
ExtraOpaqueData: RandExtraOpaqueData(t, nil),
|
)
|
||||||
|
|
||||||
|
msg := &AnnounceSignatures2{
|
||||||
|
ChannelID: tlv.NewRecordT[tlv.TlvType0, ChannelID](
|
||||||
|
chanID,
|
||||||
|
),
|
||||||
|
ShortChannelID: tlv.NewRecordT[tlv.TlvType2](scid),
|
||||||
|
PartialSignature: tlv.NewRecordT[tlv.TlvType4, PartialSig](
|
||||||
|
*pSig,
|
||||||
|
),
|
||||||
|
ExtraSignedFields: make(map[uint64][]byte),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
randRecs, _ := RandSignedRangeRecords(t)
|
||||||
|
if len(randRecs) > 0 {
|
||||||
|
msg.ExtraSignedFields = ExtraSignedFields(randRecs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile time check to ensure ChannelAnnouncement1 implements the
|
// A compile time check to ensure ChannelAnnouncement1 implements the
|
||||||
|
|||||||
Reference in new issue
Block a user