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

lightningnetwork / lnd / 15736109134

18 Jun 2025 02:46PM UTC coverage: 58.197% (-10.1%) from 68.248%
15736109134

Pull #9752

github

web-flow
Merge d2634a68c into 31c74f20f
Pull Request #9752: routerrpc: reject payment to invoice that don't have payment secret or blinded paths

6 of 13 new or added lines in 2 files covered. (46.15%)

28331 existing lines in 455 files now uncovered.

97860 of 168153 relevant lines covered (58.2%)

1.81 hits per line

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

80.0
/record/amp.go
1
package record
2

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

7
        "github.com/lightningnetwork/lnd/tlv"
8
)
9

10
// AMPOnionType is the type used in the onion to reference the AMP fields:
11
// root_share, set_id, and child_index.
12
const AMPOnionType tlv.Type = 14
13

14
// AMP is a record that encodes the fields necessary for atomic multi-path
15
// payments.
16
type AMP struct {
17
        rootShare  [32]byte
18
        setID      [32]byte
19
        childIndex uint32
20
}
21

22
// MaxAmpPayLoadSize is an AMP Record which when serialized to a tlv record uses
23
// the maximum payload size. The `childIndex` is created randomly and is a
24
// 4 byte `varint` type so we make sure we use an index which will be encoded in
25
// 4 bytes.
26
var MaxAmpPayLoadSize = AMP{
27
        rootShare:  [32]byte{},
28
        setID:      [32]byte{},
29
        childIndex: 0x80000000,
30
}
31

32
// NewAMP generate a new AMP record with the given root_share, set_id, and
33
// child_index.
34
func NewAMP(rootShare, setID [32]byte, childIndex uint32) *AMP {
3✔
35
        return &AMP{
3✔
36
                rootShare:  rootShare,
3✔
37
                setID:      setID,
3✔
38
                childIndex: childIndex,
3✔
39
        }
3✔
40
}
3✔
41

42
// RootShare returns the root share contained in the AMP record.
43
func (a *AMP) RootShare() [32]byte {
3✔
44
        return a.rootShare
3✔
45
}
3✔
46

47
// SetID returns the set id contained in the AMP record.
48
func (a *AMP) SetID() [32]byte {
3✔
49
        return a.setID
3✔
50
}
3✔
51

52
// ChildIndex returns the child index contained in the AMP record.
53
func (a *AMP) ChildIndex() uint32 {
3✔
54
        return a.childIndex
3✔
55
}
3✔
56

57
// AMPEncoder writes the AMP record to the provided io.Writer.
58
func AMPEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
3✔
59
        if v, ok := val.(*AMP); ok {
6✔
60
                if err := tlv.EBytes32(w, &v.rootShare, buf); err != nil {
3✔
61
                        return err
×
62
                }
×
63

64
                if err := tlv.EBytes32(w, &v.setID, buf); err != nil {
3✔
65
                        return err
×
66
                }
×
67

68
                return tlv.ETUint32T(w, v.childIndex, buf)
3✔
69
        }
70
        return tlv.NewTypeForEncodingErr(val, "AMP")
×
71
}
72

73
const (
74
        // minAMPLength is the minimum length of a serialized AMP TLV record,
75
        // which occurs when the truncated encoding of child_index takes 0
76
        // bytes, leaving only the root_share and set_id.
77
        minAMPLength = 64
78

79
        // maxAMPLength is the maximum length of a serialized AMP TLV record,
80
        // which occurs when the truncated encoding of a child_index takes 2
81
        // bytes.
82
        maxAMPLength = 68
83
)
84

85
// AMPDecoder reads the AMP record from the provided io.Reader.
86
func AMPDecoder(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
3✔
87
        if v, ok := val.(*AMP); ok && minAMPLength <= l && l <= maxAMPLength {
6✔
88
                if err := tlv.DBytes32(r, &v.rootShare, buf, 32); err != nil {
3✔
UNCOV
89
                        return err
×
UNCOV
90
                }
×
91

92
                if err := tlv.DBytes32(r, &v.setID, buf, 32); err != nil {
3✔
UNCOV
93
                        return err
×
UNCOV
94
                }
×
95

96
                return tlv.DTUint32(r, &v.childIndex, buf, l-minAMPLength)
3✔
97
        }
UNCOV
98
        return tlv.NewTypeForDecodingErr(val, "AMP", l, maxAMPLength)
×
99
}
100

101
// Record returns a tlv.Record that can be used to encode or decode this record.
102
func (a *AMP) Record() tlv.Record {
3✔
103
        return tlv.MakeDynamicRecord(
3✔
104
                AMPOnionType, a, a.PayloadSize, AMPEncoder, AMPDecoder,
3✔
105
        )
3✔
106
}
3✔
107

108
// PayloadSize returns the size this record takes up in encoded form.
109
func (a *AMP) PayloadSize() uint64 {
3✔
110
        return 32 + 32 + tlv.SizeTUint32(a.childIndex)
3✔
111
}
3✔
112

113
// String returns a human-readable description of the amp payload fields.
114
func (a *AMP) String() string {
3✔
115
        if a == nil {
6✔
116
                return "<nil>"
3✔
117
        }
3✔
118

119
        return fmt.Sprintf("root_share=%x set_id=%x child_index=%d",
3✔
120
                a.rootShare, a.setID, a.childIndex)
3✔
121
}
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