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

lightningnetwork / lnd / 13035292482

29 Jan 2025 03:59PM UTC coverage: 49.3% (-9.5%) from 58.777%
13035292482

Pull #9456

github

mohamedawnallah
docs: update release-notes-0.19.0.md

In this commit, we warn users about the removal
of RPCs `SendToRoute`, `SendToRouteSync`, `SendPayment`,
and `SendPaymentSync` in the next release 0.20.
Pull Request #9456: lnrpc+docs: deprecate warning `SendToRoute`, `SendToRouteSync`, `SendPayment`, and `SendPaymentSync` in Release 0.19

100634 of 204126 relevant lines covered (49.3%)

1.54 hits per line

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

55.88
/zpay32/blinded_path.go
1
package zpay32
2

3
import (
4
        "encoding/binary"
5
        "fmt"
6
        "io"
7

8
        "github.com/btcsuite/btcd/btcec/v2"
9
        sphinx "github.com/lightningnetwork/lightning-onion"
10
        "github.com/lightningnetwork/lnd/lnwire"
11
        "github.com/lightningnetwork/lnd/tlv"
12
)
13

14
const (
15
        // maxNumHopsPerPath is the maximum number of blinded path hops that can
16
        // be included in a single encoded blinded path. This is calculated
17
        // based on the `data_length` limit of 638 bytes for any tagged field in
18
        // a BOLT 11 invoice along with the estimated number of bytes required
19
        // for encoding the most minimal blinded path hop. See the [bLIP
20
        // proposal](https://github.com/lightning/blips/pull/39) for a detailed
21
        // calculation.
22
        maxNumHopsPerPath = 7
23

24
        // maxCipherTextLength defines the largest cipher text size allowed.
25
        // This is derived by using the `data_length` upper bound of 639 bytes
26
        // and then assuming the case of a path with only a single hop (meaning
27
        // the cipher text may be as large as possible).
28
        maxCipherTextLength = 535
29
)
30

31
var (
32
        // byteOrder defines the endian-ness we use for encoding to and from
33
        // buffers.
34
        byteOrder = binary.BigEndian
35
)
36

37
// BlindedPaymentPath holds all the information a payer needs to know about a
38
// blinded path to a receiver of a payment.
39
type BlindedPaymentPath struct {
40
        // FeeBaseMsat is the total base fee for the path in milli-satoshis.
41
        FeeBaseMsat uint32
42

43
        // FeeRate is the total fee rate for the path in parts per million.
44
        FeeRate uint32
45

46
        // CltvExpiryDelta is the total CLTV delta to apply to the path.
47
        CltvExpiryDelta uint16
48

49
        // HTLCMinMsat is the minimum number of milli-satoshis that any hop in
50
        // the path will route.
51
        HTLCMinMsat uint64
52

53
        // HTLCMaxMsat is the maximum number of milli-satoshis that a hop in the
54
        // path will route.
55
        HTLCMaxMsat uint64
56

57
        // Features is the feature bit vector for the path.
58
        Features *lnwire.FeatureVector
59

60
        // FirstEphemeralBlindingPoint is the blinding point to send to the
61
        // introduction node. It will be used by the introduction node to derive
62
        // a shared secret with the receiver which can then be used to decode
63
        // the encrypted payload from the receiver.
64
        FirstEphemeralBlindingPoint *btcec.PublicKey
65

66
        // Hops is the blinded path. The first hop is the introduction node and
67
        // so the BlindedNodeID of this hop will be the real node ID.
68
        Hops []*sphinx.BlindedHopInfo
69
}
70

71
// DecodeBlindedPayment attempts to parse a BlindedPaymentPath from the passed
72
// reader.
73
func DecodeBlindedPayment(r io.Reader) (*BlindedPaymentPath, error) {
3✔
74
        var payment BlindedPaymentPath
3✔
75

3✔
76
        if err := binary.Read(r, byteOrder, &payment.FeeBaseMsat); err != nil {
3✔
77
                return nil, err
×
78
        }
×
79

80
        if err := binary.Read(r, byteOrder, &payment.FeeRate); err != nil {
3✔
81
                return nil, err
×
82
        }
×
83

84
        err := binary.Read(r, byteOrder, &payment.CltvExpiryDelta)
3✔
85
        if err != nil {
3✔
86
                return nil, err
×
87
        }
×
88

89
        err = binary.Read(r, byteOrder, &payment.HTLCMinMsat)
3✔
90
        if err != nil {
3✔
91
                return nil, err
×
92
        }
×
93

94
        err = binary.Read(r, byteOrder, &payment.HTLCMaxMsat)
3✔
95
        if err != nil {
3✔
96
                return nil, err
×
97
        }
×
98

99
        // Parse the feature bit vector.
100
        f := lnwire.EmptyFeatureVector()
3✔
101
        err = f.Decode(r)
3✔
102
        if err != nil {
3✔
103
                return nil, err
×
104
        }
×
105
        payment.Features = f
3✔
106

3✔
107
        // Parse the first ephemeral blinding point.
3✔
108
        var blindingPointBytes [btcec.PubKeyBytesLenCompressed]byte
3✔
109
        _, err = r.Read(blindingPointBytes[:])
3✔
110
        if err != nil {
3✔
111
                return nil, err
×
112
        }
×
113

114
        blinding, err := btcec.ParsePubKey(blindingPointBytes[:])
3✔
115
        if err != nil {
3✔
116
                return nil, err
×
117
        }
×
118
        payment.FirstEphemeralBlindingPoint = blinding
3✔
119

3✔
120
        // Read the one byte hop number.
3✔
121
        var numHops [1]byte
3✔
122
        _, err = r.Read(numHops[:])
3✔
123
        if err != nil {
3✔
124
                return nil, err
×
125
        }
×
126

127
        payment.Hops = make([]*sphinx.BlindedHopInfo, int(numHops[0]))
3✔
128

3✔
129
        // Parse each hop.
3✔
130
        for i := 0; i < len(payment.Hops); i++ {
6✔
131
                hop, err := DecodeBlindedHop(r)
3✔
132
                if err != nil {
3✔
133
                        return nil, err
×
134
                }
×
135

136
                payment.Hops[i] = hop
3✔
137
        }
138

139
        return &payment, nil
3✔
140
}
141

