• 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

6.58
/peer/musig_chan_closer.go
1
package peer
2

3
import (
4
        "fmt"
5

6
        "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
7
        "github.com/lightningnetwork/lnd/fn/v2"
8
        "github.com/lightningnetwork/lnd/input"
9
        "github.com/lightningnetwork/lnd/lnwallet"
10
        "github.com/lightningnetwork/lnd/lnwallet/chancloser"
11
        "github.com/lightningnetwork/lnd/lnwire"
12
)
13

14
// MusigChanCloser is an adapter over the normal channel state machine that
15
// allows the chan closer to handle the musig2 details of closing taproot
16
// channels.
17
type MusigChanCloser struct {
18
        channel *lnwallet.LightningChannel
19

20
        musigSession *lnwallet.MusigSession
21

22
        localNonce  *musig2.Nonces
23
        remoteNonce *musig2.Nonces
24
}
25

26
// NewMusigChanCloser creates a new musig chan closer from a normal channel.
27
func NewMusigChanCloser(channel *lnwallet.LightningChannel) *MusigChanCloser {
9✔
28
        return &MusigChanCloser{
9✔
29
                channel: channel,
9✔
30
        }
9✔
31
}
9✔
32

33
// ProposalClosingOpts returns the options that should be used when
34
// generating a new co-op close signature.
35
func (m *MusigChanCloser) ProposalClosingOpts() (
36
        []lnwallet.ChanCloseOpt, error) {
×
37

×
38
        switch {
×
39
        case m.localNonce == nil:
×
40
                return nil, fmt.Errorf("local nonce not generated")
×
41

42
        case m.remoteNonce == nil:
×
43
                return nil, fmt.Errorf("remote nonce not generated")
×
44
        }
45

46
        localKey, remoteKey := m.channel.MultiSigKeys()
×
47

×
48
        tapscriptTweak := fn.MapOption(lnwallet.TapscriptRootToTweak)(
×
49
                m.channel.State().TapscriptRoot,
×
50
        )
×
51

×
52
        m.musigSession = lnwallet.NewPartialMusigSession(
×
53
                *m.remoteNonce, localKey, remoteKey,
×
54
                m.channel.Signer, m.channel.FundingTxOut(),
×
55
                lnwallet.RemoteMusigCommit, tapscriptTweak,
×
56
        )
×
57

×
58
        err := m.musigSession.FinalizeSession(*m.localNonce)
×
59
        if err != nil {
×
60
                return nil, err
×
61
        }
×
62

63
        return []lnwallet.ChanCloseOpt{
×
64
                lnwallet.WithCoopCloseMusigSession(m.musigSession),
×
65
        }, nil
×
66
}
67

68
// CombineClosingOpts returns the options that should be used when combining
69
// the final musig partial signature. The method also maps the lnwire partial
70
// signatures into an input.Signature that can be used more generally.
71
func (m *MusigChanCloser) CombineClosingOpts(localSig,
72
        remoteSig lnwire.PartialSig) (input.Signature, input.Signature,
73
        []lnwallet.ChanCloseOpt, error) {
×
74

×
75
        if m.musigSession == nil {
×
76
                return nil, nil, nil, fmt.Errorf("musig session not created")
×
77
        }
×
78

79
        // We'll convert the wire partial signatures into an input.Signature
80
        // compliant struct so we can pass it into the final combination
81
        // function.
82
        localPartialSig := &lnwire.PartialSigWithNonce{
×
83
                PartialSig: localSig,
×
84
                Nonce:      m.localNonce.PubNonce,
×
85
        }
×
86
        remotePartialSig := &lnwire.PartialSigWithNonce{
×
87
                PartialSig: remoteSig,
×
88
                Nonce:      m.remoteNonce.PubNonce,
×
89
        }
×
90

×
91
        localMuSig := new(lnwallet.MusigPartialSig).FromWireSig(
×
92
                localPartialSig,
×
93
        )
×
94
        remoteMuSig := new(lnwallet.MusigPartialSig).FromWireSig(
×
95
                remotePartialSig,
×
96
        )
×
97

×
98
        opts := []lnwallet.ChanCloseOpt{
×
99
                lnwallet.WithCoopCloseMusigSession(m.musigSession),
×
100
        }
×
101

×
102
        // For taproot channels, we'll need to pass along the session so the
×
103
        // final combined signature can be created.
×
104
        return localMuSig, remoteMuSig, opts, nil
×
105
}
106

107
// ClosingNonce returns the nonce that should be used when generating the our
108
// partial signature for the remote party.
109
func (m *MusigChanCloser) ClosingNonce() (*musig2.Nonces, error) {
×
110
        if m.localNonce != nil {
×
111
                return m.localNonce, nil
×
112
        }
×
113

114
        localKey, _ := m.channel.MultiSigKeys()
×
115
        nonce, err := musig2.GenNonces(
×
116
                musig2.WithPublicKey(localKey.PubKey),
×
117
        )
×
118
        if err != nil {
×
119
                return nil, err
×
120
        }
×
121

122
        m.localNonce = nonce
×
123

×
124
        return nonce, nil
×
125
}
126

127
// InitRemoteNonce saves the remote nonce the party sent during their shutdown
128
// message so it can be used later to generate and verify signatures.
129
func (m *MusigChanCloser) InitRemoteNonce(nonce *musig2.Nonces) {
×
130
        m.remoteNonce = nonce
×
131
}
×
132

133
// A compile-time assertion to ensure MusigChanCloser implements the
134
// chancloser.MusigSession interface.
135
var _ chancloser.MusigSession = (*MusigChanCloser)(nil)
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