• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.57
/lnwire/reply_channel_range.go
1
package lnwire
2

3
import (
4
        "bytes"
5
        "fmt"
6
        "io"
7
        "math"
8
        "sort"
9

10
        "github.com/btcsuite/btcd/chaincfg/chainhash"
11
        "github.com/lightningnetwork/lnd/tlv"
12
)
13

14
// ReplyChannelRange is the response to the QueryChannelRange message. It
15
// includes the original query, and the next streaming chunk of encoded short
16
// channel ID's as the response. We'll also include a byte that indicates if
17
// this is the last query in the message.
18
type ReplyChannelRange struct {
19
        // ChainHash denotes the target chain that we're trying to synchronize
20
        // channel graph state for.
21
        ChainHash chainhash.Hash
22

23
        // FirstBlockHeight is the first block in the query range. The
24
        // responder should send all new short channel IDs from this block
25
        // until this block plus the specified number of blocks.
26
        FirstBlockHeight uint32
27

28
        // NumBlocks is the number of blocks beyond the first block that short
29
        // channel ID's should be sent for.
30
        NumBlocks uint32
31

32
        // Complete denotes if this is the conclusion of the set of streaming
33
        // responses to the original query.
34
        Complete uint8
35

36
        // EncodingType is a signal to the receiver of the message that
37
        // indicates exactly how the set of short channel ID's that follow have
38
        // been encoded.
39
        EncodingType QueryEncoding
40

41
        // ShortChanIDs is a slice of decoded short channel ID's.
42
        ShortChanIDs []ShortChannelID
43

44
        // Timestamps is an optional set of timestamps corresponding to the
45
        // latest timestamps for the channel update messages corresponding to
46
        // those referenced in the ShortChanIDs list. If this field is used,
47
        // then the length must match the length of ShortChanIDs.
48
        Timestamps Timestamps
49

50
        // ExtraData is the set of data that was appended to this message to
51
        // fill out the full maximum transport message size. These fields can
52
        // be used to specify optional data such as custom TLV fields.
53
        ExtraData ExtraOpaqueData
54

55
        // noSort indicates whether or not to sort the short channel ids before
56
        // writing them out.
57
        //
58
        // NOTE: This should only be used for testing.
59
        noSort bool
60
}
61

62
// NewReplyChannelRange creates a new empty ReplyChannelRange message.
UNCOV
63
func NewReplyChannelRange() *ReplyChannelRange {
×
UNCOV
64
        return &ReplyChannelRange{
×
UNCOV
65
                ExtraData: make([]byte, 0),
×
UNCOV
66
        }
×
UNCOV
67
}
×
68

69
// A compile time check to ensure ReplyChannelRange implements the
70
// lnwire.Message interface.
71
var _ Message = (*ReplyChannelRange)(nil)
72

73
// A compile time check to ensure ReplyChannelRange implements the
74
// lnwire.SizeableMessage interface.
75
var _ SizeableMessage = (*ReplyChannelRange)(nil)
76

77
// Decode deserializes a serialized ReplyChannelRange message stored in the
78
// passed io.Reader observing the specified protocol version.
79
//
80
// This is part of the lnwire.Message interface.
81
func (c *ReplyChannelRange) Decode(r io.Reader, pver uint32) error {
3✔
82
        err := ReadElements(r,
3✔
83
                c.ChainHash[:],
3✔
84
                &c.FirstBlockHeight,
3✔
85
                &c.NumBlocks,
3✔
86
                &c.Complete,
3✔
87
        )
3✔
88
        if err != nil {
3✔
UNCOV
89
                return err
×
UNCOV
90
        }
×
91

92
        c.EncodingType, c.ShortChanIDs, err = decodeShortChanIDs(r)
3✔
93
        if err != nil {
3✔
UNCOV
94
                return err
×
UNCOV
95
        }
×
96

97
        var tlvRecords ExtraOpaqueData
3✔
98
        if err := ReadElements(r, &tlvRecords); err != nil {
3✔
99
                return err
×
100
        }
×
101

102
        var timeStamps Timestamps
3✔
103
        typeMap, err := tlvRecords.ExtractRecords(&timeStamps)
3✔
104
        if err != nil {
3✔
UNCOV
105
                return err
×
UNCOV
106
        }
×
107

108
        // Set the corresponding TLV types if they were included in the stream.
109
        if val, ok := typeMap[TimestampsRecordType]; ok && val == nil {
6✔
110
                c.Timestamps = timeStamps
3✔
111

3✔
112
                // Check that a timestamp was provided for each SCID.
3✔
113
                if len(c.Timestamps) != len(c.ShortChanIDs) {
3✔
UNCOV
114
                        return fmt.Errorf("number of timestamps does not " +
×
UNCOV
115
                                "match number of SCIDs")
×
UNCOV
116
                }
×
117
        }
118

119
        if len(tlvRecords) != 0 {
6✔
120
                c.ExtraData = tlvRecords
3✔
121
        }
3✔
122

123
        return nil
3✔
124
}
125

