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

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

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

70.9
/lnrpc/marshall_utils.go
1
package lnrpc
2

3
import (
4
        "encoding/hex"
5
        "errors"
6
        "fmt"
7
        "maps"
8
        "slices"
9

10
        "github.com/btcsuite/btcd/btcutil"
11
        "github.com/btcsuite/btcd/chaincfg"
12
        "github.com/btcsuite/btcd/txscript"
13
        "github.com/btcsuite/btcd/wire"
14
        "github.com/btcsuite/btcwallet/wallet"
15
        "github.com/lightningnetwork/lnd/aliasmgr"
16
        "github.com/lightningnetwork/lnd/fn/v2"
17
        "github.com/lightningnetwork/lnd/lnwallet"
18
        "github.com/lightningnetwork/lnd/lnwire"
19
)
20

21
var (
22
        // ErrSatMsatMutualExclusive is returned when both a sat and an msat
23
        // amount are set.
24
        ErrSatMsatMutualExclusive = errors.New(
25
                "sat and msat arguments are mutually exclusive",
26
        )
27

28
        // ErrNegativeAmt is returned when a negative amount is specified.
29
        ErrNegativeAmt = errors.New("amount cannot be negative")
30
)
31

32
// CalculateFeeLimit returns the fee limit in millisatoshis. If a percentage
33
// based fee limit has been requested, we'll factor in the ratio provided with
34
// the amount of the payment.
35
func CalculateFeeLimit(feeLimit *FeeLimit,
36
        amount lnwire.MilliSatoshi) lnwire.MilliSatoshi {
3✔
37

3✔
38
        switch feeLimit.GetLimit().(type) {
3✔
39
        case *FeeLimit_Fixed:
3✔
40
                return lnwire.NewMSatFromSatoshis(
3✔
41
                        btcutil.Amount(feeLimit.GetFixed()),
3✔
42
                )
3✔
43

UNCOV
44
        case *FeeLimit_FixedMsat:
×
UNCOV
45
                return lnwire.MilliSatoshi(feeLimit.GetFixedMsat())
×
46

47
        case *FeeLimit_Percent:
3✔
48
                return amount * lnwire.MilliSatoshi(feeLimit.GetPercent()) / 100
3✔
49

50
        default:
3✔
51
                // Fall back to a sane default value that is based on the amount
3✔
52
                // itself.
3✔
53
                return lnwallet.DefaultRoutingFeeLimitForAmount(amount)
3✔
54
        }
55
}
56

57
// UnmarshallAmt returns a strong msat type for a sat/msat pair of rpc fields.
58
func UnmarshallAmt(amtSat, amtMsat int64) (lnwire.MilliSatoshi, error) {
3✔
59
        if amtSat != 0 && amtMsat != 0 {
3✔
UNCOV
60
                return 0, ErrSatMsatMutualExclusive
×
UNCOV
61
        }
×
62

63
        if amtSat < 0 || amtMsat < 0 {
3✔
UNCOV
64
                return 0, ErrNegativeAmt
×
UNCOV
65
        }
×
66

67
        if amtSat != 0 {
6✔
68
                return lnwire.NewMSatFromSatoshis(btcutil.Amount(amtSat)), nil
3✔
69
        }
3✔
70

71
        return lnwire.MilliSatoshi(amtMsat), nil
3✔
72
}
73

74
// ParseConfs validates the minimum and maximum confirmation arguments of a
75
// ListUnspent request.
76
func ParseConfs(min, max int32) (int32, int32, error) {
3✔
77
        switch {
3✔
78
        // Ensure that the user didn't attempt to specify a negative number of
79
        // confirmations, as that isn't possible.
80
        case min < 0:
×
81
                return 0, 0, fmt.Errorf("min confirmations must be >= 0")
×
82

83
        // We'll also ensure that the min number of confs is strictly less than
84
        // or equal to the max number of confs for sanity.
85
        case min > max:
×
86
                return 0, 0, fmt.Errorf("max confirmations must be >= min " +
×
87
                        "confirmations")
×
88

89
        default:
3✔
90
                return min, max, nil
3✔
91
        }
92
}
93

94
// MarshalUtxos translates a []*lnwallet.Utxo into a []*lnrpc.Utxo.
95
func MarshalUtxos(utxos []*lnwallet.Utxo, activeNetParams *chaincfg.Params) (
96
        []*Utxo, error) {
3✔
97

3✔
98
        res := make([]*Utxo, 0, len(utxos))
3✔
99
        for _, utxo := range utxos {
6✔
100
                // Translate lnwallet address type to the proper gRPC proto
3✔
101
                // address type.
3✔
102
                var addrType AddressType
3✔
103
                switch utxo.AddressType {
3✔
104
                case lnwallet.WitnessPubKey:
3✔
105
                        addrType = AddressType_WITNESS_PUBKEY_HASH
3✔
106

107
                case lnwallet.NestedWitnessPubKey:
3✔
108
                        addrType = AddressType_NESTED_PUBKEY_HASH
3✔
109

110
                case lnwallet.TaprootPubkey:
3✔
111
                        addrType = AddressType_TAPROOT_PUBKEY
3✔
112

113
                case lnwallet.UnknownAddressType:
×
114
                        continue
×
115

116
                default:
×
117
                        return nil, fmt.Errorf("invalid utxo address type")
×
118
                }
119

120
                // Now that we know we have a proper mapping to an address,
121
                // we'll convert the regular outpoint to an lnrpc variant.
122
                outpoint := MarshalOutPoint(&utxo.OutPoint)
3✔
123

3✔
124
                utxoResp := Utxo{
3✔
125
                        AddressType:   addrType,
3✔
126
                        AmountSat:     int64(utxo.Value),
3✔
127
                        PkScript:      hex.EncodeToString(utxo.PkScript),
3✔
128
                        Outpoint:      outpoint,
3✔
129
                        Confirmations: utxo.Confirmations,
3✔
130
                }
3✔
131

3✔
132
                // Finally, we'll attempt to extract the raw address from the
3✔
133
                // script so we can display a human friendly address to the end
3✔
134
                // user.
3✔
135
                _, outAddresses, _, err := txscript.ExtractPkScriptAddrs(
3✔
136
                        utxo.PkScript, activeNetParams,
3✔
137
                )
3✔
138
                if err != nil {
3✔
139
                        return nil, err
×
140
                }
×
141

142
                // If we can't properly locate a single address, then this was
143
                // an error in our mapping, and we'll return an error back to
144
                // the user.
145
                if len(outAddresses) != 1 {
3✔
146
                        return nil, fmt.Errorf("an output was unexpectedly " +
×
147
                                "multisig")
×
148
                }
×
149
                utxoResp.Address = outAddresses[0].String()
3✔
150

3✔
151
                res = append(res, &utxoResp)
3✔
152
        }
153

154
        return res, nil
3✔
155
}
156

