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

lightningnetwork / lnd / 15858991938

24 Jun 2025 06:51PM UTC coverage: 55.808% (-2.4%) from 58.173%
15858991938

Pull #9148

github

web-flow
Merge 0e921d6a5 into 29ff13d83
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

232 of 267 new or added lines in 5 files covered. (86.89%)

24606 existing lines in 281 files now uncovered.

108380 of 194201 relevant lines covered (55.81%)

22488.12 hits per line

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

20.15
/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 {
4✔
37

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

44
        case *FeeLimit_FixedMsat:
1✔
45
                return lnwire.MilliSatoshi(feeLimit.GetFixedMsat())
1✔
46

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

UNCOV
50
        default:
×
UNCOV
51
                // Fall back to a sane default value that is based on the amount
×
UNCOV
52
                // itself.
×
UNCOV
53
                return lnwallet.DefaultRoutingFeeLimitForAmount(amount)
×
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) {
35✔
59
        if amtSat != 0 && amtMsat != 0 {
37✔
60
                return 0, ErrSatMsatMutualExclusive
2✔
61
        }
2✔
62

63
        if amtSat < 0 || amtMsat < 0 {
34✔
64
                return 0, ErrNegativeAmt
1✔
65
        }
1✔
66

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

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

74
// ParseConfs validates the minimum and maximum confirmation arguments of a
75
// ListUnspent request.
UNCOV
76
func ParseConfs(min, max int32) (int32, int32, error) {
×
UNCOV
77
        switch {
×
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

UNCOV
89
        default:
×
UNCOV
90
                return min, max, nil
×
91
        }
92
}
93

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

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

UNCOV
107
                case lnwallet.NestedWitnessPubKey:
×
UNCOV
108
                        addrType = AddressType_NESTED_PUBKEY_HASH
×
109

UNCOV
110
                case lnwallet.TaprootPubkey:
×
UNCOV
111
                        addrType = AddressType_TAPROOT_PUBKEY
×
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.
UNCOV
122
                outpoint := MarshalOutPoint(&utxo.OutPoint)
×
UNCOV
123

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

×
UNCOV
132
                // Finally, we'll attempt to extract the raw address from the
×
UNCOV
133
                // script so we can display a human friendly address to the end
×
UNCOV
134
                // user.
×
UNCOV
135
                _, outAddresses, _, err := txscript.ExtractPkScriptAddrs(
×
UNCOV
136
                        utxo.PkScript, activeNetParams,
×
UNCOV
137
                )
×
UNCOV
138
                if err != nil {
×
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.
UNCOV
145
                if len(outAddresses) != 1 {
×
146
                        return nil, fmt.Errorf("an output was unexpectedly " +
×
147
                                "multisig")
×
148
                }
×
UNCOV
149
                utxoResp.Address = outAddresses[0].String()
×
UNCOV
150

×
UNCOV
151
                res = append(res, &utxoResp)
×
152
        }
153

UNCOV
154
        return res, nil
×
155
}
156

157
// MarshallOutputType translates a txscript.ScriptClass into a
158
// lnrpc.OutputScriptType.
UNCOV
159
func MarshallOutputType(o txscript.ScriptClass) OutputScriptType {
×
UNCOV
160
        // Translate txscript ScriptClass type to the proper gRPC proto
×
UNCOV
161
        // output script type.
×
UNCOV
162
        switch o {
×
163
        case txscript.ScriptHashTy:
×
164
                return OutputScriptType_SCRIPT_TYPE_SCRIPT_HASH
×
UNCOV
165
        case txscript.WitnessV0PubKeyHashTy:
×
UNCOV
166
                return OutputScriptType_SCRIPT_TYPE_WITNESS_V0_PUBKEY_HASH
×
UNCOV
167
        case txscript.WitnessV0ScriptHashTy:
×
UNCOV
168
                return OutputScriptType_SCRIPT_TYPE_WITNESS_V0_SCRIPT_HASH
×
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
×
UNCOV
179
        case txscript.WitnessV1TaprootTy:
×
UNCOV
180
                return OutputScriptType_SCRIPT_TYPE_WITNESS_V1_TAPROOT
×
UNCOV
181
        default:
×
UNCOV
182
                return OutputScriptType_SCRIPT_TYPE_PUBKEY_HASH
×
183
        }
184
}
185

186
// MarshalOutPoint converts a wire.OutPoint to its proto counterpart.
187
func MarshalOutPoint(op *wire.OutPoint) *OutPoint {
2✔
188
        return &OutPoint{
2✔
189
                TxidBytes:   op.Hash[:],
2✔
190
                TxidStr:     op.Hash.String(),
2✔
191
                OutputIndex: op.Index,
2✔
192
        }
2✔
193
}
2✔
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) (
UNCOV
204
        wallet.CoinSelectionStrategy, error) {
×
UNCOV
205

×
UNCOV
206
        switch strategy {
×
UNCOV
207
        case CoinSelectionStrategy_STRATEGY_USE_GLOBAL_CONFIG:
×
UNCOV
208
                return globalStrategy, nil
×
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.
UNCOV
224
func MarshalAliasMap(scidMap aliasmgr.ScidAliasMap) []*AliasMap {
×
UNCOV
225
        return fn.Map(
×
UNCOV
226
                slices.Collect(maps.Keys(scidMap)),
×
UNCOV
227
                func(base lnwire.ShortChannelID) *AliasMap {
×
UNCOV
228
                        return &AliasMap{
×
UNCOV
229
                                BaseScid: base.ToUint64(),
×
UNCOV
230
                                Aliases: fn.Map(
×
UNCOV
231
                                        scidMap[base],
×
UNCOV
232
                                        func(a lnwire.ShortChannelID) uint64 {
×
UNCOV
233
                                                return a.ToUint64()
×
UNCOV
234
                                        },
×
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