forked from lightningnetwork/lnd
-
Notifications
You must be signed in to change notification settings - Fork 1
/
marshall_utils.go
175 lines (148 loc) · 4.99 KB
/
marshall_utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package lnrpc
import (
"encoding/hex"
"errors"
fmt "fmt"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
)
var (
// ErrSatMsatMutualExclusive is returned when both a sat and an msat
// amount are set.
ErrSatMsatMutualExclusive = errors.New(
"sat and msat arguments are mutually exclusive",
)
)
// CalculateFeeLimit returns the fee limit in millisatoshis. If a percentage
// based fee limit has been requested, we'll factor in the ratio provided with
// the amount of the payment.
func CalculateFeeLimit(feeLimit *FeeLimit,
amount lnwire.MilliSatoshi) lnwire.MilliSatoshi {
switch feeLimit.GetLimit().(type) {
case *FeeLimit_Fixed:
return lnwire.NewMSatFromSatoshis(
btcutil.Amount(feeLimit.GetFixed()),
)
case *FeeLimit_FixedMsat:
return lnwire.MilliSatoshi(feeLimit.GetFixedMsat())
case *FeeLimit_Percent:
return amount * lnwire.MilliSatoshi(feeLimit.GetPercent()) / 100
default:
// Fall back to a sane default value that is based on the amount
// itself.
return lnwallet.DefaultRoutingFeeLimitForAmount(amount)
}
}
// UnmarshallAmt returns a strong msat type for a sat/msat pair of rpc fields.
func UnmarshallAmt(amtSat, amtMsat int64) (lnwire.MilliSatoshi, error) {
if amtSat != 0 && amtMsat != 0 {
return 0, ErrSatMsatMutualExclusive
}
if amtSat != 0 {
return lnwire.NewMSatFromSatoshis(btcutil.Amount(amtSat)), nil
}
return lnwire.MilliSatoshi(amtMsat), nil
}
// ParseConfs validates the minimum and maximum confirmation arguments of a
// ListUnspent request.
func ParseConfs(min, max int32) (int32, int32, error) {
switch {
// Ensure that the user didn't attempt to specify a negative number of
// confirmations, as that isn't possible.
case min < 0:
return 0, 0, fmt.Errorf("min confirmations must be >= 0")
// We'll also ensure that the min number of confs is strictly less than
// or equal to the max number of confs for sanity.
case min > max:
return 0, 0, fmt.Errorf("max confirmations must be >= min " +
"confirmations")
default:
return min, max, nil
}
}
// MarshalUtxos translates a []*lnwallet.Utxo into a []*lnrpc.Utxo.
func MarshalUtxos(utxos []*lnwallet.Utxo, activeNetParams *chaincfg.Params) (
[]*Utxo, error) {
res := make([]*Utxo, 0, len(utxos))
for _, utxo := range utxos {
// Translate lnwallet address type to the proper gRPC proto
// address type.
var addrType AddressType
switch utxo.AddressType {
case lnwallet.WitnessPubKey:
addrType = AddressType_WITNESS_PUBKEY_HASH
case lnwallet.NestedWitnessPubKey:
addrType = AddressType_NESTED_PUBKEY_HASH
case lnwallet.TaprootPubkey:
addrType = AddressType_TAPROOT_PUBKEY
case lnwallet.UnknownAddressType:
continue
default:
return nil, fmt.Errorf("invalid utxo address type")
}
// Now that we know we have a proper mapping to an address,
// we'll convert the regular outpoint to an lnrpc variant.
outpoint := &OutPoint{
TxidBytes: utxo.OutPoint.Hash[:],
TxidStr: utxo.OutPoint.Hash.String(),
OutputIndex: utxo.OutPoint.Index,
}
utxoResp := Utxo{
AddressType: addrType,
AmountSat: int64(utxo.Value),
PkScript: hex.EncodeToString(utxo.PkScript),
Outpoint: outpoint,
Confirmations: utxo.Confirmations,
}
// Finally, we'll attempt to extract the raw address from the
// script so we can display a human friendly address to the end
// user.
_, outAddresses, _, err := txscript.ExtractPkScriptAddrs(
utxo.PkScript, activeNetParams,
)
if err != nil {
return nil, err
}
// If we can't properly locate a single address, then this was
// an error in our mapping, and we'll return an error back to
// the user.
if len(outAddresses) != 1 {
return nil, fmt.Errorf("an output was unexpectedly " +
"multisig")
}
utxoResp.Address = outAddresses[0].String()
res = append(res, &utxoResp)
}
return res, nil
}
// MarshallOutputType translates a txscript.ScriptClass into a
// lnrpc.OutputScriptType.
func MarshallOutputType(o txscript.ScriptClass) OutputScriptType {
// Translate txscript ScriptClass type to the proper gRPC proto
// output script type.
switch o {
case txscript.ScriptHashTy:
return OutputScriptType_SCRIPT_TYPE_SCRIPT_HASH
case txscript.WitnessV0PubKeyHashTy:
return OutputScriptType_SCRIPT_TYPE_WITNESS_V0_PUBKEY_HASH
case txscript.WitnessV0ScriptHashTy:
return OutputScriptType_SCRIPT_TYPE_WITNESS_V0_SCRIPT_HASH
case txscript.PubKeyTy:
return OutputScriptType_SCRIPT_TYPE_PUBKEY
case txscript.MultiSigTy:
return OutputScriptType_SCRIPT_TYPE_MULTISIG
case txscript.NullDataTy:
return OutputScriptType_SCRIPT_TYPE_NULLDATA
case txscript.NonStandardTy:
return OutputScriptType_SCRIPT_TYPE_NON_STANDARD
case txscript.WitnessUnknownTy:
return OutputScriptType_SCRIPT_TYPE_WITNESS_UNKNOWN
case txscript.WitnessV1TaprootTy:
return OutputScriptType_SCRIPT_TYPE_WITNESS_V1_TAPROOT
default:
return OutputScriptType_SCRIPT_TYPE_PUBKEY_HASH
}
}