• 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

42.68
/lnwire/channel_update.go
1
package lnwire
2

3
import (
4
        "bytes"
5
        "fmt"
6
        "io"
7

8
        "github.com/btcsuite/btcd/chaincfg/chainhash"
9
)
10

11
// ChanUpdateMsgFlags is a bitfield that signals whether optional fields are
12
// present in the ChannelUpdate.
13
type ChanUpdateMsgFlags uint8
14

15
const (
16
        // ChanUpdateRequiredMaxHtlc is a bit that indicates whether the
17
        // required htlc_maximum_msat field is present in this ChannelUpdate.
18
        ChanUpdateRequiredMaxHtlc ChanUpdateMsgFlags = 1 << iota
19
)
20

21
// String returns the bitfield flags as a string.
22
func (c ChanUpdateMsgFlags) String() string {
3✔
23
        return fmt.Sprintf("%08b", c)
3✔
24
}
3✔
25

26
// HasMaxHtlc returns true if the htlc_maximum_msat option bit is set in the
27
// message flags.
28
func (c ChanUpdateMsgFlags) HasMaxHtlc() bool {
3✔
29
        return c&ChanUpdateRequiredMaxHtlc != 0
3✔
30
}
3✔
31

32
// ChanUpdateChanFlags is a bitfield that signals various options concerning a
33
// particular channel edge. Each bit is to be examined in order to determine
34
// how the ChannelUpdate message is to be interpreted.
35
type ChanUpdateChanFlags uint8
36

37
const (
38
        // ChanUpdateDirection indicates the direction of a channel update. If
39
        // this bit is set to 0 if Node1 (the node with the "smaller" Node ID)
40
        // is updating the channel, and to 1 otherwise.
41
        ChanUpdateDirection ChanUpdateChanFlags = 1 << iota
42

43
        // ChanUpdateDisabled is a bit that indicates if the channel edge
44
        // selected by the ChanUpdateDirection bit is to be treated as being
45
        // disabled.
46
        ChanUpdateDisabled
47
)
48

49
// IsDisabled determines whether the channel flags has the disabled bit set.
50
func (c ChanUpdateChanFlags) IsDisabled() bool {
3✔
51
        return c&ChanUpdateDisabled == ChanUpdateDisabled
3✔
52
}
3✔
53

54
// String returns the bitfield flags as a string.
55
func (c ChanUpdateChanFlags) String() string {
3✔
56
        return fmt.Sprintf("%08b", c)
3✔
57
}
3✔
58

59
// ChannelUpdate1 message is used after channel has been initially announced.
60
// Each side independently announces its fees and minimum expiry for HTLCs and
61
// other parameters. Also this message is used to redeclare initially set
62
// channel parameters.
63
type ChannelUpdate1 struct {
64
        // Signature is used to validate the announced data and prove the
65
        // ownership of node id.
66
        Signature Sig
67

68
        // ChainHash denotes the target chain that this channel was opened
69
        // within. This value should be the genesis hash of the target chain.
70
        // Along with the short channel ID, this uniquely identifies the
71
        // channel globally in a blockchain.
72
        ChainHash chainhash.Hash
73

74
        // ShortChannelID is the unique description of the funding transaction.
75
        ShortChannelID ShortChannelID
76

77
        // Timestamp allows ordering in the case of multiple announcements. We
78
        // should ignore the message if timestamp is not greater than
79
        // the last-received.
80
        Timestamp uint32
81

82
        // MessageFlags is a bitfield that describes whether optional fields
83
        // are present in this update. Currently, the least-significant bit
84
        // must be set to 1 if the optional field MaxHtlc is present.
85
        MessageFlags ChanUpdateMsgFlags
86

87
        // ChannelFlags is a bitfield that describes additional meta-data
88
        // concerning how the update is to be interpreted. Currently, the
89
        // least-significant bit must be set to 0 if the creating node
90
        // corresponds to the first node in the previously sent channel
91
        // announcement and 1 otherwise. If the second bit is set, then the
92
        // channel is set to be disabled.
93
        ChannelFlags ChanUpdateChanFlags
94

95
        // TimeLockDelta is the minimum number of blocks this node requires to
96
        // be added to the expiry of HTLCs. This is a security parameter
97
        // determined by the node operator. This value represents the required
98
        // gap between the time locks of the incoming and outgoing HTLC's set
99
        // to this node.
100
        TimeLockDelta uint16
101

102
        // HtlcMinimumMsat is the minimum HTLC value which will be accepted.
103
        HtlcMinimumMsat MilliSatoshi
104

105
        // BaseFee is the base fee that must be used for incoming HTLC's to
106
        // this particular channel. This value will be tacked onto the required
107
        // for a payment independent of the size of the payment.
108
        BaseFee uint32
109

110
        // FeeRate is the fee rate that will be charged per millionth of a
111
        // satoshi.
112
        FeeRate uint32
113

114
        // HtlcMaximumMsat is the maximum HTLC value which will be accepted.
115
        HtlcMaximumMsat MilliSatoshi
116

117
        // ExtraData is the set of data that was appended to this message to
118
        // fill out the full maximum transport message size. These fields can
119
        // be used to specify optional data such as custom TLV fields.
120
        ExtraOpaqueData ExtraOpaqueData
121
}
122

