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

lightningnetwork / lnd / 15838907453

24 Jun 2025 01:26AM UTC coverage: 57.079% (-11.1%) from 68.172%
15838907453

Pull #9982

github

web-flow
Merge e42780be2 into 45c15646c
Pull Request #9982: lnwire+lnwallet: add LocalNonces field for splice nonce coordination w/ taproot channels

103 of 167 new or added lines in 5 files covered. (61.68%)

30191 existing lines in 463 files now uncovered.

96331 of 168768 relevant lines covered (57.08%)

0.6 hits per line

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

75.0
/watchtower/blob/type.go
1
package blob
2

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

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

10
// Flag represents a specify option that can be present in a Type.
11
type Flag uint16
12

13
const (
14
        // FlagReward signals that the justice transaction should contain an
15
        // additional output for itself. Signatures sent by the client should
16
        // include the reward script negotiated during session creation. Without
17
        // the flag, there is only one output sweeping clients funds back to
18
        // them solely.
19
        FlagReward Flag = 1
20

21
        // FlagCommitOutputs signals that the blob contains the information
22
        // required to sweep commitment outputs.
23
        FlagCommitOutputs Flag = 1 << 1
24

25
        // FlagAnchorChannel signals that this blob is meant to spend an anchor
26
        // channel, and therefore must expect a P2WSH-style to-remote output if
27
        // one exists.
28
        FlagAnchorChannel Flag = 1 << 2
29

30
        // FlagTaprootChannel signals that this blob is meant to spend a
31
        // taproot channel and therefore must expect P2TR outputs.
32
        FlagTaprootChannel Flag = 1 << 3
33
)
34

35
// Type returns a Type consisting solely of this flag enabled.
UNCOV
36
func (f Flag) Type() Type {
×
UNCOV
37
        return Type(f)
×
UNCOV
38
}
×
39

40
// String returns the name of the flag.
41
func (f Flag) String() string {
1✔
42
        switch f {
1✔
43
        case FlagReward:
1✔
44
                return "FlagReward"
1✔
45
        case FlagCommitOutputs:
1✔
46
                return "FlagCommitOutputs"
1✔
47
        case FlagAnchorChannel:
1✔
48
                return "FlagAnchorChannel"
1✔
49
        case FlagTaprootChannel:
1✔
50
                return "FlagTaprootChannel"
1✔
UNCOV
51
        default:
×
UNCOV
52
                return "FlagUnknown"
×
53
        }
54
}
55

56
// Type is a bit vector composed of Flags that govern various aspects of
57
// reconstructing the justice transaction from an encrypted blob. The flags can
58
// be used to signal behaviors such as which inputs are being swept, which
59
// outputs should be added to the justice transaction, or modify serialization
60
// of the blob itself.
61
type Type uint16
62

63
const (
64
        // TypeAltruistCommit sweeps only commitment outputs to a sweep address
65
        // controlled by the user, and does not give the tower a reward.
66
        TypeAltruistCommit = Type(FlagCommitOutputs)
67

68
        // TypeAltruistAnchorCommit sweeps only commitment outputs from an
69
        // anchor commitment to a sweep address controlled by the user, and does
70
        // not give the tower a reward.
71
        TypeAltruistAnchorCommit = Type(FlagCommitOutputs | FlagAnchorChannel)
72

73
        // TypeRewardCommit sweeps only commitment outputs to a sweep address
74
        // controlled by the user, and pays a negotiated reward to the tower.
75
        TypeRewardCommit = Type(FlagCommitOutputs | FlagReward)
76

77
        // TypeAltruistTaprootCommit sweeps only the commitment outputs from a
78
        // taproot channel commitment to a sweep address controlled by the user,
79
        // and does not give the tower a reward.
80
        TypeAltruistTaprootCommit = Type(FlagCommitOutputs | FlagTaprootChannel)
81
)
82

83
// TypeFromChannel returns the appropriate blob Type for the given channel
84
// type.
85
func TypeFromChannel(chanType channeldb.ChannelType) Type {
1✔
86
        switch {
1✔
87
        case chanType.IsTaproot():
1✔
88
                return TypeAltruistTaprootCommit
1✔
89
        case chanType.HasAnchors():
1✔
90
                return TypeAltruistAnchorCommit
1✔
91
        default:
1✔
92
                return TypeAltruistCommit
1✔
93
        }
94
}
95

96
// Identifier returns a unique, stable string identifier for the blob Type.
97
func (t Type) Identifier() (string, error) {
1✔
98
        switch t {
1✔
99
        case TypeAltruistCommit:
1✔
100
                return "legacy", nil
1✔
101
        case TypeAltruistAnchorCommit:
1✔
102
                return "anchor", nil
1✔
103
        case TypeRewardCommit:
×
104
                return "reward", nil
×
105
        case TypeAltruistTaprootCommit:
1✔
106
                return "taproot", nil
1✔
107
        default:
×
108
                return "", fmt.Errorf("unknown blob type: %v", t)
×
109
        }
110
}
111

