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

lightningnetwork / lnd / 12312390362

13 Dec 2024 08:44AM UTC coverage: 57.458% (+8.5%) from 48.92%
12312390362

Pull #9343

github

ellemouton
fn: rework the ContextGuard and add tests

In this commit, the ContextGuard struct is re-worked such that the
context that its new main WithCtx method provides is cancelled in sync
with a parent context being cancelled or with it's quit channel being
cancelled. Tests are added to assert the behaviour. In order for the
close of the quit channel to be consistent with the cancelling of the
derived context, the quit channel _must_ be contained internal to the
ContextGuard so that callers are only able to close the channel via the
exposed Quit method which will then take care to first cancel any
derived context that depend on the quit channel before returning.
Pull Request #9343: fn: expand the ContextGuard and add tests

101853 of 177264 relevant lines covered (57.46%)

24972.93 hits per line

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

88.46
/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.
36
func (f Flag) Type() Type {
5✔
37
        return Type(f)
5✔
38
}
5✔
39

40
// String returns the name of the flag.
41
func (f Flag) String() string {
941✔
42
        switch f {
941✔
43
        case FlagReward:
235✔
44
                return "FlagReward"
235✔
45
        case FlagCommitOutputs:
235✔
46
                return "FlagCommitOutputs"
235✔
47
        case FlagAnchorChannel:
235✔
48
                return "FlagAnchorChannel"
235✔
49
        case FlagTaprootChannel:
235✔
50
                return "FlagTaprootChannel"
235✔
51
        default:
1✔
52
                return "FlagUnknown"
1✔
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 {
42✔
86
        switch {
42✔
87
        case chanType.IsTaproot():
42✔
88
                return TypeAltruistTaprootCommit
42✔
89
        case chanType.HasAnchors():
×
90
                return TypeAltruistAnchorCommit
×
91
        default:
×
92
                return TypeAltruistCommit
×
93
        }
94
}
95

96
// Identifier returns a unique, stable string identifier for the blob Type.
97
func (t Type) Identifier() (string, error) {
87✔
98
        switch t {
87✔
99
        case TypeAltruistCommit:
×
100
                return "legacy", nil
×
101
        case TypeAltruistAnchorCommit:
×
102
                return "anchor", nil
×
103
        case TypeRewardCommit:
×
104
                return "reward", nil
×
105
        case TypeAltruistTaprootCommit:
87✔
106
                return "taproot", nil
87✔
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,429✔
116

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

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

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

129
                return LegacyCommitment, nil
170✔
130

131
        default:
2✔
132
                return 0, ErrUnknownBlobType
2✔
133
        }
134
}
135

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

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

148
        return typ
6✔
149
}
150

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

156
// IsTaprootChannel returns true if the blob type is for a taproot channel.
157
func (t Type) IsTaprootChannel() bool {
43✔
158
        return t.Has(FlagTaprootChannel)
43✔
159
}
43✔
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 {
235✔
171
        var (
235✔
172
                hrPieces        []string
235✔
173
                hasUnknownFlags bool
235✔
174
        )
235✔
175

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

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

205
        // Otherwise, we'll prepend the bit-wise representation to the human
206
        // readable names.
207
        return fmt.Sprintf("%016b[%s]", t, strings.Join(hrPieces, "|"))
1✔
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 {
130✔
221
        _, ok := supportedTypes[blobType]
130✔
222
        return ok
130✔
223
}
130✔
224

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