142
// Encode serialises the BlindedPaymentPath and writes the bytes to the passed
143
// writer.
144
// 1) The first 26 bytes contain the relay info:
145
//   - Base Fee in msat: uint32 (4 bytes).
146
//   - Proportional Fee in PPM: uint32 (4 bytes).
147
//   - CLTV expiry delta: uint16 (2 bytes).
148
//   - HTLC min msat: uint64 (8 bytes).
149
//   - HTLC max msat: uint64 (8 bytes).
150
//
151
// 2) Feature bit vector length (2 bytes).
152
// 3) Feature bit vector (can be zero length).
153
// 4) First blinding point: 33 bytes.
154
// 5) Number of hops: 1 byte.
155
// 6) Encoded BlindedHops.
156
func (p *BlindedPaymentPath) Encode(w io.Writer) error {
3✔
157
        if err := binary.Write(w, byteOrder, p.FeeBaseMsat); err != nil {
3✔
158
                return err
×
159
        }
×
160

161
        if err := binary.Write(w, byteOrder, p.FeeRate); err != nil {
3✔
162
                return err
×
163
        }
×
164

165
        if err := binary.Write(w, byteOrder, p.CltvExpiryDelta); err != nil {
3✔
166
                return err
×
167
        }
×
168

169
        if err := binary.Write(w, byteOrder, p.HTLCMinMsat); err != nil {
3✔
170
                return err
×
171
        }
×
172

173
        if err := binary.Write(w, byteOrder, p.HTLCMaxMsat); err != nil {
3✔
174
                return err
×
175
        }
×
176

177
        if err := p.Features.Encode(w); err != nil {
3✔
178
                return err
×
179
        }
×
180

181
        _, err := w.Write(p.FirstEphemeralBlindingPoint.SerializeCompressed())
3✔
182
        if err != nil {
3✔
183
                return err
×
184
        }
×
185

186
        numHops := len(p.Hops)
3✔
187
        if numHops > maxNumHopsPerPath {
3✔
188
                return fmt.Errorf("the number of hops, %d, exceeds the "+
×
189
                        "maximum of %d", numHops, maxNumHopsPerPath)
×
190
        }
×
191

192
        if _, err := w.Write([]byte{byte(numHops)}); err != nil {
3✔
193
                return err
×
194
        }
×
195

196
        for _, hop := range p.Hops {
6✔
197
                if err := EncodeBlindedHop(w, hop); err != nil {
3✔
198
                        return err
×
199
                }
×
200
        }
201

202
        return nil
3✔
203
}
204

205
// DecodeBlindedHop reads a sphinx.BlindedHopInfo from the passed reader.
206
func DecodeBlindedHop(r io.Reader) (*sphinx.BlindedHopInfo, error) {
3✔
207
        var nodeIDBytes [btcec.PubKeyBytesLenCompressed]byte
3✔
208
        _, err := r.Read(nodeIDBytes[:])
3✔
209
        if err != nil {
3✔
210
                return nil, err
×
211
        }
×
212

213
        nodeID, err := btcec.ParsePubKey(nodeIDBytes[:])
3✔
214
        if err != nil {
3✔
215
                return nil, err
×
216
        }
×
217

218
        dataLen, err := tlv.ReadVarInt(r, &[8]byte{})
3✔
219
        if err != nil {
3✔
220
                return nil, err
×
221
        }
×
222

223
        if dataLen > maxCipherTextLength {
3✔
224
                return nil, fmt.Errorf("a blinded hop cipher text blob may "+
×
225
                        "not exceed the maximum of %d bytes",
×
226
                        maxCipherTextLength)
×
227
        }
×
228

229
        encryptedData := make([]byte, dataLen)
3✔
230
        _, err = r.Read(encryptedData)
3✔
231
        if err != nil {
3✔
232
                return nil, err
×
233
        }
×
234

235
        return &sphinx.BlindedHopInfo{
3✔
236
                BlindedNodePub: nodeID,
3✔
237
                CipherText:     encryptedData,
3✔
238
        }, nil
3✔
239
}
240

241
// EncodeBlindedHop writes the passed BlindedHopInfo to the given writer.
242
//
243
// 1) Blinded node pub key: 33 bytes
244
// 2) Cipher text length: BigSize
245
// 3) Cipher text.
246
func EncodeBlindedHop(w io.Writer, hop *sphinx.BlindedHopInfo) error {
3✔
247
        _, err := w.Write(hop.BlindedNodePub.SerializeCompressed())
3✔
248
        if err != nil {
3✔
249
                return err
×
250
        }
×
251

252
        if len(hop.CipherText) > maxCipherTextLength {
3✔
253
                return fmt.Errorf("encrypted recipient data can not exceed a "+
×
254
                        "length of %d bytes", maxCipherTextLength)
×
255
        }
×
256

257
        err = tlv.WriteVarInt(w, uint64(len(hop.CipherText)), &[8]byte{})
3✔
258
        if err != nil {
3✔
259
                return err
×
260
        }
×
261

262
        _, err = w.Write(hop.CipherText)
3✔
263

3✔
264
        return err
3✔
265
}
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