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

lightningnetwork / lnd / 19155841408

07 Nov 2025 02:03AM UTC coverage: 66.675% (-0.04%) from 66.712%
19155841408

Pull #10352

github

web-flow
Merge e4313eba8 into 096ab65b1
Pull Request #10352: [WIP] chainrpc: return Unavailable while notifier starts

137328 of 205965 relevant lines covered (66.68%)

21333.36 hits per line

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

89.57
/lnwire/partial_sig.go
1
package lnwire
2

3
import (
4
        "io"
5

6
        "github.com/btcsuite/btcd/btcec/v2"
7
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
8
        "github.com/lightningnetwork/lnd/tlv"
9
)
10

11
const (
12
        // PartialSigLen is the length of a musig2 partial signature.
13
        PartialSigLen = 32
14
)
15

16
type (
17
        // PartialSigType is the type of the tlv record for a musig2
18
        // partial signature. This is an _even_ type, which means it's required
19
        // if included.
20
        PartialSigType = tlv.TlvType6
21

22
        // PartialSigTLV is a tlv record for a musig2 partial signature.
23
        PartialSigTLV = tlv.RecordT[PartialSigType, PartialSig]
24

25
        // OptPartialSigTLV is a tlv record for a musig2 partial signature.
26
        // This is an optional record type.
27
        OptPartialSigTLV = tlv.OptionalRecordT[PartialSigType, PartialSig]
28
)
29

30
// PartialSig is the base partial sig type. This only encodes the 32-byte
31
// partial signature. This is used for the co-op close flow, as both sides have
32
// already exchanged nonces, so they can send just the partial signature.
33
type PartialSig struct {
34
        // Sig is the 32-byte musig2 partial signature.
35
        Sig btcec.ModNScalar
36
}
37

38
// NewPartialSig creates a new partial sig.
39
func NewPartialSig(sig btcec.ModNScalar) PartialSig {
619✔
40
        return PartialSig{
619✔
41
                Sig: sig,
619✔
42
        }
619✔
43
}
619✔
44

45
// Record returns the tlv record for the partial sig.
46
func (p *PartialSig) Record() tlv.Record {
529✔
47
        return tlv.MakeStaticRecord(
529✔
48
                (PartialSigType)(nil).TypeVal(), p, PartialSigLen,
529✔
49
                partialSigTypeEncoder, partialSigTypeDecoder,
529✔
50
        )
529✔
51
}
529✔
52

53
// partialSigTypeEncoder encodes a 32-byte musig2 partial signature as a TLV
54
// value.
55
func partialSigTypeEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
179✔
56
        if v, ok := val.(*PartialSig); ok {
358✔
57
                sigBytes := v.Sig.Bytes()
179✔
58

179✔
59
                return tlv.EBytes32(w, &sigBytes, buf)
179✔
60
        }
179✔
61

62
        return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSig")
×
63
}
64

65
// Encode writes the encoded version of this message to the passed io.Writer.
66
func (p *PartialSig) Encode(w io.Writer) error {
×
67
        return partialSigTypeEncoder(w, p, nil)
×
68
}
×
69

70
// partialSigTypeDecoder decodes a 32-byte musig2 extended partial signature.
71
func partialSigTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
72
        l uint64) error {
188✔
73

188✔
74
        if v, ok := val.(*PartialSig); ok && l == PartialSigLen {
374✔
75
                var sBytes [32]byte
186✔
76
                err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
186✔
77
                if err != nil {
188✔
78
                        return err
2✔
79
                }
2✔
80

81
                var s btcec.ModNScalar
184✔
82
                s.SetBytes(&sBytes)
184✔
83

184✔
84
                *v = PartialSig{
184✔
85
                        Sig: s,
184✔
86
                }
184✔
87

184✔
88
                return nil
184✔
89
        }
90

91
        return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSig", l,
2✔
92
                PartialSigLen)
2✔
93
}
94

95
// Decode reads the encoded version of this message from the passed io.Reader.
96
func (p *PartialSig) Decode(r io.Reader) error {
×
97
        return partialSigTypeDecoder(r, p, nil, PartialSigLen)
×
98
}
×
99

100
// SomePartialSig is a helper function that returns an otional PartialSig.
101
func SomePartialSig(sig PartialSig) OptPartialSigTLV {
58✔
102
        return tlv.SomeRecordT(tlv.NewRecordT[PartialSigType, PartialSig](sig))
58✔
103
}
58✔
104

105
const (
106
        // PartialSigWithNonceLen is the length of a serialized
107
        // PartialSigWithNonce. The sig is encoded as the 32 byte S value
108
        // followed by the 66 nonce value.
109
        PartialSigWithNonceLen = 98
110
)
111

112
type (
113
        // PartialSigWithNonceType is the type of the tlv record for a musig2
114
        // partial signature with nonce. This is an _even_ type, which means
115
        // it's required if included.
116
        PartialSigWithNonceType = tlv.TlvType2
117

118
        // PartialSigWithNonceTLV is a tlv record for a musig2 partial
119
        // signature.
120
        PartialSigWithNonceTLV = tlv.RecordT[
121
                PartialSigWithNonceType, PartialSigWithNonce,
122
        ]
123

124
        // OptPartialSigWithNonceTLV is a tlv record for a musig2 partial
125
        // signature.  This is an optional record type.
126
        OptPartialSigWithNonceTLV = tlv.OptionalRecordT[
127
                PartialSigWithNonceType, PartialSigWithNonce,
128
        ]
129
)
130

