Skip to content

Commit 2f6e7ef

Browse files
Roasbeefguggero
authored andcommitted
funding: create new AuxFundingController interface
In this commit, we make a new `AuxFundingController` interface capable of processing messages off the wire. In addition, we can use it to abstract away details w.r.t how we obtain a `AuxFundingDesc` for a given channel. We'll now use this whenever we get a channel funding request, to make sure we pass along the custom state that a channel may require.
1 parent 54bbc25 commit 2f6e7ef

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

funding/aux_funding.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package funding
2+
3+
import (
4+
"github.com/btcsuite/btcd/chaincfg/chainhash"
5+
"github.com/lightningnetwork/lnd/channeldb"
6+
"github.com/lightningnetwork/lnd/fn"
7+
"github.com/lightningnetwork/lnd/lnwallet"
8+
"github.com/lightningnetwork/lnd/protofsm"
9+
)
10+
11+
// AuxFundingController permits the implementation of the funding of custom
12+
// channels types. The controller serves as a MsgEndpoint which allows it to
13+
// intercept custom messages, or even the regular funding messages. The
14+
// controller might also pass along an aux funding desc based on an existing
15+
// pending channel ID.
16+
type AuxFundingController interface {
17+
// MsgEndpoint is the embedded interface that signals that the funding
18+
// controller is also a message endpoint. This'll allow it to handle
19+
// custom messages specific to the funding type.
20+
protofsm.MsgEndpoint
21+
22+
// DescFromPendingChanID takes a pending channel ID, that may already be
23+
// known due to prior custom channel messages, and maybe returns an aux
24+
// funding desc which can be used to modify how a channel is funded.
25+
DescFromPendingChanID(pid PendingChanID,
26+
openChan *channeldb.OpenChannel,
27+
localKeyRing, remoteKeyRing lnwallet.CommitmentKeyRing,
28+
initiator bool) (fn.Option[lnwallet.AuxFundingDesc], error)
29+
30+
// DeriveTapscriptRoot takes a pending channel ID and maybe returns a
31+
// tapscript root that should be used when creating any MuSig2 sessions
32+
// for a channel.
33+
DeriveTapscriptRoot(PendingChanID) (fn.Option[chainhash.Hash], error)
34+
35+
// ChannelReady is called when a channel has been fully opened (multiple
36+
// confirmations) and is ready to be used. This can be used to perform
37+
// any final setup or cleanup.
38+
ChannelReady(openChan *channeldb.OpenChannel) error
39+
40+
// ChannelFinalized is called when a channel has been fully finalized.
41+
// In this state, we've received the commitment sig from the remote
42+
// party, so we are safe to broadcast the funding transaction.
43+
ChannelFinalized(PendingChanID) error
44+
}
45+
46+
// descFromPendingChanID takes a pending channel ID, that may already be known
47+
// due to prior custom channel messages, and maybe returns an aux funding desc
48+
// which can be used to modify how a channel is funded.
49+
func descFromPendingChanID(controller fn.Option[AuxFundingController],
50+
chanID PendingChanID, openChan *channeldb.OpenChannel,
51+
localKeyRing, remoteKeyRing lnwallet.CommitmentKeyRing,
52+
initiator bool) (fn.Option[lnwallet.AuxFundingDesc], error) {
53+
54+
var result fn.Option[lnwallet.AuxFundingDesc]
55+
mapErr := fn.MapOptionZ(controller, func(c AuxFundingController) error {
56+
var err error
57+
result, err = c.DescFromPendingChanID(
58+
chanID, openChan, localKeyRing, remoteKeyRing,
59+
initiator,
60+
)
61+
62+
return err
63+
})
64+
65+
return result, mapErr
66+
}
67+
68+
// deriveTapscriptRoot takes a pending channel ID and maybe returns a
69+
// tapscript root that should be used when creating any MuSig2 sessions for a
70+
// channel.
71+
func deriveTapscriptRoot(controller fn.Option[AuxFundingController],
72+
chanID PendingChanID) (fn.Option[chainhash.Hash], error) {
73+
74+
var result fn.Option[chainhash.Hash]
75+
mapErr := fn.MapOptionZ(controller, func(c AuxFundingController) error {
76+
var err error
77+
result, err = c.DeriveTapscriptRoot(chanID)
78+
return err
79+
})
80+
81+
return result, mapErr
82+
}

funding/manager.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,12 @@ type Config struct {
543543
// AuxLeafStore is an optional store that can be used to store auxiliary
544544
// leaves for certain custom channel types.
545545
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
546+
547+
// AuxFundingController is an optional controller that can be used to
548+
// modify the way we handle certain custom channel types. It's also
549+
// able to automatically handle new custom protocol messages related to
550+
// the funding process.
551+
AuxFundingController fn.Option[AuxFundingController]
546552
}
547553

548554
// Manager acts as an orchestrator/bridge between the wallet's
@@ -1613,6 +1619,18 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
16131619
return
16141620
}
16151621

1622+
// At this point, if we have an AuxFundingController active, we'll
1623+
// check to see if we have a special tapscript root to use in our
1624+
// MuSig funding output.
1625+
tapscriptRoot, err := deriveTapscriptRoot(
1626+
f.cfg.AuxFundingController, msg.PendingChannelID,
1627+
)
1628+
if err != nil {
1629+
err = fmt.Errorf("error deriving tapscript root: %w", err)
1630+
log.Error(err)
1631+
f.failFundingFlow(peer, cid, err)
1632+
}
1633+
16161634
req := &lnwallet.InitFundingReserveMsg{
16171635
ChainHash: &msg.ChainHash,
16181636
PendingChanID: msg.PendingChannelID,
@@ -1629,6 +1647,7 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
16291647
ZeroConf: zeroConf,
16301648
OptionScidAlias: scid,
16311649
ScidAliasFeature: scidFeatureVal,
1650+
TapscriptRoot: tapscriptRoot,
16321651
}
16331652

16341653
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
@@ -4603,6 +4622,20 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
46034622
scidFeatureVal = true
46044623
}
46054624

4625+
// At this point, if we have an AuxFundingController active, we'll check
4626+
// to see if we have a special tapscript root to use in our MuSig2
4627+
// funding output.
4628+
tapscriptRoot, err := deriveTapscriptRoot(
4629+
f.cfg.AuxFundingController, chanID,
4630+
)
4631+
if err != nil {
4632+
err = fmt.Errorf("error deriving tapscript root: %w", err)
4633+
log.Error(err)
4634+
msg.Err <- err
4635+
4636+
return
4637+
}
4638+
46064639
req := &lnwallet.InitFundingReserveMsg{
46074640
ChainHash: &msg.ChainHash,
46084641
PendingChanID: chanID,
@@ -4626,6 +4659,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
46264659
OptionScidAlias: scid,
46274660
ScidAliasFeature: scidFeatureVal,
46284661
Memo: msg.Memo,
4662+
TapscriptRoot: tapscriptRoot,
46294663
}
46304664

46314665
reservation, err := f.cfg.Wallet.InitChannelReservation(req)

0 commit comments

Comments
 (0)