126
// Encode serializes the target ReplyChannelRange into the passed io.Writer
127
// observing the protocol version specified.
128
//
129
// This is part of the lnwire.Message interface.
130
func (c *ReplyChannelRange) Encode(w *bytes.Buffer, pver uint32) error {
3✔
131
        if err := WriteBytes(w, c.ChainHash[:]); err != nil {
3✔
132
                return err
×
133
        }
×
134

135
        if err := WriteUint32(w, c.FirstBlockHeight); err != nil {
3✔
136
                return err
×
137
        }
×
138

139
        if err := WriteUint32(w, c.NumBlocks); err != nil {
3✔
140
                return err
×
141
        }
×
142

143
        if err := WriteUint8(w, c.Complete); err != nil {
3✔
144
                return err
×
145
        }
×
146

147
        // For both of the current encoding types, the channel ID's are to be
148
        // sorted in place, so we'll do that now. The sorting is applied unless
149
        // we were specifically requested not to for testing purposes.
150
        if !c.noSort {
6✔
151
                var scidPreSortIndex map[uint64]int
3✔
152
                if len(c.Timestamps) != 0 {
6✔
153
                        // Sanity check that a timestamp was provided for each
3✔
154
                        // SCID.
3✔
155
                        if len(c.Timestamps) != len(c.ShortChanIDs) {
3✔
UNCOV
156
                                return fmt.Errorf("must provide a timestamp " +
×
UNCOV
157
                                        "pair for each of the given SCIDs")
×
UNCOV
158
                        }
×
159

160
                        // Create a map from SCID value to the original index of
161
                        // the SCID in the unsorted list.
162
                        scidPreSortIndex = make(
3✔
163
                                map[uint64]int, len(c.ShortChanIDs),
3✔
164
                        )
3✔
165
                        for i, scid := range c.ShortChanIDs {
6✔
166
                                scidPreSortIndex[scid.ToUint64()] = i
3✔
167
                        }
3✔
168

169
                        // Sanity check that there were no duplicates in the
170
                        // SCID list.
171
                        if len(scidPreSortIndex) != len(c.ShortChanIDs) {
3✔
UNCOV
172
                                return fmt.Errorf("scid list should not " +
×
UNCOV
173
                                        "contain duplicates")
×
UNCOV
174
                        }
×
175
                }
176

177
                // Now sort the SCIDs.
178
                sort.Slice(c.ShortChanIDs, func(i, j int) bool {
6✔
179
                        return c.ShortChanIDs[i].ToUint64() <
3✔
180
                                c.ShortChanIDs[j].ToUint64()
3✔
181
                })
3✔
182

183
                if len(c.Timestamps) != 0 {
6✔
184
                        timestamps := make(Timestamps, len(c.Timestamps))
3✔
185

3✔
186
                        for i, scid := range c.ShortChanIDs {
6✔
187
                                timestamps[i] = []ChanUpdateTimestamps(
3✔
188
                                        c.Timestamps,
3✔
189
                                )[scidPreSortIndex[scid.ToUint64()]]
3✔
190
                        }
3✔
191
                        c.Timestamps = timestamps
3✔
192
                }
193
        }
194

195
        err := encodeShortChanIDs(w, c.EncodingType, c.ShortChanIDs)
3✔
196
        if err != nil {
3✔
197
                return err
×
198
        }
×
199

200
        recordProducers := make([]tlv.RecordProducer, 0, 1)
3✔
201
        if len(c.Timestamps) != 0 {
6✔
202
                recordProducers = append(recordProducers, &c.Timestamps)
3✔
203
        }
3✔
204
        err = EncodeMessageExtraData(&c.ExtraData, recordProducers...)
3✔
205
        if err != nil {
3✔
206
                return err
×
207
        }
×
208

209
        return WriteBytes(w, c.ExtraData)
3✔
210
}
211

212
// MsgType returns the integer uniquely identifying this message type on the
213
// wire.
214
//
215
// This is part of the lnwire.Message interface.
216
func (c *ReplyChannelRange) MsgType() MessageType {
3✔
217
        return MsgReplyChannelRange
3✔
218
}
3✔
219

220
// LastBlockHeight returns the last block height covered by the range of a
221
// QueryChannelRange message.
222
func (c *ReplyChannelRange) LastBlockHeight() uint32 {
3✔
223
        // Handle overflows by casting to uint64.
3✔
224
        lastBlockHeight := uint64(c.FirstBlockHeight) + uint64(c.NumBlocks) - 1
3✔
225
        if lastBlockHeight > math.MaxUint32 {
3✔
226
                return math.MaxUint32
×
227
        }
×
228
        return uint32(lastBlockHeight)
3✔
229
}
230

231
// SerializedSize returns the serialized size of the message in bytes.
232
//
233
// This is part of the lnwire.SizeableMessage interface.
234
func (c *ReplyChannelRange) SerializedSize() (uint32, error) {
3✔
235
        return MessageSerializedSize(c)
3✔
236
}
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc