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

lightningnetwork / lnd / 12343072627

15 Dec 2024 11:09PM UTC coverage: 57.504% (-1.1%) from 58.636%
12343072627

Pull #9315

github

yyforyongyu
contractcourt: offer outgoing htlc one block earlier before its expiry

We need to offer the outgoing htlc one block earlier to make sure when
the expiry height hits, the sweeper will not miss sweeping it in the
same block. This also means the outgoing contest resolver now only does
one thing - watch for preimage spend till height expiry-1, which can
easily be moved into the timeout resolver instead in the future.
Pull Request #9315: Implement `blockbeat`

1445 of 2007 new or added lines in 26 files covered. (72.0%)

19246 existing lines in 249 files now uncovered.

102342 of 177975 relevant lines covered (57.5%)

24772.24 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() (
UNCOV
36
        []lnwallet.ChanCloseOpt, error) {
×
UNCOV
37

×
UNCOV
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

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

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

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

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

UNCOV
63
        return []lnwallet.ChanCloseOpt{
×
UNCOV
64
                lnwallet.WithCoopCloseMusigSession(m.musigSession),
×
UNCOV
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,
UNCOV
73
        []lnwallet.ChanCloseOpt, error) {
×
UNCOV
74

×
UNCOV
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.
UNCOV
82
        localPartialSig := &lnwire.PartialSigWithNonce{
×
UNCOV
83
                PartialSig: localSig,
×
UNCOV
84
                Nonce:      m.localNonce.PubNonce,
×
UNCOV
85
        }
×
UNCOV
86
        remotePartialSig := &lnwire.PartialSigWithNonce{
×
UNCOV
87
                PartialSig: remoteSig,
×
UNCOV
88
                Nonce:      m.remoteNonce.PubNonce,
×
UNCOV
89
        }
×
UNCOV
90

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

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

×
UNCOV
102
        // For taproot channels, we'll need to pass along the session so the
×
UNCOV
103
        // final combined signature can be created.
×
UNCOV
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.
UNCOV
109
func (m *MusigChanCloser) ClosingNonce() (*musig2.Nonces, error) {
×
UNCOV
110
        if m.localNonce != nil {
×
111
                return m.localNonce, nil
×
112
        }
×
113

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

UNCOV
122
        m.localNonce = nonce
×
UNCOV
123

×
UNCOV
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.
UNCOV
129
func (m *MusigChanCloser) InitRemoteNonce(nonce *musig2.Nonces) {
×
UNCOV
130
        m.remoteNonce = nonce
×
UNCOV
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