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

lightningnetwork / lnd / 9915780197

13 Jul 2024 12:30AM UTC coverage: 49.268% (-9.1%) from 58.413%
9915780197

push

github

web-flow
Merge pull request #8653 from ProofOfKeags/fn-prim

DynComms [0/n]: `fn` package additions

92837 of 188433 relevant lines covered (49.27%)

1.55 hits per line

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

54.03
/routing/ann_validation.go
1
package routing
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/davecgh/go-spew/spew"
11
        "github.com/go-errors/errors"
12
        "github.com/lightningnetwork/lnd/lnwire"
13
)
14

15
// ValidateChannelAnn validates the channel announcement message and checks
16
// that node signatures covers the announcement message, and that the bitcoin
17
// signatures covers the node keys.
18
func ValidateChannelAnn(a *lnwire.ChannelAnnouncement) error {
3✔
19
        // First, we'll compute the digest (h) which is to be signed by each of
3✔
20
        // the keys included within the node announcement message. This hash
3✔
21
        // digest includes all the keys, so the (up to 4 signatures) will
3✔
22
        // attest to the validity of each of the keys.
3✔
23
        data, err := a.DataToSign()
3✔
24
        if err != nil {
3✔
25
                return err
×
26
        }
×
27
        dataHash := chainhash.DoubleHashB(data)
3✔
28

3✔
29
        // First we'll verify that the passed bitcoin key signature is indeed a
3✔
30
        // signature over the computed hash digest.
3✔
31
        bitcoinSig1, err := a.BitcoinSig1.ToSignature()
3✔
32
        if err != nil {
3✔
33
                return err
×
34
        }
×
35
        bitcoinKey1, err := btcec.ParsePubKey(a.BitcoinKey1[:])
3✔
36
        if err != nil {
3✔
37
                return err
×
38
        }
×
39
        if !bitcoinSig1.Verify(dataHash, bitcoinKey1) {
3✔
40
                return errors.New("can't verify first bitcoin signature")
×
41
        }
×
42

43
        // If that checks out, then we'll verify that the second bitcoin
44
        // signature is a valid signature of the bitcoin public key over hash
45
        // digest as well.
46
        bitcoinSig2, err := a.BitcoinSig2.ToSignature()
3✔
47
        if err != nil {
3✔
48
                return err
×
49
        }
×
50
        bitcoinKey2, err := btcec.ParsePubKey(a.BitcoinKey2[:])
3✔
51
        if err != nil {
3✔
52
                return err
×
53
        }
×
54
        if !bitcoinSig2.Verify(dataHash, bitcoinKey2) {
3✔
55
                return errors.New("can't verify second bitcoin signature")
×
56
        }
×
57

58
        // Both node signatures attached should indeed be a valid signature
59
        // over the selected digest of the channel announcement signature.
60
        nodeSig1, err := a.NodeSig1.ToSignature()
3✔
61
        if err != nil {
3✔
62
                return err
×
63
        }
×
64
        nodeKey1, err := btcec.ParsePubKey(a.NodeID1[:])
3✔
65
        if err != nil {
3✔
66
                return err
×
67
        }
×
68
        if !nodeSig1.Verify(dataHash, nodeKey1) {
3✔
69
                return errors.New("can't verify data in first node signature")
×
70
        }
×
71

72
        nodeSig2, err := a.NodeSig2.ToSignature()
3✔
73
        if err != nil {
3✔
74
                return err
×
75
        }
×
76
        nodeKey2, err := btcec.ParsePubKey(a.NodeID2[:])
3✔
77
        if err != nil {
3✔
78
                return err
×
79
        }
×
80
        if !nodeSig2.Verify(dataHash, nodeKey2) {
3✔
81
                return errors.New("can't verify data in second node signature")
×
82
        }
×
83

84
        return nil
3✔
85

86
}
87