112
// CommitmentType returns the appropriate CommitmentType for the given blob Type
113
// and channel type.
114
func (t Type) CommitmentType(chanType *channeldb.ChannelType) (CommitmentType,
115
        error) {
1✔
116

1✔
117
        switch {
1✔
118
        case t.Has(FlagTaprootChannel):
1✔
119
                return TaprootCommitment, nil
1✔
120

121
        case t.Has(FlagAnchorChannel):
1✔
122
                return AnchorCommitment, nil
1✔
123

124
        case t.Has(FlagCommitOutputs):
1✔
125
                if chanType != nil && chanType.IsTweakless() {
2✔
126
                        return LegacyTweaklessCommitment, nil
1✔
127
                }
1✔
128

129
                return LegacyCommitment, nil
1✔
130

UNCOV
131
        default:
×
UNCOV
132
                return 0, ErrUnknownBlobType
×
133
        }
134
}
135

136
// Has returns true if the Type has the passed flag enabled.
137
func (t Type) Has(flag Flag) bool {
1✔
138
        return Flag(t)&flag == flag
1✔
139
}
1✔
140

141
// TypeFromFlags creates a single Type from an arbitrary list of flags.
UNCOV
142
func TypeFromFlags(flags ...Flag) Type {
×
UNCOV
143
        var typ Type
×
UNCOV
144
        for _, flag := range flags {
×
UNCOV
145
                typ |= Type(flag)
×
UNCOV
146
        }
×
147

UNCOV
148
        return typ
×
149
}
150

151
// IsAnchorChannel returns true if the blob type is for an anchor channel.
152
func (t Type) IsAnchorChannel() bool {
1✔
153
        return t.Has(FlagAnchorChannel)
1✔
154
}
1✔
155

156
// IsTaprootChannel returns true if the blob type is for a taproot channel.
157
func (t Type) IsTaprootChannel() bool {
1✔
158
        return t.Has(FlagTaprootChannel)
1✔
159
}
1✔
160

161
// knownFlags maps the supported flags to their name.
162
var knownFlags = map[Flag]struct{}{
163
        FlagReward:         {},
164
        FlagCommitOutputs:  {},
165
        FlagAnchorChannel:  {},
166
        FlagTaprootChannel: {},
167
}
168

169
// String returns a human-readable description of a Type.
170
func (t Type) String() string {
1✔
171
        var (
1✔
172
                hrPieces        []string
1✔
173
                hasUnknownFlags bool
1✔
174
        )
1✔
175

1✔
176
        // Iterate through the possible flags from highest to lowest. This will
1✔
177
        // ensure that the human readable names will be in the same order as the
1✔
178
        // bits (left to right) if the type were to be printed in big-endian
1✔
179
        // byte order.
1✔
180
        for f := Flag(1 << 15); f != 0; f >>= 1 {
2✔
181
                // If this flag is known, we'll add a human-readable name or its
1✔
182
                // inverse depending on whether the type has this flag set.
1✔
183
                if _, ok := knownFlags[f]; ok {
2✔
184
                        if t.Has(f) {
2✔
185
                                hrPieces = append(hrPieces, f.String())
1✔
186
                        } else {
2✔
187
                                hrPieces = append(hrPieces, "No-"+f.String())
1✔
188
                        }
1✔
189
                } else {
1✔
190
                        // Make note of any unknown flags that this type has
1✔
191
                        // set. If any are present, we'll prepend the bit-wise
1✔
192
                        // representation of the type in the final string.
1✔
193
                        if t.Has(f) {
1✔
UNCOV
194
                                hasUnknownFlags = true
×
UNCOV
195
                        }
×
196
                }
197
        }
198

199
        // If there were no unknown flags, we'll simply return the list of human
200
        // readable pieces.
201
        if !hasUnknownFlags {
2✔
202
                return fmt.Sprintf("[%s]", strings.Join(hrPieces, "|"))
1✔
203
        }
1✔
204

205
        // Otherwise, we'll prepend the bit-wise representation to the human
206
        // readable names.
UNCOV
207
        return fmt.Sprintf("%016b[%s]", t, strings.Join(hrPieces, "|"))
×
208
}
209

210
// supportedTypes is the set of all configurations known to be supported by the
211
// package.
212
var supportedTypes = map[Type]struct{}{
213
        TypeAltruistCommit:        {},
214
        TypeRewardCommit:          {},
215
        TypeAltruistAnchorCommit:  {},
216
        TypeAltruistTaprootCommit: {},
217
}
218

219
// IsSupportedType returns true if the given type is supported by the package.
220
func IsSupportedType(blobType Type) bool {
1✔
221
        _, ok := supportedTypes[blobType]
1✔
222
        return ok
1✔
223
}
1✔
224

225
// SupportedTypes returns a list of all supported blob types.
UNCOV
226
func SupportedTypes() []Type {
×
UNCOV
227
        supported := make([]Type, 0, len(supportedTypes))
×
UNCOV
228
        for t := range supportedTypes {
×
UNCOV
229
                supported = append(supported, t)
×
UNCOV
230
        }
×
UNCOV
231
        return supported
×
232
}
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