• 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

36.76
/graph/db/models/channel_edge_info.go
1
package models
2

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

7
        "github.com/btcsuite/btcd/btcec/v2"
8
        "github.com/btcsuite/btcd/btcutil"
9
        "github.com/btcsuite/btcd/chaincfg/chainhash"
10
        "github.com/btcsuite/btcd/wire"
11
        "github.com/lightningnetwork/lnd/fn/v2"
12
)
13

14
// ChannelEdgeInfo represents a fully authenticated channel along with all its
15
// unique attributes. Once an authenticated channel announcement has been
16
// processed on the network, then an instance of ChannelEdgeInfo encapsulating
17
// the channels attributes is stored. The other portions relevant to routing
18
// policy of a channel are stored within a ChannelEdgePolicy for each direction
19
// of the channel.
20
type ChannelEdgeInfo struct {
21
        // ChannelID is the unique channel ID for the channel. The first 3
22
        // bytes are the block height, the next 3 the index within the block,
23
        // and the last 2 bytes are the output index for the channel.
24
        ChannelID uint64
25

26
        // ChainHash is the hash that uniquely identifies the chain that this
27
        // channel was opened within.
28
        //
29
        // TODO(roasbeef): need to modify db keying for multi-chain
30
        //  * must add chain hash to prefix as well
31
        ChainHash chainhash.Hash
32

33
        // NodeKey1Bytes is the raw public key of the first node.
34
        NodeKey1Bytes [33]byte
35
        nodeKey1      *btcec.PublicKey
36

37
        // NodeKey2Bytes is the raw public key of the first node.
38
        NodeKey2Bytes [33]byte
39
        nodeKey2      *btcec.PublicKey
40

41
        // BitcoinKey1Bytes is the raw public key of the first node.
42
        BitcoinKey1Bytes [33]byte
43
        bitcoinKey1      *btcec.PublicKey
44

45
        // BitcoinKey2Bytes is the raw public key of the first node.
46
        BitcoinKey2Bytes [33]byte
47
        bitcoinKey2      *btcec.PublicKey
48

49
        // Features is an opaque byte slice that encodes the set of channel
50
        // specific features that this channel edge supports.
51
        Features []byte
52

53
        // AuthProof is the authentication proof for this channel. This proof
54
        // contains a set of signatures binding four identities, which attests
55
        // to the legitimacy of the advertised channel.
56
        AuthProof *ChannelAuthProof
57

58
        // ChannelPoint is the funding outpoint of the channel. This can be
59
        // used to uniquely identify the channel within the channel graph.
60
        ChannelPoint wire.OutPoint
61

62
        // Capacity is the total capacity of the channel, this is determined by
63
        // the value output in the outpoint that created this channel.
64
        Capacity btcutil.Amount
65

66
        // TapscriptRoot is the optional Merkle root of the tapscript tree if
67
        // this channel is a taproot channel that also commits to a tapscript
68
        // tree (custom channel).
69
        TapscriptRoot fn.Option[chainhash.Hash]
70

71
        // ExtraOpaqueData is the set of data that was appended to this
72
        // message, some of which we may not actually know how to iterate or
73
        // parse. By holding onto this data, we ensure that we're able to
74
        // properly validate the set of signatures that cover these new fields,
75
        // and ensure we're able to make upgrades to the network in a forwards
76
        // compatible manner.
77
        ExtraOpaqueData []byte
78
}
79

