Skip to content

Commit ab96de3

Browse files
authored
Merge pull request #8967 from ProofOfKeags/feature/stfu-wire
[MICRO]: add wire messages for quiescence
2 parents c262b1b + 2ddc3db commit ab96de3

File tree

5 files changed

+123
-0
lines changed

5 files changed

+123
-0
lines changed

lnwire/fuzz_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,17 @@ func FuzzWarning(f *testing.F) {
191191
})
192192
}
193193

194+
func FuzzStfu(f *testing.F) {
195+
f.Fuzz(func(t *testing.T, data []byte) {
196+
// Prefix with MsgStfu.
197+
data = prefixWithMsgType(data, MsgStfu)
198+
199+
// Pass the message into our general fuzz harness for wire
200+
// messages.
201+
harness(t, data)
202+
})
203+
}
204+
194205
func FuzzFundingCreated(f *testing.F) {
195206
f.Fuzz(func(t *testing.T, data []byte) {
196207
// Prefix with MsgFundingCreated.

lnwire/lnwire_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,22 @@ func TestLightningWireProtocol(t *testing.T) {
438438
// are too complex for the testing/quick package to automatically
439439
// generate.
440440
customTypeGen := map[MessageType]func([]reflect.Value, *rand.Rand){
441+
MsgStfu: func(v []reflect.Value, r *rand.Rand) {
442+
req := Stfu{}
443+
if _, err := r.Read(req.ChanID[:]); err != nil {
444+
t.Fatalf("unable to generate ChanID: %v", err)
445+
}
446+
447+
// 1/2 chance of being initiator
448+
req.Initiator = r.Intn(2) == 1
449+
450+
// 1/2 chance additional TLV data.
451+
if r.Intn(2) == 0 {
452+
req.ExtraData = []byte{0xfd, 0x00, 0xff, 0x00}
453+
}
454+
455+
v[0] = reflect.ValueOf(req)
456+
},
441457
MsgInit: func(v []reflect.Value, r *rand.Rand) {
442458
req := NewInitMessage(
443459
randRawFeatureVector(r),
@@ -1384,6 +1400,12 @@ func TestLightningWireProtocol(t *testing.T) {
13841400
msgType MessageType
13851401
scenario interface{}
13861402
}{
1403+
{
1404+
msgType: MsgStfu,
1405+
scenario: func(m Stfu) bool {
1406+
return mainScenario(&m)
1407+
},
1408+
},
13871409
{
13881410
msgType: MsgInit,
13891411
scenario: func(m Init) bool {

lnwire/message.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type MessageType uint16
2323
// Lightning protocol.
2424
const (
2525
MsgWarning MessageType = 1
26+
MsgStfu = 2
2627
MsgInit = 16
2728
MsgError = 17
2829
MsgPing = 18
@@ -84,6 +85,8 @@ func (t MessageType) String() string {
8485
switch t {
8586
case MsgWarning:
8687
return "Warning"
88+
case MsgStfu:
89+
return "Stfu"
8790
case MsgInit:
8891
return "Init"
8992
case MsgOpenChannel:
@@ -211,6 +214,8 @@ func makeEmptyMessage(msgType MessageType) (Message, error) {
211214
switch msgType {
212215
case MsgWarning:
213216
msg = &Warning{}
217+
case MsgStfu:
218+
msg = &Stfu{}
214219
case MsgInit:
215220
msg = &Init{}
216221
case MsgOpenChannel:

lnwire/stfu.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package lnwire
2+
3+
import (
4+
"bytes"
5+
"io"
6+
)
7+
8+
// Stfu is a message that is sent to lock the channel state prior to some other
9+
// interactive protocol where channel updates need to be paused.
10+
type Stfu struct {
11+
// ChanID identifies which channel needs to be frozen.
12+
ChanID ChannelID
13+
14+
// Initiator is a byte that identifies whether we are the initiator of
15+
// this process.
16+
Initiator bool
17+
18+
// ExtraData is the set of data that was appended to this message to
19+
// fill out the full maximum transport message size. These fields can
20+
// be used to specify optional data such as custom TLV fields.
21+
ExtraData ExtraOpaqueData
22+
}
23+
24+
// A compile time check to ensure Stfu implements the lnwire.Message interface.
25+
var _ Message = (*Stfu)(nil)
26+
27+
// Encode serializes the target Stfu into the passed io.Writer.
28+
// Serialization will observe the rules defined by the passed protocol version.
29+
//
30+
// This is a part of the lnwire.Message interface.
31+
func (s *Stfu) Encode(w *bytes.Buffer, _ uint32) error {
32+
if err := WriteChannelID(w, s.ChanID); err != nil {
33+
return err
34+
}
35+
36+
if err := WriteBool(w, s.Initiator); err != nil {
37+
return err
38+
}
39+
40+
return WriteBytes(w, s.ExtraData)
41+
}
42+
43+
// Decode deserializes the serialized Stfu stored in the passed io.Reader
44+
// into the target Stfu using the deserialization rules defined by the
45+
// passed protocol version.
46+
//
47+
// This is a part of the lnwire.Message interface.
48+
func (s *Stfu) Decode(r io.Reader, _ uint32) error {
49+
if err := ReadElements(
50+
r, &s.ChanID, &s.Initiator, &s.ExtraData,
51+
); err != nil {
52+
return err
53+
}
54+
55+
// This is required to pass the fuzz test round trip equality check.
56+
if len(s.ExtraData) == 0 {
57+
s.ExtraData = nil
58+
}
59+
60+
return nil
61+
}
62+
63+
// MsgType returns the MessageType code which uniquely identifies this message
64+
// as a Stfu on the wire.
65+
//
66+
// This is part of the lnwire.Message interface.
67+
func (s *Stfu) MsgType() MessageType {
68+
return MsgStfu
69+
}
70+
71+
// A compile time check to ensure Stfu implements the
72+
// lnwire.LinkUpdater interface.
73+
var _ LinkUpdater = (*Stfu)(nil)
74+
75+
// TargetChanID returns the channel id of the link for which this message is
76+
// intended.
77+
//
78+
// NOTE: Part of peer.LinkUpdater interface.
79+
func (s *Stfu) TargetChanID() ChannelID {
80+
return s.ChanID
81+
}

peer/brontide.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,6 +2144,10 @@ func messageSummary(msg lnwire.Message) string {
21442144
time.Unix(int64(msg.FirstTimestamp), 0),
21452145
msg.TimestampRange)
21462146

2147+
case *lnwire.Stfu:
2148+
return fmt.Sprintf("chan_id=%v, initiator=%v", msg.ChanID,
2149+
msg.Initiator)
2150+
21472151
case *lnwire.Custom:
21482152
return fmt.Sprintf("type=%d", msg.Type)
21492153
}

0 commit comments

Comments
 (0)