123
// A compile time check to ensure ChannelUpdate implements the lnwire.Message
124
// interface.
125
var _ Message = (*ChannelUpdate1)(nil)
126

127
// A compile time check to ensure ChannelUpdate1 implements the
128
// lnwire.SizeableMessage interface.
129
var _ SizeableMessage = (*ChannelUpdate1)(nil)
130

131
// Decode deserializes a serialized ChannelUpdate stored in the passed
132
// io.Reader observing the specified protocol version.
133
//
134
// This is part of the lnwire.Message interface.
135
func (a *ChannelUpdate1) Decode(r io.Reader, _ uint32) error {
3✔
136
        err := ReadElements(r,
3✔
137
                &a.Signature,
3✔
138
                a.ChainHash[:],
3✔
139
                &a.ShortChannelID,
3✔
140
                &a.Timestamp,
3✔
141
                &a.MessageFlags,
3✔
142
                &a.ChannelFlags,
3✔
143
                &a.TimeLockDelta,
3✔
144
                &a.HtlcMinimumMsat,
3✔
145
                &a.BaseFee,
3✔
146
                &a.FeeRate,
3✔
147
        )
3✔
148
        if err != nil {
3✔
UNCOV
149
                return err
×
UNCOV
150
        }
×
151

152
        // Now check whether the max HTLC field is present and read it if so.
153
        if a.MessageFlags.HasMaxHtlc() {
6✔
154
                if err := ReadElements(r, &a.HtlcMaximumMsat); err != nil {
3✔
UNCOV
155
                        return err
×
UNCOV
156
                }
×
157
        }
158

159
        err = a.ExtraOpaqueData.Decode(r)
3✔
160
        if err != nil {
3✔
161
                return err
×
162
        }
×
163

164
        return a.ExtraOpaqueData.ValidateTLV()
3✔
165
}
166