80
// AddNodeKeys is a setter-like method that can be used to replace the set of
81
// keys for the target ChannelEdgeInfo.
82
func (c *ChannelEdgeInfo) AddNodeKeys(nodeKey1, nodeKey2, bitcoinKey1,
UNCOV
83
        bitcoinKey2 *btcec.PublicKey) {
×
UNCOV
84

×
UNCOV
85
        c.nodeKey1 = nodeKey1
×
UNCOV
86
        copy(c.NodeKey1Bytes[:], c.nodeKey1.SerializeCompressed())
×
UNCOV
87

×
UNCOV
88
        c.nodeKey2 = nodeKey2
×
UNCOV
89
        copy(c.NodeKey2Bytes[:], nodeKey2.SerializeCompressed())
×
UNCOV
90

×
UNCOV
91
        c.bitcoinKey1 = bitcoinKey1
×
UNCOV
92
        copy(c.BitcoinKey1Bytes[:], c.bitcoinKey1.SerializeCompressed())
×
UNCOV
93

×
UNCOV
94
        c.bitcoinKey2 = bitcoinKey2
×
UNCOV
95
        copy(c.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
×
UNCOV
96
}
×
97

98
// NodeKey1 is the identity public key of the "first" node that was involved in
99
// the creation of this channel. A node is considered "first" if the
100
// lexicographical ordering the its serialized public key is "smaller" than
101
// that of the other node involved in channel creation.
102
//
103
// NOTE: By having this method to access an attribute, we ensure we only need
104
// to fully deserialize the pubkey if absolutely necessary.
105
func (c *ChannelEdgeInfo) NodeKey1() (*btcec.PublicKey, error) {
3✔
106
        if c.nodeKey1 != nil {
6✔
107
                return c.nodeKey1, nil
3✔
108
        }
3✔
109

110
        key, err := btcec.ParsePubKey(c.NodeKey1Bytes[:])
3✔
111
        if err != nil {
3✔
112
                return nil, err
×
113
        }
×
114
        c.nodeKey1 = key
3✔
115

3✔
116
        return key, nil
3✔
117
}
118

119
// NodeKey2 is the identity public key of the "second" node that was involved in
120
// the creation of this channel. A node is considered "second" if the
121
// lexicographical ordering the its serialized public key is "larger" than that
122
// of the other node involved in channel creation.
123
//
124
// NOTE: By having this method to access an attribute, we ensure we only need
125
// to fully deserialize the pubkey if absolutely necessary.
126
func (c *ChannelEdgeInfo) NodeKey2() (*btcec.PublicKey, error) {
3✔
127
        if c.nodeKey2 != nil {
6✔
128
                return c.nodeKey2, nil
3✔
129
        }
3✔
130

131
        key, err := btcec.ParsePubKey(c.NodeKey2Bytes[:])
3✔
132
        if err != nil {
3✔
133
                return nil, err
×
134
        }
×
135
        c.nodeKey2 = key
3✔
136

3✔
137
        return key, nil
3✔
138
}
139

140
// BitcoinKey1 is the Bitcoin multi-sig key belonging to the first node, that
141
// was involved in the funding transaction that originally created the channel
142
// that this struct represents.
143
//
144
// NOTE: By having this method to access an attribute, we ensure we only need
145
// to fully deserialize the pubkey if absolutely necessary.
146
func (c *ChannelEdgeInfo) BitcoinKey1() (*btcec.PublicKey, error) {
×
147
        if c.bitcoinKey1 != nil {
×
148
                return c.bitcoinKey1, nil
×
149
        }
×
150

151
        key, err := btcec.ParsePubKey(c.BitcoinKey1Bytes[:])
×
152
        if err != nil {
×
153
                return nil, err
×
154
        }
×
155
        c.bitcoinKey1 = key
×
156

×
157
        return key, nil
×
158
}
159

160
// BitcoinKey2 is the Bitcoin multi-sig key belonging to the second node, that
161
// was involved in the funding transaction that originally created the channel
162
// that this struct represents.
163
//
164
// NOTE: By having this method to access an attribute, we ensure we only need
165
// to fully deserialize the pubkey if absolutely necessary.
166
func (c *ChannelEdgeInfo) BitcoinKey2() (*btcec.PublicKey, error) {
×
167
        if c.bitcoinKey2 != nil {
×
168
                return c.bitcoinKey2, nil
×
169
        }
×
170

171
        key, err := btcec.ParsePubKey(c.BitcoinKey2Bytes[:])
×
172
        if err != nil {
×
173
                return nil, err
×
174
        }
×
175
        c.bitcoinKey2 = key
×
176

×
177
        return key, nil
×
178
}
179

180
// OtherNodeKeyBytes returns the node key bytes of the other end of the channel.
181
func (c *ChannelEdgeInfo) OtherNodeKeyBytes(thisNodeKey []byte) (
182
        [33]byte, error) {
3✔
183

3✔
184
        switch {
3✔
185
        case bytes.Equal(c.NodeKey1Bytes[:], thisNodeKey):
3✔
186
                return c.NodeKey2Bytes, nil
3✔
187
        case bytes.Equal(c.NodeKey2Bytes[:], thisNodeKey):
3✔
188
                return c.NodeKey1Bytes, nil
3✔
189
        default:
×
190
                return [33]byte{}, fmt.Errorf("node not participating in " +
×
191
                        "this channel")
×
192
        }
193
}
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