88
// ValidateNodeAnn validates the node announcement by ensuring that the
89
// attached signature is needed a signature of the node announcement under the
90
// specified node public key.
91
func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error {
3✔
92
        // Reconstruct the data of announcement which should be covered by the
3✔
93
        // signature so we can verify the signature shortly below
3✔
94
        data, err := a.DataToSign()
3✔
95
        if err != nil {
3✔
96
                return err
×
97
        }
×
98

99
        nodeSig, err := a.Signature.ToSignature()
3✔
100
        if err != nil {
3✔
101
                return err
×
102
        }
×
103
        nodeKey, err := btcec.ParsePubKey(a.NodeID[:])
3✔
104
        if err != nil {
3✔
105
                return err
×
106
        }
×
107

108
        // Finally ensure that the passed signature is valid, if not we'll
109
        // return an error so this node announcement can be rejected.
110
        dataHash := chainhash.DoubleHashB(data)
3✔
111
        if !nodeSig.Verify(dataHash, nodeKey) {
3✔
112
                var msgBuf bytes.Buffer
×
113
                if _, err := lnwire.WriteMessage(&msgBuf, a, 0); err != nil {
×
114
                        return err
×
115
                }
×
116

117
                return errors.Errorf("signature on NodeAnnouncement(%x) is "+
×
118
                        "invalid: %x", nodeKey.SerializeCompressed(),
×
119
                        msgBuf.Bytes())
×
120
        }
121

122
        return nil
3✔
123
}
124

125
// ValidateChannelUpdateAnn validates the channel update announcement by
126
// checking (1) that the included signature covers the announcement and has been
127
// signed by the node's private key, and (2) that the announcement's message
128
// flags and optional fields are sane.
129
func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey, capacity btcutil.Amount,
130
        a *lnwire.ChannelUpdate) error {
3✔
131

3✔
132
        if err := ValidateChannelUpdateFields(capacity, a); err != nil {
3✔
133
                return err
×
134
        }
×
135

136
        return VerifyChannelUpdateSignature(a, pubKey)
3✔
137
}
138

139
// VerifyChannelUpdateSignature verifies that the channel update message was
140
// signed by the party with the given node public key.
141
func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate,
142
        pubKey *btcec.PublicKey) error {
3✔
143

3✔
144
        data, err := msg.DataToSign()
3✔
145
        if err != nil {
3✔
146
                return fmt.Errorf("unable to reconstruct message data: %w", err)
×
147
        }
×
148
        dataHash := chainhash.DoubleHashB(data)
3✔
149

3✔
150
        nodeSig, err := msg.Signature.ToSignature()
3✔
151
        if err != nil {
3✔
152
                return err
×
153
        }
×
154

155
        if !nodeSig.Verify(dataHash, pubKey) {
3✔
156
                return fmt.Errorf("invalid signature for channel update %v",
×
157
                        spew.Sdump(msg))
×
158
        }
×
159

160
        return nil
3✔
161
}
162

163
// ValidateChannelUpdateFields validates a channel update's message flags and
164
// corresponding update fields.
165
func ValidateChannelUpdateFields(capacity btcutil.Amount,
166
        msg *lnwire.ChannelUpdate) error {
3✔
167

3✔
168
        // The maxHTLC flag is mandatory.
3✔
169
        if !msg.MessageFlags.HasMaxHtlc() {
3✔
170
                return errors.Errorf("max htlc flag not set for channel "+
×
171
                        "update %v", spew.Sdump(msg))
×
172
        }
×
173

174
        maxHtlc := msg.HtlcMaximumMsat
3✔
175
        if maxHtlc == 0 || maxHtlc < msg.HtlcMinimumMsat {
3✔
176
                return errors.Errorf("invalid max htlc for channel "+
×
177
                        "update %v", spew.Sdump(msg))
×
178
        }
×
179

180
        // For light clients, the capacity will not be set so we'll skip
181
        // checking whether the MaxHTLC value respects the channel's
182
        // capacity.
183
        capacityMsat := lnwire.NewMSatFromSatoshis(capacity)
3✔
184
        if capacityMsat != 0 && maxHtlc > capacityMsat {
3✔
185
                return errors.Errorf("max_htlc (%v) for channel update "+
×
186
                        "greater than capacity (%v)", maxHtlc, capacityMsat)
×
187
        }
×
188

189
        return nil
3✔
190
}
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