157
// MarshallOutputType translates a txscript.ScriptClass into a
158
// lnrpc.OutputScriptType.
159
func MarshallOutputType(o txscript.ScriptClass) OutputScriptType {
3✔
160
        // Translate txscript ScriptClass type to the proper gRPC proto
3✔
161
        // output script type.
3✔
162
        switch o {
3✔
163
        case txscript.ScriptHashTy:
×
164
                return OutputScriptType_SCRIPT_TYPE_SCRIPT_HASH
×
165
        case txscript.WitnessV0PubKeyHashTy:
3✔
166
                return OutputScriptType_SCRIPT_TYPE_WITNESS_V0_PUBKEY_HASH
3✔
167
        case txscript.WitnessV0ScriptHashTy:
3✔
168
                return OutputScriptType_SCRIPT_TYPE_WITNESS_V0_SCRIPT_HASH
3✔
169
        case txscript.PubKeyTy:
×
170
                return OutputScriptType_SCRIPT_TYPE_PUBKEY
×
171
        case txscript.MultiSigTy:
×
172
                return OutputScriptType_SCRIPT_TYPE_MULTISIG
×
173
        case txscript.NullDataTy:
×
174
                return OutputScriptType_SCRIPT_TYPE_NULLDATA
×
175
        case txscript.NonStandardTy:
×
176
                return OutputScriptType_SCRIPT_TYPE_NON_STANDARD
×
177
        case txscript.WitnessUnknownTy:
×
178
                return OutputScriptType_SCRIPT_TYPE_WITNESS_UNKNOWN
×
179
        case txscript.WitnessV1TaprootTy:
3✔
180
                return OutputScriptType_SCRIPT_TYPE_WITNESS_V1_TAPROOT
3✔
181
        default:
3✔
182
                return OutputScriptType_SCRIPT_TYPE_PUBKEY_HASH
3✔
183
        }
184
}
185

186
// MarshalOutPoint converts a wire.OutPoint to its proto counterpart.
187
func MarshalOutPoint(op *wire.OutPoint) *OutPoint {
3✔
188
        return &OutPoint{
3✔
189
                TxidBytes:   op.Hash[:],
3✔
190
                TxidStr:     op.Hash.String(),
3✔
191
                OutputIndex: op.Index,
3✔
192
        }
3✔
193
}
3✔
194

195
// UnmarshallCoinSelectionStrategy converts a lnrpc.CoinSelectionStrategy proto
196
// type to its wallet.CoinSelectionStrategy counterpart type, considering
197
// a global default strategy if necessary.
198
//
199
// The globalStrategy parameter specifies the default coin selection strategy
200
// to use if the strategy is set to STRATEGY_USE_GLOBAL_CONFIG. This allows
201
// flexibility in defining a default strategy at a global level.
202
func UnmarshallCoinSelectionStrategy(strategy CoinSelectionStrategy,
203
        globalStrategy wallet.CoinSelectionStrategy) (
204
        wallet.CoinSelectionStrategy, error) {
3✔
205

3✔
206
        switch strategy {
3✔
207
        case CoinSelectionStrategy_STRATEGY_USE_GLOBAL_CONFIG:
3✔
208
                return globalStrategy, nil
3✔
209

210
        case CoinSelectionStrategy_STRATEGY_LARGEST:
×
211
                return wallet.CoinSelectionLargest, nil
×
212

213
        case CoinSelectionStrategy_STRATEGY_RANDOM:
×
214
                return wallet.CoinSelectionRandom, nil
×
215

216
        default:
×
217
                return nil, fmt.Errorf("unknown coin selection strategy "+
×
218
                        "%v", strategy)
×
219
        }
220
}
221

222
// MarshalAliasMap converts a ScidAliasMap to its proto counterpart. This is
223
// used in various RPCs that handle scid alias mappings.
224
func MarshalAliasMap(scidMap aliasmgr.ScidAliasMap) []*AliasMap {
3✔
225
        return fn.Map(
3✔
226
                slices.Collect(maps.Keys(scidMap)),
3✔
227
                func(base lnwire.ShortChannelID) *AliasMap {
6✔
228
                        return &AliasMap{
3✔
229
                                BaseScid: base.ToUint64(),
3✔
230
                                Aliases: fn.Map(
3✔
231
                                        scidMap[base],
3✔
232
                                        func(a lnwire.ShortChannelID) uint64 {
6✔
233
                                                return a.ToUint64()
3✔
234
                                        },
3✔
235
                                ),
236
                        }
237
                },
238
        )
239
}
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