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

lightningnetwork / lnd / 15249422085

26 May 2025 08:11AM UTC coverage: 57.977% (-11.0%) from 69.015%
15249422085

push

github

web-flow
Merge pull request #9853 from lightningnetwork/elle-graphSQL8-prep

graph/db: init SQLStore caches and batch schedulers

9 of 34 new or added lines in 4 files covered. (26.47%)

29283 existing lines in 458 files now uncovered.

96475 of 166402 relevant lines covered (57.98%)

1.22 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 {
2✔
82
        err := ReadElements(r,
2✔
83
                c.ChainHash[:],
2✔
84
                &c.FirstBlockHeight,
2✔
85
                &c.NumBlocks,
2✔
86
                &c.Complete,
2✔
87
        )
2✔
88
        if err != nil {
2✔
UNCOV
89
                return err
×
UNCOV
90
        }
×
91

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

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

102
        var timeStamps Timestamps
2✔
103
        typeMap, err := tlvRecords.ExtractRecords(&timeStamps)
2✔
104
        if err != nil {
2✔
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 {
4✔
110
                c.Timestamps = timeStamps
2✔
111

2✔
112
                // Check that a timestamp was provided for each SCID.
2✔
113
                if len(c.Timestamps) != len(c.ShortChanIDs) {
2✔
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 {
4✔
120
                c.ExtraData = tlvRecords
2✔
121
        }
2✔
122

123
        return nil
2✔
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 {
2✔
131
        if err := WriteBytes(w, c.ChainHash[:]); err != nil {
2✔
132
                return err
×
133
        }
×
134

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

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

143
        if err := WriteUint8(w, c.Complete); err != nil {
2✔
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 {
4✔
151
                var scidPreSortIndex map[uint64]int
2✔
152
                if len(c.Timestamps) != 0 {
4✔
153
                        // Sanity check that a timestamp was provided for each
2✔
154
                        // SCID.
2✔
155
                        if len(c.Timestamps) != len(c.ShortChanIDs) {
2✔
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(
2✔
163
                                map[uint64]int, len(c.ShortChanIDs),
2✔
164
                        )
2✔
165
                        for i, scid := range c.ShortChanIDs {
4✔
166
                                scidPreSortIndex[scid.ToUint64()] = i
2✔
167
                        }
2✔
168

169
                        // Sanity check that there were no duplicates in the
170
                        // SCID list.
171
                        if len(scidPreSortIndex) != len(c.ShortChanIDs) {
2✔
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 {
4✔
179
                        return c.ShortChanIDs[i].ToUint64() <
2✔
180
                                c.ShortChanIDs[j].ToUint64()
2✔
181
                })
2✔
182

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

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

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

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

209
        return WriteBytes(w, c.ExtraData)
2✔
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 {
2✔
217
        return MsgReplyChannelRange
2✔
218
}
2✔
219

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