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

lightningnetwork / lnd / 12199391122

06 Dec 2024 01:10PM UTC coverage: 49.807% (-9.1%) from 58.933%
12199391122

push

github

web-flow
Merge pull request #9337 from Guayaba221/patch-1

chore: fix typo in ruby.md

100137 of 201051 relevant lines covered (49.81%)

2.07 hits per line

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

66.67
/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.
63
func NewReplyChannelRange() *ReplyChannelRange {
×
64
        return &ReplyChannelRange{
×
65
                ExtraData: make([]byte, 0),
×
66
        }
×
67
}
×
68

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

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

88
        c.EncodingType, c.ShortChanIDs, err = decodeShortChanIDs(r)
4✔
89
        if err != nil {
4✔
90
                return err
×
91
        }
×
92

93
        var tlvRecords ExtraOpaqueData
4✔
94
        if err := ReadElements(r, &tlvRecords); err != nil {
4✔
95
                return err
×
96
        }
×
97

98
        var timeStamps Timestamps
4✔
99
        typeMap, err := tlvRecords.ExtractRecords(&timeStamps)
4✔
100
        if err != nil {
4✔
101
                return err
×
102
        }
×
103

104
        // Set the corresponding TLV types if they were included in the stream.
105
        if val, ok := typeMap[TimestampsRecordType]; ok && val == nil {
8✔
106
                c.Timestamps = timeStamps
4✔
107

4✔
108
                // Check that a timestamp was provided for each SCID.
4✔
109
                if len(c.Timestamps) != len(c.ShortChanIDs) {
4✔
110
                        return fmt.Errorf("number of timestamps does not " +
×
111
                                "match number of SCIDs")
×
112
                }
×
113
        }
114

115
        if len(tlvRecords) != 0 {
8✔
116
                c.ExtraData = tlvRecords
4✔
117
        }
4✔
118

119
        return nil
4✔
120
}
121

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

131
        if err := WriteUint32(w, c.FirstBlockHeight); err != nil {
4✔
132
                return err
×
133
        }
×
134

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

139
        if err := WriteUint8(w, c.Complete); err != nil {
4✔
140
                return err
×
141
        }
×
142

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

156
                        // Create a map from SCID value to the original index of
157
                        // the SCID in the unsorted list.
158
                        scidPreSortIndex = make(
4✔
159
                                map[uint64]int, len(c.ShortChanIDs),
4✔
160
                        )
4✔
161
                        for i, scid := range c.ShortChanIDs {
8✔
162
                                scidPreSortIndex[scid.ToUint64()] = i
4✔
163
                        }
4✔
164

165
                        // Sanity check that there were no duplicates in the
166
                        // SCID list.
167
                        if len(scidPreSortIndex) != len(c.ShortChanIDs) {
4✔
168
                                return fmt.Errorf("scid list should not " +
×
169
                                        "contain duplicates")
×
170
                        }
×
171
                }
172

173
                // Now sort the SCIDs.
174
                sort.Slice(c.ShortChanIDs, func(i, j int) bool {
8✔
175
                        return c.ShortChanIDs[i].ToUint64() <
4✔
176
                                c.ShortChanIDs[j].ToUint64()
4✔
177
                })
4✔
178

179
                if len(c.Timestamps) != 0 {
8✔
180
                        timestamps := make(Timestamps, len(c.Timestamps))
4✔
181

4✔
182
                        for i, scid := range c.ShortChanIDs {
8✔
183
                                timestamps[i] = []ChanUpdateTimestamps(
4✔
184
                                        c.Timestamps,
4✔
185
                                )[scidPreSortIndex[scid.ToUint64()]]
4✔
186
                        }
4✔
187
                        c.Timestamps = timestamps
4✔
188
                }
189
        }
190

191
        err := encodeShortChanIDs(w, c.EncodingType, c.ShortChanIDs)
4✔
192
        if err != nil {
4✔
193
                return err
×
194
        }
×
195

196
        recordProducers := make([]tlv.RecordProducer, 0, 1)
4✔
197
        if len(c.Timestamps) != 0 {
8✔
198
                recordProducers = append(recordProducers, &c.Timestamps)
4✔
199
        }
4✔
200
        err = EncodeMessageExtraData(&c.ExtraData, recordProducers...)
4✔
201
        if err != nil {
4✔
202
                return err
×
203
        }
×
204

205
        return WriteBytes(w, c.ExtraData)
4✔
206
}
207

208
// MsgType returns the integer uniquely identifying this message type on the
209
// wire.
210
//
211
// This is part of the lnwire.Message interface.
212
func (c *ReplyChannelRange) MsgType() MessageType {
4✔
213
        return MsgReplyChannelRange
4✔
214
}
4✔
215

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