Skip to content

Commit b77b698

Browse files
committed
lnwire: update AnnounceSigs2 to use pure TLV
1 parent b6b764d commit b77b698

File tree

3 files changed

+166
-37
lines changed

3 files changed

+166
-37
lines changed

lnwire/announcement_signatures_2.go

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package lnwire
33
import (
44
"bytes"
55
"io"
6+
7+
"github.com/lightningnetwork/lnd/tlv"
68
)
79

810
// AnnounceSignatures2 is a direct message between two endpoints of a
@@ -14,27 +16,40 @@ type AnnounceSignatures2 struct {
1416
// Channel id is better for users and debugging and short channel id is
1517
// used for quick test on existence of the particular utxo inside the
1618
// blockchain, because it contains information about block.
17-
ChannelID ChannelID
19+
ChannelID tlv.RecordT[tlv.TlvType0, ChannelID]
1820

1921
// ShortChannelID is the unique description of the funding transaction.
2022
// It is constructed with the most significant 3 bytes as the block
2123
// height, the next 3 bytes indicating the transaction index within the
2224
// block, and the least significant two bytes indicating the output
2325
// index which pays to the channel.
24-
ShortChannelID ShortChannelID
26+
ShortChannelID tlv.RecordT[tlv.TlvType2, ShortChannelID]
2527

2628
// PartialSignature is the combination of the partial Schnorr signature
2729
// created for the node's bitcoin key with the partial signature created
2830
// for the node's node ID key.
29-
PartialSignature PartialSig
30-
31-
// ExtraOpaqueData is the set of data that was appended to this
32-
// message, some of which we may not actually know how to iterate or
33-
// parse. By holding onto this data, we ensure that we're able to
34-
// properly validate the set of signatures that cover these new fields,
35-
// and ensure we're able to make upgrades to the network in a forwards
36-
// compatible manner.
37-
ExtraOpaqueData ExtraOpaqueData
31+
PartialSignature tlv.RecordT[tlv.TlvType4, PartialSig]
32+
33+
// Any extra fields in the signed range that we do not yet know about,
34+
// but we need to keep them for signature validation and to produce a
35+
// valid message.
36+
ExtraSignedFields
37+
}
38+
39+
// NewAnnSigs2 is a constructor for AnnounceSignatures2.
40+
func NewAnnSigs2(chanID ChannelID, scid ShortChannelID,
41+
partialSig PartialSig) *AnnounceSignatures2 {
42+
43+
return &AnnounceSignatures2{
44+
ChannelID: tlv.NewRecordT[tlv.TlvType0, ChannelID](chanID),
45+
ShortChannelID: tlv.NewRecordT[tlv.TlvType2, ShortChannelID](
46+
scid,
47+
),
48+
PartialSignature: tlv.NewRecordT[tlv.TlvType4, PartialSig](
49+
partialSig,
50+
),
51+
ExtraSignedFields: make(ExtraSignedFields),
52+
}
3853
}
3954

4055
// A compile time check to ensure AnnounceSignatures2 implements the
@@ -45,37 +60,38 @@ var _ Message = (*AnnounceSignatures2)(nil)
4560
// lnwire.SizeableMessage interface.
4661
var _ SizeableMessage = (*AnnounceSignatures2)(nil)
4762