167
// Encode serializes the target ChannelUpdate into the passed io.Writer
168
// observing the protocol version specified.
169
//
170
// This is part of the lnwire.Message interface.
171
func (a *ChannelUpdate1) Encode(w *bytes.Buffer, pver uint32) error {
3✔
172
        if err := WriteSig(w, a.Signature); err != nil {
3✔
173
                return err
×
174
        }
×
175

176
        if err := WriteBytes(w, a.ChainHash[:]); err != nil {
3✔
177
                return err
×
178
        }
×
179

180
        if err := WriteShortChannelID(w, a.ShortChannelID); err != nil {
3✔
181
                return err
×
182
        }
×
183

184
        if err := WriteUint32(w, a.Timestamp); err != nil {
3✔
185
                return err
×
186
        }
×
187

188
        if err := WriteChanUpdateMsgFlags(w, a.MessageFlags); err != nil {
3✔
189
                return err
×
190
        }
×
191

192
        if err := WriteChanUpdateChanFlags(w, a.ChannelFlags); err != nil {
3✔
193
                return err
×
194
        }
×
195

196
        if err := WriteUint16(w, a.TimeLockDelta); err != nil {
3✔
197
                return err
×
198
        }
×
199

200
        if err := WriteMilliSatoshi(w, a.HtlcMinimumMsat); err != nil {
3✔
201
                return err
×
202
        }
×
203

204
        if err := WriteUint32(w, a.BaseFee); err != nil {
3✔
205
                return err
×
206
        }
×
207

208
        if err := WriteUint32(w, a.FeeRate); err != nil {
3✔
209
                return err
×
210
        }
×
211

212
        // Now append optional fields if they are set. Currently, the only
213
        // optional field is max HTLC.
214
        if a.MessageFlags.HasMaxHtlc() {
6✔
215
                err := WriteMilliSatoshi(w, a.HtlcMaximumMsat)
3✔
216
                if err != nil {
3✔
217
                        return err
×
218
                }
×
219
        }
220

221
        // Finally, append any extra opaque data.
222
        return WriteBytes(w, a.ExtraOpaqueData)
3✔
223
}
224

225
// MsgType returns the integer uniquely identifying this message type on the
226
// wire.
227
//
228
// This is part of the lnwire.Message interface.
229
func (a *ChannelUpdate1) MsgType() MessageType {
3✔
230
        return MsgChannelUpdate
3✔
231
}
3✔
232

233
// DataToSign is used to retrieve part of the announcement message which should
234
// be signed.
235
func (a *ChannelUpdate1) DataToSign() ([]byte, error) {
3✔
236
        // We should not include the signatures itself.
3✔
237
        b := make([]byte, 0, MaxMsgBody)
3✔
238
        buf := bytes.NewBuffer(b)
3✔
239
        if err := WriteBytes(buf, a.ChainHash[:]); err != nil {
3✔
240
                return nil, err
×
241
        }
×
242

243
        if err := WriteShortChannelID(buf, a.ShortChannelID); err != nil {
3✔
244
                return nil, err
×
245
        }
×
246

247
        if err := WriteUint32(buf, a.Timestamp); err != nil {
3✔
248
                return nil, err
×
249
        }
×
250

251
        if err := WriteChanUpdateMsgFlags(buf, a.MessageFlags); err != nil {
3✔
252
                return nil, err
×
253
        }
×
254

255
        if err := WriteChanUpdateChanFlags(buf, a.ChannelFlags); err != nil {
3✔
256
                return nil, err
×
257
        }
×
258

259
        if err := WriteUint16(buf, a.TimeLockDelta); err != nil {
3✔
260
                return nil, err
×
261
        }
×
262

263
        if err := WriteMilliSatoshi(buf, a.HtlcMinimumMsat); err != nil {
3✔
264
                return nil, err
×
265
        }
×
266

267
        if err := WriteUint32(buf, a.BaseFee); err != nil {
3✔
268
                return nil, err
×
269
        }
×
270

271
        if err := WriteUint32(buf, a.FeeRate); err != nil {
3✔
272
                return nil, err
×
273
        }
×
274

275
        // Now append optional fields if they are set. Currently, the only
276
        // optional field is max HTLC.
277
        if a.MessageFlags.HasMaxHtlc() {
6✔
278
                err := WriteMilliSatoshi(buf, a.HtlcMaximumMsat)
3✔
279
                if err != nil {
3✔
280
                        return nil, err
×
281
                }
×
282
        }
283

284
        // Finally, append any extra opaque data.
285
        if err := WriteBytes(buf, a.ExtraOpaqueData); err != nil {
3✔
286
                return nil, err
×
287
        }
×
288

289
        return buf.Bytes(), nil
3✔
290
}
291

292
// SCID returns the ShortChannelID of the channel that the update applies to.
293
//
294
// NOTE: this is part of the ChannelUpdate interface.
295
func (a *ChannelUpdate1) SCID() ShortChannelID {
×
296
        return a.ShortChannelID
×
297
}
×
298

