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

lightningnetwork / lnd / 13211764208

08 Feb 2025 03:08AM UTC coverage: 49.288% (-9.5%) from 58.815%
13211764208

Pull #9489

github

calvinrzachman
itest: verify switchrpc server enforces send then track

We prevent the rpc server from allowing onion dispatches for
attempt IDs which have already been tracked by rpc clients.

This helps protect the client from leaking a duplicate onion
attempt. NOTE: This is not the only method for solving this
issue! The issue could be addressed via careful client side
programming which accounts for the uncertainty and async
nature of dispatching onions to a remote process via RPC.
This would require some lnd ChannelRouter changes for how
we intend to use these RPCs though.
Pull Request #9489: multi: add BuildOnion, SendOnion, and TrackOnion RPCs

474 of 990 new or added lines in 11 files covered. (47.88%)

27321 existing lines in 435 files now uncovered.

101192 of 205306 relevant lines covered (49.29%)

1.54 hits per line

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

64.06
/lnwire/query_channel_range.go
1
package lnwire
2

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

8
        "github.com/btcsuite/btcd/chaincfg/chainhash"
9
        "github.com/lightningnetwork/lnd/tlv"
10
)
11

12
// QueryChannelRange is a message sent by a node in order to query the
13
// receiving node of the set of open channel they know of with short channel
14
// ID's after the specified block height, capped at the number of blocks beyond
15
// that block height. This will be used by nodes upon initial connect to
16
// synchronize their views of the network.
17
type QueryChannelRange struct {
18
        // ChainHash denotes the target chain that we're trying to synchronize
19
        // channel graph state for.
20
        ChainHash chainhash.Hash
21

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

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

31
        // QueryOptions is an optional feature bit vector that can be used to
32
        // specify additional query options.
33
        QueryOptions *QueryOptions
34

35
        // ExtraData is the set of data that was appended to this message to
36
        // fill out the full maximum transport message size. These fields can
37
        // be used to specify optional data such as custom TLV fields.
38
        ExtraData ExtraOpaqueData
39
}
40

41
// NewQueryChannelRange creates a new empty QueryChannelRange message.
42
func NewQueryChannelRange() *QueryChannelRange {
×
43
        return &QueryChannelRange{
×
44
                ExtraData: make([]byte, 0),
×
45
        }
×
46
}
×
47

48
// A compile time check to ensure QueryChannelRange implements the
49
// lnwire.Message interface.
50
var _ Message = (*QueryChannelRange)(nil)
51

52
// Decode deserializes a serialized QueryChannelRange message stored in the
53
// passed io.Reader observing the specified protocol version.
54
//
55
// This is part of the lnwire.Message interface.
56
func (q *QueryChannelRange) Decode(r io.Reader, _ uint32) error {
3✔
57
        err := ReadElements(
3✔
58
                r, q.ChainHash[:], &q.FirstBlockHeight, &q.NumBlocks,
3✔
59
        )
3✔
60
        if err != nil {
3✔
UNCOV
61
                return err
×
UNCOV
62
        }
×
63

64
        var tlvRecords ExtraOpaqueData
3✔
65
        if err := ReadElements(r, &tlvRecords); err != nil {
3✔
66
                return err
×
67
        }
×
68

69
        var queryOptions QueryOptions
3✔
70
        typeMap, err := tlvRecords.ExtractRecords(&queryOptions)
3✔
71
        if err != nil {
3✔
UNCOV
72
                return err
×
UNCOV
73
        }
×
74

75
        // Set the corresponding TLV types if they were included in the stream.
76
        if val, ok := typeMap[QueryOptionsRecordType]; ok && val == nil {
6✔
77
                q.QueryOptions = &queryOptions
3✔
78
        }
3✔
79

80
        if len(tlvRecords) != 0 {
6✔
81
                q.ExtraData = tlvRecords
3✔
82
        }
3✔
83

84
        return nil
3✔
85
}
86

87
// Encode serializes the target QueryChannelRange into the passed io.Writer
88
// observing the protocol version specified.
89
//
90
// This is part of the lnwire.Message interface.
91
func (q *QueryChannelRange) Encode(w *bytes.Buffer, _ uint32) error {
3✔
92
        if err := WriteBytes(w, q.ChainHash[:]); err != nil {
3✔
93
                return err
×
94
        }
×
95

96
        if err := WriteUint32(w, q.FirstBlockHeight); err != nil {
3✔
97
                return err
×
98
        }
×
99

100
        if err := WriteUint32(w, q.NumBlocks); err != nil {
3✔
101
                return err
×
102
        }
×
103

104
        recordProducers := make([]tlv.RecordProducer, 0, 1)
3✔
105
        if q.QueryOptions != nil {
6✔
106
                recordProducers = append(recordProducers, q.QueryOptions)
3✔
107
        }
3✔
108
        err := EncodeMessageExtraData(&q.ExtraData, recordProducers...)
3✔
109
        if err != nil {
3✔
110
                return err
×
111
        }
×
112

113
        return WriteBytes(w, q.ExtraData)
3✔
114
}
115

116
// MsgType returns the integer uniquely identifying this message type on the
117
// wire.
118
//
119
// This is part of the lnwire.Message interface.
120
func (q *QueryChannelRange) MsgType() MessageType {
3✔
121
        return MsgQueryChannelRange
3✔
122
}
3✔
123

124
// LastBlockHeight returns the last block height covered by the range of a
125
// QueryChannelRange message.
126
func (q *QueryChannelRange) LastBlockHeight() uint32 {
3✔
127
        // Handle overflows by casting to uint64.
3✔
128
        lastBlockHeight := uint64(q.FirstBlockHeight) + uint64(q.NumBlocks) - 1
3✔
129
        if lastBlockHeight > math.MaxUint32 {
3✔
UNCOV
130
                return math.MaxUint32
×
UNCOV
131
        }
×
132
        return uint32(lastBlockHeight)
3✔
133
}
134

135
// WithTimestamps returns true if the query has asked for timestamps too.
136
func (q *QueryChannelRange) WithTimestamps() bool {
3✔
137
        if q.QueryOptions == nil {
3✔
UNCOV
138
                return false
×
UNCOV
139
        }
×
140

141
        queryOpts := RawFeatureVector(*q.QueryOptions)
3✔
142

3✔
143
        return queryOpts.IsSet(QueryOptionTimestampBit)
3✔
144
}
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