131
// PartialSigWithNonce is a partial signature with the nonce that was used to
132
// generate the signature. This is used for funding as well as the commitment
133
// transaction update dance. By sending the nonce only with the signature, we
134
// enable the sender to generate their nonce just before they create their
135
// signature. Signers can use this trait to mix in additional contextual data
136
// such as the commitment txn itself into their nonce generation function.
137
//
138
// The final signature is 98 bytes: 32 bytes for the S value, and 66 bytes for
139
// the public nonce (two compressed points).
140
type PartialSigWithNonce struct {
141
        PartialSig
142

143
        // Nonce is the 66-byte musig2 nonce.
144
        Nonce Musig2Nonce
145
}
146

147
// NewPartialSigWithNonce creates a new partial sig with nonce.
148
func NewPartialSigWithNonce(nonce [musig2.PubNonceSize]byte,
149
        sig btcec.ModNScalar) *PartialSigWithNonce {
159✔
150

159✔
151
        return &PartialSigWithNonce{
159✔
152
                Nonce:      nonce,
159✔
153
                PartialSig: NewPartialSig(sig),
159✔
154
        }
159✔
155
}
159✔
156

157
// Record returns the tlv record for the partial sig with nonce.
158
func (p *PartialSigWithNonce) Record() tlv.Record {
5,078✔
159
        return tlv.MakeStaticRecord(
5,078✔
160
                (PartialSigWithNonceType)(nil).TypeVal(), p,
5,078✔
161
                PartialSigWithNonceLen, partialSigWithNonceTypeEncoder,
5,078✔
162
                partialSigWithNonceTypeDecoder,
5,078✔
163
        )
5,078✔
164
}
5,078✔
165

166
// partialSigWithNonceTypeEncoder encodes 98-byte musig2 extended partial
167
// signature as: s {32} || nonce {66}.
168
func partialSigWithNonceTypeEncoder(w io.Writer, val interface{},
169
        _ *[8]byte) error {
340✔
170

340✔
171
        if v, ok := val.(*PartialSigWithNonce); ok {
680✔
172
                sigBytes := v.Sig.Bytes()
340✔
173
                if _, err := w.Write(sigBytes[:]); err != nil {
340✔
174
                        return err
×
175
                }
×
176
                if _, err := w.Write(v.Nonce[:]); err != nil {
340✔
177
                        return err
×
178
                }
×
179

180
                return nil
340✔
181
        }
182

183
        return tlv.NewTypeForEncodingErr(val, "lnwire.PartialSigWithNonce")
×
184
}
185

186
// Encode writes the encoded version of this message to the passed io.Writer.
187
func (p *PartialSigWithNonce) Encode(w io.Writer) error {
175✔
188
        return partialSigWithNonceTypeEncoder(w, p, nil)
175✔
189
}
175✔
190

191
// partialSigWithNonceTypeDecoder decodes a 98-byte musig2 extended partial
192
// signature.
193
func partialSigWithNonceTypeDecoder(r io.Reader, val interface{}, buf *[8]byte,
194
        l uint64) error {
193✔
195

193✔
196
        if v, ok := val.(*PartialSigWithNonce); ok &&
193✔
197
                l == PartialSigWithNonceLen {
383✔
198

190✔
199
                var sBytes [32]byte
190✔
200
                err := tlv.DBytes32(r, &sBytes, buf, PartialSigLen)
190✔
201
                if err != nil {
193✔
202
                        return err
3✔
203
                }
3✔
204

205
                var s btcec.ModNScalar
187✔
206
                s.SetBytes(&sBytes)
187✔
207

187✔
208
                var nonce [66]byte
187✔
209
                if _, err := io.ReadFull(r, nonce[:]); err != nil {
190✔
210
                        return err
3✔
211
                }
3✔
212

213
                *v = PartialSigWithNonce{
184✔
214
                        PartialSig: NewPartialSig(s),
184✔
215
                        Nonce:      nonce,
184✔
216
                }
184✔
217

184✔
218
                return nil
184✔
219
        }
220

221
        return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSigWithNonce", l,
3✔
222
                PartialSigWithNonceLen)
3✔
223
}
224

225
// Decode reads the encoded version of this message from the passed io.Reader.
226
func (p *PartialSigWithNonce) Decode(r io.Reader) error {
11✔
227
        return partialSigWithNonceTypeDecoder(
11✔
228
                r, p, nil, PartialSigWithNonceLen,
11✔
229
        )
11✔
230
}
11✔
231

232
// MaybePartialSigWithNonce is a helper function that returns an optional
233
// PartialSigWithNonceTLV.
234
func MaybePartialSigWithNonce(sig *PartialSigWithNonce,
235
) OptPartialSigWithNonceTLV {
2,314✔
236

2,314✔
237
        if sig == nil {
4,293✔
238
                var none OptPartialSigWithNonceTLV
1,979✔
239
                return none
1,979✔
240
        }
1,979✔
241

242
        return tlv.SomeRecordT(
338✔
243
                tlv.NewRecordT[PartialSigWithNonceType, PartialSigWithNonce](
338✔
244
                        *sig,
338✔
245
                ),
338✔
246
        )
338✔
247
}
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