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

lightningnetwork / lnd / 21485572389

29 Jan 2026 04:09PM UTC coverage: 65.247% (+0.2%) from 65.074%
21485572389

Pull #10089

github

web-flow
Merge 22d34d15e into 19b2ad797
Pull Request #10089: Onion message forwarding

1152 of 1448 new or added lines in 23 files covered. (79.56%)

4109 existing lines in 29 files now uncovered.

139515 of 213825 relevant lines covered (65.25%)

20529.09 hits per line

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

75.51
/routing/route/blindedroute.go
1
package route
2

3
import (
4
        "fmt"
5

6
        "github.com/btcsuite/btcd/btcec/v2"
7
        sphinx "github.com/lightningnetwork/lightning-onion"
8
        "github.com/lightningnetwork/lnd/lnwire"
9
)
10

11
// OnionMessageBlindedPathToSphinxPath converts a complete blinded path intended
12
// for sending an onion message to a PaymentPath that contains the per-hop
13
// payloads used to encoding the routing data for each hop in the route. This
14
// method also accepts final hop payloads.
15
func OnionMessageBlindedPathToSphinxPath(blindedPath *sphinx.BlindedPath,
16
        replyPath *sphinx.BlindedPath, finalHopTLVs []*lnwire.FinalHopTLV) (
17
        *sphinx.PaymentPath, error) {
11✔
18

11✔
19
        var path sphinx.PaymentPath
11✔
20

11✔
21
        // We can only construct a route if there are hops provided.
11✔
22
        if len(blindedPath.BlindedHops) == 0 {
11✔
NEW
23
                return nil, ErrNoRouteHopsProvided
×
NEW
24
        }
×
25

26
        // Check maximum route length. We keep the maximum the same as
27
        // sphinx.NumMaxHops for simplicity. In theory the maximum for onion
28
        // messages could be higher, namely 481. See:
29
        // https://delvingbitcoin.org/t/onion-messaging-dos-threat-mitigations
30
        if len(blindedPath.BlindedHops) > sphinx.NumMaxHops {
11✔
NEW
31
                return nil, ErrMaxRouteHopsExceeded
×
NEW
32
        }
×
33

34
        // For each hop encoded within the route, we'll convert the hop struct
35
        // to an OnionHop with matching per-hop payload within the path as used
36
        // by the sphinx package.
37
        for i, hop := range blindedPath.BlindedHops {
31✔
38
                // Create an onionMessagePayload with the encrypted data for
20✔
39
                // this hop.
20✔
40
                onionMessagePayload := &lnwire.OnionMessagePayload{
20✔
41
                        EncryptedData: hop.CipherText,
20✔
42
                }
20✔
43

20✔
44
                // If we're on the final hop include the tlvs intended for the
20✔
45
                // final hop and the reply path (if provided).
20✔
46
                finalHop := i == len(blindedPath.BlindedHops)-1
20✔
47
                if finalHop {
31✔
48
                        onionMessagePayload.FinalHopTLVs = finalHopTLVs
11✔
49
                        onionMessagePayload.ReplyPath = replyPath
11✔
50
                }
11✔
51

52
                // create a sphinx hop for this blinded hop.
53
                hop, err := createSphinxHop(
20✔
54
                        *hop.BlindedNodePub, onionMessagePayload,
20✔
55
                )
20✔
56
                if err != nil {
20✔
NEW
57
                        return nil, fmt.Errorf("sphinx hop %v: %w", i, err)
×
NEW
58
                }
×
59
                path[i] = *hop
20✔
60
        }
61

62
        return &path, nil
11✔
63
}
64

65
// createSphinxHop encodes an onion message payload and produces a sphinx
66
// onion hop for it.
67
func createSphinxHop(nodeID btcec.PublicKey,
68
        onionMessagePayload *lnwire.OnionMessagePayload) (*sphinx.OnionHop,
69
        error) {
20✔
70

20✔
71
        encodeOnionMessagePayload, err := onionMessagePayload.Encode()
20✔
72
        if err != nil {
20✔
NEW
73
                return nil, fmt.Errorf("failed onion message payload encode: "+
×
NEW
74
                        "%w", err)
×
NEW
75
        }
×
76

77
        hopPayload, err := sphinx.NewTLVHopPayload(encodeOnionMessagePayload)
20✔
78
        if err != nil {
20✔
NEW
79
                return nil, fmt.Errorf("failed creation of tlv hop payload: "+
×
NEW
80
                        "%w", err)
×
NEW
81
        }
×
82

83
        return &sphinx.OnionHop{
20✔
84
                NodePub:    nodeID,
20✔
85
                HopPayload: hopPayload,
20✔
86
        }, nil
20✔
87
}
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

© 2026 Coveralls, Inc