63+
// A compile time check to ensure ChannelAnnouncement2 implements the
64+
// lnwire.PureTLVMessage interface.
65+
var _ PureTLVMessage = (*AnnounceSignatures2)(nil)
66+
4867
// Decode deserializes a serialized AnnounceSignatures2 stored in the passed
4968
// io.Reader observing the specified protocol version.
5069
//
5170
// This is part of the lnwire.Message interface.
5271
func (a *AnnounceSignatures2) Decode(r io.Reader, _ uint32) error {
53-
return ReadElements(r,
54-
&a.ChannelID,
55-
&a.ShortChannelID,
56-
&a.PartialSignature,
57-
&a.ExtraOpaqueData,
58-
)
59-
}
60-
61-
// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
62-
// observing the protocol version specified.
63-
//
64-
// This is part of the lnwire.Message interface.
65-
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
66-
if err := WriteChannelID(w, a.ChannelID); err != nil {
72+
stream, err := tlv.NewStream(ProduceRecordsSorted(
73+
&a.ChannelID, &a.ShortChannelID, &a.PartialSignature,
74+
)...)
75+
if err != nil {
6776
return err
6877
}
6978

70-
if err := WriteShortChannelID(w, a.ShortChannelID); err != nil {
79+
typeMap, err := stream.DecodeWithParsedTypesP2P(r)
80+
if err != nil {
7181
return err
7282
}
7383

74-
if err := WriteElement(w, a.PartialSignature); err != nil {
75-
return err
76-
}
84+
a.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
85+
86+
return nil
87+
}
7788

78-
return WriteBytes(w, a.ExtraOpaqueData)
89+
// Encode serializes the target AnnounceSignatures2 into the passed io.Writer
90+
// observing the protocol version specified.
91+
//
92+
// This is part of the lnwire.Message interface.
93+
func (a *AnnounceSignatures2) Encode(w *bytes.Buffer, _ uint32) error {
94+
return EncodePureTLVMessage(a, w)
7995
}
8096

8197
// MsgType returns the integer uniquely identifying this message type on the
@@ -93,16 +109,34 @@ func (a *AnnounceSignatures2) SerializedSize() (uint32, error) {
93109
return MessageSerializedSize(a)
94110
}
95111

112+
// AllRecords returns all the TLV records for the message. This will include all
113+
// the records we know about along with any that we don't know about but that
114+
// fall in the signed TLV range.
115+
//
116+
// NOTE: this is part of the PureTLVMessage interface.
117+
func (a *AnnounceSignatures2) AllRecords() []tlv.Record {
118+
recordProducers := []tlv.RecordProducer{
119+
&a.ChannelID, &a.ShortChannelID,
120+
&a.PartialSignature,
121+
}
122+
123+
recordProducers = append(recordProducers, RecordsAsProducers(
124+
tlv.MapToRecords(a.ExtraSignedFields),
125+
)...)
126+
127+
return ProduceRecordsSorted(recordProducers...)
128+
}
129+
96130
// SCID returns the ShortChannelID of the channel.
97131
//
98132
// NOTE: this is part of the AnnounceSignatures interface.
99133
func (a *AnnounceSignatures2) SCID() ShortChannelID {
100-
return a.ShortChannelID
134+
return a.ShortChannelID.Val
101135
}
102136

103137
// ChanID returns the ChannelID identifying the channel.
104138
//
105139
// NOTE: this is part of the AnnounceSignatures interface.
106140
func (a *AnnounceSignatures2) ChanID() ChannelID {
107-
return a.ChannelID
141+
return a.ChannelID.Val
108142
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package lnwire
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/lightningnetwork/lnd/tlv"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
// TestAnnSigs2EncodeDecode tests the encoding and decoding of the
12+
// AnnounceSignatures2 message using hardcoded byte slices.
13+
func TestAnnSigs2EncodeDecode(t *testing.T) {
14+
t.Parallel()
15+
16+
// We'll create a raw byte stream that represents a valid
17+
// AnnounceSignatures2 message with various known and unknown fields in
18+
// the signed TLV ranges.
19+
var rawBytes []byte
20+
21+
// ChannelID.
22+
rawBytes = append(rawBytes, []byte{
23+
0x00, // type
24+
0x20, // length
25+
}...)
26+
rawBytes = append(rawBytes, make([]byte, 32)...) // value
27+
28+
// ShortChannelID.
29+
rawBytes = append(rawBytes, []byte{
30+
0x02, // type
31+
0x08, // length
32+
0, 0, 1, 0, 0, 2, 0, 3, // value
33+
}...)
34+
35+
// PartialSignature.
36+
rawBytes = append(rawBytes, []byte{
37+
0x04, // type
38+
0x20, // length
39+
}...)
40+
rawBytes = append(rawBytes, make([]byte, 32)...) // value
41+
42+
// Extra field in the first signed range.
43+
rawBytes = append(rawBytes, []byte{
44+
0x30, // type
45+
0x02, // length
46+
0xab, 0xcd, // value
47+
}...)
48+
49+
w := new(bytes.Buffer)
50+
var buf [8]byte
51+
err := tlv.WriteVarInt(w, pureTLVSignedSecondRangeStart+1, &buf)
52+
require.NoError(t, err)
53+
54+
// Extra field in the second signed range.
55+
rawBytes = append(rawBytes, w.Bytes()...) // type
56+
rawBytes = append(rawBytes, []byte{
57+
0x02, // length
58+
0x79, 0x79, // value
59+
}...)
60+
61+
// Now, create a new empty message and decode the raw bytes into it.
62+
msg := &AnnounceSignatures2{}
63+
r := bytes.NewReader(rawBytes)
64+
err = msg.Decode(r, 0)
65+
require.NoError(t, err)
66+
67+
// At this point, we expect 2 extra signed fields.
68+
require.Len(t, msg.ExtraSignedFields, 2)
69+
70+
// Next, encode the message back into a new byte buffer.
71+
var b bytes.Buffer
72+
err = msg.Encode(&b, 0)
73+
require.NoError(t, err)
74+
75+
// The re-encoded bytes should be exactly the same as the original raw
76+
// bytes.
77+
require.Equal(t, rawBytes, b.Bytes())
78+
}

lnwire/test_message.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,29 @@ var _ TestMessage = (*AnnounceSignatures2)(nil)
129129
//
130130
// This is part of the TestMessage interface.
131131
func (a *AnnounceSignatures2) RandTestMessage(t *rapid.T) Message {
132-
return &AnnounceSignatures2{
133-
ChannelID: RandChannelID(t),
134-
ShortChannelID: RandShortChannelID(t),
135-
PartialSignature: *RandPartialSig(t),
136-
ExtraOpaqueData: RandExtraOpaqueData(t, nil),
132+
var (
133+
chanID = RandChannelID(t)
134+
scid = RandShortChannelID(t)
135+
pSig = RandPartialSig(t)
136+
)
137+
138+
msg := &AnnounceSignatures2{
139+
ChannelID: tlv.NewRecordT[tlv.TlvType0, ChannelID](
140+
chanID,
141+
),
142+
ShortChannelID: tlv.NewRecordT[tlv.TlvType2](scid),
143+
PartialSignature: tlv.NewRecordT[tlv.TlvType4, PartialSig](
144+
*pSig,
145+
),
146+
ExtraSignedFields: make(map[uint64][]byte),
147+
}
148+
149+
randRecs, _ := RandSignedRangeRecords(t)
150+
if len(randRecs) > 0 {
151+
msg.ExtraSignedFields = ExtraSignedFields(randRecs)
137152
}
153+
154+
return msg
138155
}
139156

140157
// A compile time check to ensure ChannelAnnouncement1 implements the

0 commit comments

Comments
 (0)