Skip to content

Commit d247cc9

Browse files
committed
lnwire: add custom records field to type UpdateFulfillHtlc
- Introduce the field `CustomRecords` to the type `UpdateFulfillHtlc`. - Encode and decode the new field into the `ExtraData` field of the `update_fulfill_htlc` wire message. - Empty `ExtraData` field is set to `nil`.
1 parent 6fa2db0 commit d247cc9

File tree

3 files changed

+103
-6
lines changed

3 files changed

+103
-6
lines changed

htlcswitch/payment_result_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ func TestNetworkResultSerialization(t *testing.T) {
3838
ChanID: chanID,
3939
ID: 2,
4040
PaymentPreimage: preimage,
41-
ExtraData: make([]byte, 0),
4241
}
4342

4443
fail := &lnwire.UpdateFailHTLC{

lnwire/update_fulfill_htlc.go

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package lnwire
22

33
import (
44
"bytes"
5+
"fmt"
56
"io"
7+
8+
"github.com/lightningnetwork/lnd/tlv"
69
)
710

811
// UpdateFulfillHTLC is sent by Alice to Bob when she wishes to settle a
@@ -23,6 +26,10 @@ type UpdateFulfillHTLC struct {
2326
// HTLC.
2427
PaymentPreimage [32]byte
2528

29+
// CustomRecords maps TLV types to byte slices, storing arbitrary data
30+
// intended for inclusion in the ExtraData field.
31+
CustomRecords CustomRecords
32+
2633
// ExtraData is the set of data that was appended to this message to
2734
// fill out the full maximum transport message size. These fields can
2835
// be used to specify optional data such as custom TLV fields.
@@ -49,12 +56,75 @@ var _ Message = (*UpdateFulfillHTLC)(nil)
4956
//
5057
// This is part of the lnwire.Message interface.
5158
func (c *UpdateFulfillHTLC) Decode(r io.Reader, pver uint32) error {
52-
return ReadElements(r,
59+
// msgExtraData is a temporary variable used to read the message extra
60+
// data field from the reader.
61+
var msgExtraData ExtraOpaqueData
62+
63+
if err := ReadElements(r,
5364
&c.ChanID,
5465
&c.ID,
5566
c.PaymentPreimage[:],
56-
&c.ExtraData,
67+
&msgExtraData,
68+
); err != nil {
69+
return err
70+
}
71+
72+
// Extract TLV records from the message extra data field.
73+
extraDataTlvMap, err := msgExtraData.ExtractRecords()
74+
if err != nil {
75+
return err
76+
}
77+
78+
// Any records from the extra data TLV map which are in the custom
79+
// records TLV type range will be included in the custom records field
80+
// and removed from the extra data field.
81+
customRecordsTlvMap := make(tlv.TypeMap, len(extraDataTlvMap))
82+
for k, v := range extraDataTlvMap {
83+
// Skip records that are not in the custom records TLV type
84+
// range.
85+
if k < MinCustomRecordsTlvType {
86+
continue
87+
}
88+
89+
// Include the record in the custom records map.
90+
customRecordsTlvMap[k] = v
91+
92+
// Now that the record is included in the custom records map,
93+
// we can remove it from the extra data TLV map.
94+
delete(extraDataTlvMap, k)
95+
}
96+
97+
// Set the custom records field to the TLV record map.
98+
customRecords, err := NewCustomRecordsFromTlvTypeMap(
99+
customRecordsTlvMap,
57100
)
101+
if err != nil {
102+
return err
103+
}
104+
c.CustomRecords = customRecords
105+
106+
// Set custom records to nil if we didn't parse anything out of it so
107+
// that we can use assert.Equal in tests.
108+
if len(customRecordsTlvMap) == 0 {
109+
c.CustomRecords = nil
110+
}
111+
112+
// Set extra data to nil if we didn't parse anything out of it so that
113+
// we can use assert.Equal in tests.
114+
if len(extraDataTlvMap) == 0 {
115+
c.ExtraData = nil
116+
return nil
117+
}
118+
119+
// Encode the remaining records back into the extra data field. These
120+
// records are not in the custom records TLV type range and do not
121+
// have associated fields in the UpdateFulfillHTLC struct.
122+
c.ExtraData, err = NewExtraOpaqueDataFromTlvTypeMap(extraDataTlvMap)
123+
if err != nil {
124+
return err
125+
}
126+
127+
return nil
58128
}
59129

60130
// Encode serializes the target UpdateFulfillHTLC into the passed io.Writer
@@ -74,7 +144,34 @@ func (c *UpdateFulfillHTLC) Encode(w *bytes.Buffer, pver uint32) error {
74144
return err
75145
}
76146

77-
return WriteBytes(w, c.ExtraData)
147+
// Construct a slice of all the records that we should include in the
148+
// message extra data field. We will start by including any records from
149+
// the extra data field.
150+
msgExtraDataRecords, err := c.ExtraData.RecordProducers()
151+
if err != nil {
152+
return err
153+
}
154+
155+
// Include custom records in the extra data wire field if they are
156+
// present. Ensure that the custom records are validated before encoding
157+
// them.
158+
if err := c.CustomRecords.Validate(); err != nil {
159+
return fmt.Errorf("custom records validation error: %w", err)
160+
}
161+
162+
// Extend the message extra data records slice with TLV records from the
163+
// custom records field.
164+
customTlvRecords := c.CustomRecords.RecordProducers()
165+
msgExtraDataRecords = append(msgExtraDataRecords, customTlvRecords...)
166+
167+
// We will now construct the message extra data field that will be
168+
// encoded into the byte writer.
169+
var msgExtraData ExtraOpaqueData
170+
if err := msgExtraData.PackRecords(msgExtraDataRecords...); err != nil {
171+
return err
172+
}
173+
174+
return WriteBytes(w, msgExtraData)
78175
}
79176

80177
// MsgType returns the integer uniquely identifying this message type on the

peer/brontide.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,8 +2033,9 @@ func messageSummary(msg lnwire.Message) string {
20332033
msg.ID, msg.Reason)
20342034

20352035
case *lnwire.UpdateFulfillHTLC:
2036-
return fmt.Sprintf("chan_id=%v, id=%v, pre_image=%x",
2037-
msg.ChanID, msg.ID, msg.PaymentPreimage[:])
2036+
return fmt.Sprintf("chan_id=%v, id=%v, pre_image=%x, "+
2037+
"custom_records=%v", msg.ChanID, msg.ID,
2038+
msg.PaymentPreimage[:], msg.CustomRecords)
20382039

20392040
case *lnwire.CommitSig:
20402041
return fmt.Sprintf("chan_id=%v, num_htlcs=%v", msg.ChanID,

0 commit comments

Comments
 (0)