299
// IsNode1 is true if the update was produced by node 1 of the channel peers.
300
// Node 1 is the node with the lexicographically smaller public key.
301
//
302
// NOTE: this is part of the ChannelUpdate interface.
303
func (a *ChannelUpdate1) IsNode1() bool {
×
304
        return a.ChannelFlags&ChanUpdateDirection == 0
×
305
}
×
306

307
// IsDisabled is true if the update is announcing that the channel should be
308
// considered disabled.
309
//
310
// NOTE: this is part of the ChannelUpdate interface.
311
func (a *ChannelUpdate1) IsDisabled() bool {
×
312
        return a.ChannelFlags&ChanUpdateDisabled == ChanUpdateDisabled
×
313
}
×
314

315
// GetChainHash returns the hash of the chain that the message is referring to.
316
//
317
// NOTE: this is part of the ChannelUpdate interface.
318
func (a *ChannelUpdate1) GetChainHash() chainhash.Hash {
×
319
        return a.ChainHash
×
320
}
×
321

322
// ForwardingPolicy returns the set of forwarding constraints of the update.
323
//
324
// NOTE: this is part of the ChannelUpdate interface.
325
func (a *ChannelUpdate1) ForwardingPolicy() *ForwardingPolicy {
×
326
        return &ForwardingPolicy{
×
327
                TimeLockDelta: a.TimeLockDelta,
×
328
                BaseFee:       MilliSatoshi(a.BaseFee),
×
329
                FeeRate:       MilliSatoshi(a.FeeRate),
×
330
                MinHTLC:       a.HtlcMinimumMsat,
×
331
                HasMaxHTLC:    a.MessageFlags.HasMaxHtlc(),
×
332
                MaxHTLC:       a.HtlcMaximumMsat,
×
333
        }
×
334
}
×
335

336
// CmpAge can be used to determine if the update is older or newer than the
337
// passed update. It returns 1 if this update is newer, -1 if it is older, and
338
// 0 if they are the same age.
339
//
340
// NOTE: this is part of the ChannelUpdate interface.
341
func (a *ChannelUpdate1) CmpAge(update ChannelUpdate) (CompareResult, error) {
×
342
        other, ok := update.(*ChannelUpdate1)
×
343
        if !ok {
×
344
                return 0, fmt.Errorf("expected *ChannelUpdate1, got: %T",
×
345
                        update)
×
346
        }
×
347

348
        switch {
×
349
        case a.Timestamp > other.Timestamp:
×
350
                return GreaterThan, nil
×
351
        case a.Timestamp < other.Timestamp:
×
352
                return LessThan, nil
×
353
        default:
×
354
                return EqualTo, nil
×
355
        }
356
}
357

358
// SetDisabledFlag can be used to adjust the disabled flag of an update.
359
//
360
// NOTE: this is part of the ChannelUpdate interface.
361
func (a *ChannelUpdate1) SetDisabledFlag(disabled bool) {
×
362
        if disabled {
×
363
                a.ChannelFlags |= ChanUpdateDisabled
×
364
        } else {
×
365
                a.ChannelFlags &= ^ChanUpdateDisabled
×
366
        }
×
367
}
368

369
// SetSCID can be used to overwrite the SCID of the update.
370
//
371
// NOTE: this is part of the ChannelUpdate interface.
372
func (a *ChannelUpdate1) SetSCID(scid ShortChannelID) {
×
373
        a.ShortChannelID = scid
×
374
}
×
375

376
// A compile time assertion to ensure ChannelUpdate1 implements the
377
// ChannelUpdate interface.
378
var _ ChannelUpdate = (*ChannelUpdate1)(nil)
379

380
// SerializedSize returns the serialized size of the message in bytes.
381
//
382
// This is part of the lnwire.SizeableMessage interface.
383
func (a *ChannelUpdate1) SerializedSize() (uint32, error) {
3✔
384
        return MessageSerializedSize(a)
3✔
385
}
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