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

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

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

74.78
/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 {
3✔
40
        return PartialSig{
3✔
41
                Sig: sig,
3✔
42
        }
3✔
43
}
3✔
44

45
// Record returns the tlv record for the partial sig.
46
func (p *PartialSig) Record() tlv.Record {
3✔
47
        return tlv.MakeStaticRecord(
3✔
48
                (PartialSigType)(nil).TypeVal(), p, PartialSigLen,
3✔
49
                partialSigTypeEncoder, partialSigTypeDecoder,
3✔
50
        )
3✔
51
}
3✔
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 {
3✔
56
        if v, ok := val.(*PartialSig); ok {
6✔
57
                sigBytes := v.Sig.Bytes()
3✔
58

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

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

65
// Encode writes the encoded version of this message to the passed io.Writer.
UNCOV
66
func (p *PartialSig) Encode(w io.Writer) error {
×
UNCOV
67
        return partialSigTypeEncoder(w, p, nil)
×
UNCOV
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 {
3✔
73

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

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

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

3✔
88
                return nil
3✔
89
        }
90

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

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

100
// SomePartialSig is a helper function that returns an otional PartialSig.
101
func SomePartialSig(sig PartialSig) OptPartialSigTLV {
3✔
102
        return tlv.SomeRecordT(tlv.NewRecordT[PartialSigType, PartialSig](sig))
3✔
103
}
3✔
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,
UNCOV
149
        sig btcec.ModNScalar) *PartialSigWithNonce {
×
UNCOV
150

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

157
// Record returns the tlv record for the partial sig with nonce.
158
func (p *PartialSigWithNonce) Record() tlv.Record {
3✔
159
        return tlv.MakeStaticRecord(
3✔
160
                (PartialSigWithNonceType)(nil).TypeVal(), p,
3✔
161
                PartialSigWithNonceLen, partialSigWithNonceTypeEncoder,
3✔
162
                partialSigWithNonceTypeDecoder,
3✔
163
        )
3✔
164
}
3✔
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 {
3✔
170

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

180
                return nil
3✔
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 {
3✔
188
        return partialSigWithNonceTypeEncoder(w, p, nil)
3✔
189
}
3✔
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 {
3✔
195

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

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

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

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

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

3✔
218
                return nil
3✔
219
        }
220

UNCOV
221
        return tlv.NewTypeForDecodingErr(val, "lnwire.PartialSigWithNonce", l,
×
UNCOV
222
                PartialSigWithNonceLen)
×
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 {
3✔
227
        return partialSigWithNonceTypeDecoder(
3✔
228
                r, p, nil, PartialSigWithNonceLen,
3✔
229
        )
3✔
230
}
3✔
231

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

3✔
237
        if sig == nil {
6✔
238
                var none OptPartialSigWithNonceTLV
3✔
239
                return none
3✔
240
        }
3✔
241

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