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

lightningnetwork / lnd / 19155841408

07 Nov 2025 02:03AM UTC coverage: 66.675% (-0.04%) from 66.712%
19155841408

Pull #10352

github

web-flow
Merge e4313eba8 into 096ab65b1
Pull Request #10352: [WIP] chainrpc: return Unavailable while notifier starts

137328 of 205965 relevant lines covered (66.68%)

21333.36 hits per line

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

96.47
/zpay32/amountunits.go
1
package zpay32
2

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

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

10
var (
11
        // toMSat is a map from a unit to a function that converts an amount
12
        // of that unit to millisatoshis.
13
        toMSat = map[byte]func(uint64) (lnwire.MilliSatoshi, error){
14
                'm': mBtcToMSat,
15
                'u': uBtcToMSat,
16
                'n': nBtcToMSat,
17
                'p': pBtcToMSat,
18
        }
19

20
        // fromMSat is a map from a unit to a function that converts an amount
21
        // in millisatoshis to an amount of that unit.
22
        fromMSat = map[byte]func(lnwire.MilliSatoshi) (uint64, error){
23
                'm': mSatToMBtc,
24
                'u': mSatToUBtc,
25
                'n': mSatToNBtc,
26
                'p': mSatToPBtc,
27
        }
28
)
29

30
// mBtcToMSat converts the given amount in milliBTC to millisatoshis.
31
func mBtcToMSat(m uint64) (lnwire.MilliSatoshi, error) {
40✔
32
        return lnwire.MilliSatoshi(m) * 100000000, nil
40✔
33
}
40✔
34

35
// uBtcToMSat converts the given amount in microBTC to millisatoshis.
36
func uBtcToMSat(u uint64) (lnwire.MilliSatoshi, error) {
18✔
37
        return lnwire.MilliSatoshi(u * 100000), nil
18✔
38
}
18✔
39

40
// nBtcToMSat converts the given amount in nanoBTC to millisatoshis.
41
func nBtcToMSat(n uint64) (lnwire.MilliSatoshi, error) {
6✔
42
        return lnwire.MilliSatoshi(n * 100), nil
6✔
43
}
6✔
44

45
// pBtcToMSat converts the given amount in picoBTC to millisatoshis.
46
func pBtcToMSat(p uint64) (lnwire.MilliSatoshi, error) {
14✔
47
        if p < 10 {
16✔
48
                return 0, fmt.Errorf("minimum amount is 10p")
2✔
49
        }
2✔
50
        if p%10 != 0 {
15✔
51
                return 0, fmt.Errorf("amount %d pBTC not expressible in msat",
3✔
52
                        p)
3✔
53
        }
3✔
54
        return lnwire.MilliSatoshi(p / 10), nil
9✔
55
}
56

57
// mSatToMBtc converts the given amount in millisatoshis to milliBTC.
58
func mSatToMBtc(msat lnwire.MilliSatoshi) (uint64, error) {
133✔
59
        if msat%100000000 != 0 {
240✔
60
                return 0, fmt.Errorf("%d msat not expressible "+
107✔
61
                        "in mBTC", msat)
107✔
62
        }
107✔
63
        return uint64(msat / 100000000), nil
29✔
64
}
65

66
// mSatToUBtc converts the given amount in millisatoshis to microBTC.
67
func mSatToUBtc(msat lnwire.MilliSatoshi) (uint64, error) {
133✔
68
        if msat%100000 != 0 {
139✔
69
                return 0, fmt.Errorf("%d msat not expressible "+
6✔
70
                        "in uBTC", msat)
6✔
71
        }
6✔
72
        return uint64(msat / 100000), nil
130✔
73
}
74

75
// mSatToNBtc converts the given amount in millisatoshis to nanoBTC.
76
func mSatToNBtc(msat lnwire.MilliSatoshi) (uint64, error) {
133✔
77
        if msat%100 != 0 {
135✔
78
                return 0, fmt.Errorf("%d msat not expressible in nBTC", msat)
2✔
79
        }
2✔
80
        return uint64(msat / 100), nil
131✔
81
}
82

83
// mSatToPBtc converts the given amount in millisatoshis to picoBTC.
84
func mSatToPBtc(msat lnwire.MilliSatoshi) (uint64, error) {
263✔
85
        return uint64(msat * 10), nil
263✔
86
}
263✔
87

88
// decodeAmount returns the amount encoded by the provided string in
89
// millisatoshi.
90
func decodeAmount(amount string) (lnwire.MilliSatoshi, error) {
129✔
91
        if len(amount) < 1 {
130✔
92
                return 0, fmt.Errorf("amount must be non-empty")
1✔
93
        }
1✔
94

95
        // If last character is a digit, then the amount can just be
96
        // interpreted as BTC.
97
        char := amount[len(amount)-1]
128✔
98
        digit := char - '0'
128✔
99
        if digit >= 0 && digit <= 9 {
173✔
100
                btc, err := strconv.ParseUint(amount, 10, 64)
45✔
101
                if err != nil {
52✔
102
                        return 0, err
7✔
103
                }
7✔
104
                return lnwire.MilliSatoshi(btc) * mSatPerBtc, nil
38✔
105
        }
106

107
        // If not a digit, it must be part of the known units.
108
        conv, ok := toMSat[char]
83✔
109
        if !ok {
87✔
110
                return 0, fmt.Errorf("unknown multiplier %c", char)
4✔
111
        }
4✔
112

113
        // Known unit.
114
        num := amount[:len(amount)-1]
79✔
115
        if len(num) < 1 {
82✔
116
                return 0, fmt.Errorf("number must be non-empty")
3✔
117
        }
3✔
118

119
        am, err := strconv.ParseUint(num, 10, 64)
76✔
120
        if err != nil {
80✔
121
                return 0, err
4✔
122
        }
4✔
123

124
        return conv(am)
72✔
125
}
126

127
// encodeAmount encodes the provided millisatoshi amount using as few characters
128
// as possible.
129
func encodeAmount(msat lnwire.MilliSatoshi) (string, error) {
142✔
130
        // If possible to express in BTC, that will always be the shortest
142✔
131
        // representation.
142✔
132
        if msat%mSatPerBtc == 0 {
151✔
133
                return strconv.FormatInt(int64(msat/mSatPerBtc), 10), nil
9✔
134
        }
9✔
135

136
        // Should always be expressible in pico BTC.
137
        pico, err := fromMSat['p'](msat)
133✔
138
        if err != nil {
133✔
139
                return "", fmt.Errorf("unable to express %d msat as pBTC: %w",
×
140
                        msat, err)
×
141
        }
×
142
        shortened := strconv.FormatUint(pico, 10) + "p"
133✔
143
        for unit, conv := range fromMSat {
656✔
144
                am, err := conv(msat)
523✔
145
                if err != nil {
635✔
146
                        // Not expressible using this unit.
112✔
147
                        continue
112✔
148
                }
149

150
                // Save the shortest found representation.
151
                str := strconv.FormatUint(am, 10) + string(unit)
414✔
152
                if len(str) < len(shortened) {
566✔
153
                        shortened = str
152✔
154
                }
152✔
155
        }
156

157
        return shortened, nil
133✔
158
}
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