Skip to content

Commit 3b9507b

Browse files
guggeroffranr
authored andcommitted
multi: refactor reject msg to use new tlv types
Change reject message data encoding to use new TLV libraries. This is a breaking change as the RejectErr field will now be encoded as a single TLV field. This commit also bumps the reject msg current version from 0 to 1.
1 parent 0d64598 commit 3b9507b

File tree

4 files changed

+72
-85
lines changed

4 files changed

+72
-85
lines changed

rfqmsg/messages.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ type WireMsgDataVersion uint8
117117
const (
118118
// V0 represents version 0 of the contents in a wire message data field.
119119
V0 WireMsgDataVersion = 0
120+
121+
// V1 represents version 1 of the contents in a wire message data field.
122+
V1 WireMsgDataVersion = 1
120123
)
121124

122125
// Record returns a TLV record that can be used to encode/decode a

rfqmsg/reject.go

Lines changed: 59 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -9,74 +9,47 @@ import (
99
"github.com/lightningnetwork/lnd/tlv"
1010
)
1111

12-
const (
13-
// Reject message type field TLV types.
14-
15-
TypeRejectVersion tlv.Type = 0
16-
TypeRejectID tlv.Type = 2
17-
TypeRejectErrCode tlv.Type = 3
18-
TypeRejectErrMsg tlv.Type = 5
19-
)
20-
21-
func TypeRecordRejectVersion(version *WireMsgDataVersion) tlv.Record {
22-
const recordSize = 1
23-
24-
return tlv.MakeStaticRecord(
25-
TypeRejectVersion, version, recordSize,
26-
WireMsgDataVersionEncoder, WireMsgDataVersionDecoder,
27-
)
28-
}
29-
30-
func TypeRecordRejectID(id *ID) tlv.Record {
31-
const recordSize = 32
32-
33-
return tlv.MakeStaticRecord(
34-
TypeRejectID, id, recordSize, IdEncoder, IdDecoder,
35-
)
36-
}
37-
38-
func TypeRecordRejectErrCode(errCode *uint8) tlv.Record {
39-
return tlv.MakePrimitiveRecord(TypeRejectErrCode, errCode)
40-
}
41-
42-
func TypeRecordRejectErrMsg(errMsg *string) tlv.Record {
43-
sizeFunc := func() uint64 {
44-
return uint64(len(*errMsg))
45-
}
46-
return tlv.MakeDynamicRecord(
47-
TypeRejectErrMsg, errMsg, sizeFunc,
48-
rejectErrMsgEncoder, rejectErrMsgDecoder,
49-
)
50-
}
12+
// rejectErrEncoder is a function that encodes a RejectErr into a writer.
13+
func rejectErrEncoder(w io.Writer, val any, buf *[8]byte) error {
14+
if typ, ok := val.(*RejectErr); ok {
15+
if err := tlv.EUint8(w, &typ.Code, buf); err != nil {
16+
return err
17+
}
5118

52-
func rejectErrMsgEncoder(w io.Writer, val any, buf *[8]byte) error {
53-
if typ, ok := val.(*string); ok {
54-
msgBytes := []byte(*typ)
55-
err := tlv.EVarBytes(w, &msgBytes, buf)
56-
if err != nil {
19+
msgBytes := []byte(typ.Msg)
20+
if err := tlv.EVarBytes(w, &msgBytes, buf); err != nil {
5721
return err
5822
}
5923

6024
return nil
6125
}
6226

63-
return tlv.NewTypeForEncodingErr(val, "RejectErrMsg")
27+
return tlv.NewTypeForEncodingErr(val, "RejectErr")
6428
}
6529

66-
func rejectErrMsgDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error {
67-
if typ, ok := val.(*string); ok {
30+
// rejectErrDecoder is a function that decodes a RejectErr from a reader.
31+
func rejectErrDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error {
32+
if typ, ok := val.(*RejectErr); ok {
33+
var rejectCode uint8
34+
if err := tlv.DUint8(r, &rejectCode, buf, 1); err != nil {
35+
return err
36+
}
37+
6838
var errMsgBytes []byte
69-
err := tlv.DVarBytes(r, &errMsgBytes, buf, l)
39+
err := tlv.DVarBytes(r, &errMsgBytes, buf, l-1)
7040
if err != nil {
7141
return err
7242
}
7343

74-
*typ = string(errMsgBytes)
44+
*typ = RejectErr{
45+
Code: rejectCode,
46+
Msg: string(errMsgBytes),
47+
}
7548

7649
return nil
7750
}
7851

79-
return tlv.NewTypeForDecodingErr(val, "RejectErrMsg", l, l)
52+
return tlv.NewTypeForDecodingErr(val, "RejectErr", l, l)
8053
}
8154

8255
// RejectErr is a struct that represents the error code and message of a quote
@@ -89,6 +62,20 @@ type RejectErr struct {
8962
Msg string
9063
}
9164

65+
// Record returns a TLV record that can be used to encode/decode a RejectErr
66+
// to/from a TLV stream.
67+
func (v *RejectErr) Record() tlv.Record {
68+
sizeFunc := func() uint64 {
69+
return 1 + uint64(len(v.Msg))
70+
}
71+
72+
// We set the type to zero here because the type parameter in
73+
// tlv.RecordT will be used as the actual type.
74+
return tlv.MakeDynamicRecord(
75+
0, v, sizeFunc, rejectErrEncoder, rejectErrDecoder,
76+
)
77+
}
78+
9279
var (
9380
// ErrUnknownReject is the error code for when the quote is rejected
9481
// for an unspecified reason.
@@ -108,57 +95,45 @@ var (
10895
const (
10996
// latestRejectVersion is the latest supported reject wire message data
11097
// field version.
111-
latestRejectVersion = V0
98+
latestRejectVersion = V1
11299
)
113100

114-
// rejectMsgData is a struct that represents the data field of a quote
115-
// reject message.
101+
// rejectMsgData is a struct that represents the data field of a quote reject
102+
// message.
116103
type rejectMsgData struct {
117104
// Version is the version of the message data.
118-
Version WireMsgDataVersion
105+
Version tlv.RecordT[tlv.TlvType0, WireMsgDataVersion]
119106

120107
// ID represents the unique identifier of the quote request message that
121108
// this response is associated with.
122-
ID ID
109+
ID tlv.RecordT[tlv.TlvType2, ID]
123110

124111
// Err is the error code and message that provides the reason for the
125112
// rejection.
126-
Err RejectErr
113+
Err tlv.RecordT[tlv.TlvType5, RejectErr]
127114
}
128115

129-
// EncodeRecords determines the non-nil records to include when encoding at
130-
// runtime.
131-
func (q *rejectMsgData) encodeRecords() []tlv.Record {
116+
// records returns all records for encoding/decoding.
117+
func (q *rejectMsgData) records() []tlv.Record {
132118
return []tlv.Record{
133-
TypeRecordRejectVersion(&q.Version),
134-
TypeRecordRejectID(&q.ID),
135-
TypeRecordRejectErrCode(&q.Err.Code),
136-
TypeRecordRejectErrMsg(&q.Err.Msg),
119+
q.Version.Record(),
120+
q.ID.Record(),
121+
q.Err.Record(),
137122
}
138123
}
139124

140125
// Encode encodes the structure into a TLV stream.
141126
func (q *rejectMsgData) Encode(writer io.Writer) error {
142-
stream, err := tlv.NewStream(q.encodeRecords()...)
127+
stream, err := tlv.NewStream(q.records()...)
143128
if err != nil {
144129
return err
145130
}
146131
return stream.Encode(writer)
147132
}
148133

149-
// DecodeRecords provides all TLV records for decoding.
150-
func (q *rejectMsgData) decodeRecords() []tlv.Record {
151-
return []tlv.Record{
152-
TypeRecordRejectVersion(&q.Version),
153-
TypeRecordRejectID(&q.ID),
154-
TypeRecordRejectErrCode(&q.Err.Code),
155-
TypeRecordRejectErrMsg(&q.Err.Msg),
156-
}
157-
}
158-
159134
// Decode decodes the structure from a TLV stream.
160135
func (q *rejectMsgData) Decode(r io.Reader) error {
161-
stream, err := tlv.NewStream(q.decodeRecords()...)
136+
stream, err := tlv.NewStream(q.records()...)
162137
if err != nil {
163138
return err
164139
}
@@ -192,9 +167,11 @@ func NewReject(peer route.Vertex, requestId ID,
192167
return &Reject{
193168
Peer: peer,
194169
rejectMsgData: rejectMsgData{
195-
Version: latestRejectVersion,
196-
ID: requestId,
197-
Err: rejectErr,
170+
Version: tlv.NewRecordT[tlv.TlvType0](
171+
latestRejectVersion,
172+
),
173+
ID: tlv.NewRecordT[tlv.TlvType2](requestId),
174+
Err: tlv.NewRecordT[tlv.TlvType5](rejectErr),
198175
},
199176
}
200177
}
@@ -216,9 +193,9 @@ func NewQuoteRejectFromWireMsg(wireMsg WireMessage) (*Reject, error) {
216193
}
217194

218195
// Ensure that the message version is supported.
219-
if msgData.Version > latestRejectVersion {
196+
if msgData.Version.Val != latestRejectVersion {
220197
return nil, fmt.Errorf("unsupported reject message version: %d",
221-
msgData.Version)
198+
msgData.Version.Val)
222199
}
223200

224201
return &Reject{
@@ -250,13 +227,13 @@ func (q *Reject) MsgPeer() route.Vertex {
250227

251228
// MsgID returns the quote request session ID.
252229
func (q *Reject) MsgID() ID {
253-
return q.ID
230+
return q.ID.Val
254231
}
255232

256233
// String returns a human-readable string representation of the message.
257234
func (q *Reject) String() string {
258235
return fmt.Sprintf("Reject(id=%x, err_code=%d, err_msg=%s)",
259-
q.ID[:], q.Err.Code, q.Err.Msg)
236+
q.ID.Val[:], q.Err.Val.Code, q.Err.Val.Msg)
260237
}
261238

262239
// Ensure that the message type implements the OutgoingMsg interface.

rfqmsg/reject_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ func TestRejectEncodeDecode(t *testing.T) {
4646
id: id,
4747
err: ErrPriceOracleUnavailable,
4848
},
49+
{
50+
testName: "empty error message",
51+
peer: route.Vertex{1, 2, 3},
52+
version: 5,
53+
id: id,
54+
err: RejectErr{},
55+
},
4956
}
5057

5158
for _, tc := range testCases {

taprpc/marshal.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,9 @@ func MarshalIncomingRejectQuoteEvent(
612612

613613
return &rfqrpc.RejectedQuoteResponse{
614614
Peer: event.Peer.String(),
615-
Id: event.ID[:],
616-
ErrorMessage: event.Err.Msg,
617-
ErrorCode: uint32(event.Err.Code),
615+
Id: event.ID.Val[:],
616+
ErrorMessage: event.Err.Val.Msg,
617+
ErrorCode: uint32(event.Err.Val.Code),
618618
}
619619
}
620620

0 commit comments

Comments
 (0)