mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-22 14:22:37 +01:00
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.
This commit is contained in:
parent
54bbc25d9a
commit
2f6e7ef191
2 changed files with 116 additions and 0 deletions
82
funding/aux_funding.go
Normal file
82
funding/aux_funding.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package funding
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/protofsm"
|
||||
)
|
||||
|
||||
// AuxFundingController permits the implementation of the funding of custom
|
||||
// channels types. The controller serves as a MsgEndpoint which allows it to
|
||||
// intercept custom messages, or even the regular funding messages. The
|
||||
// controller might also pass along an aux funding desc based on an existing
|
||||
// pending channel ID.
|
||||
type AuxFundingController interface {
|
||||
// MsgEndpoint is the embedded interface that signals that the funding
|
||||
// controller is also a message endpoint. This'll allow it to handle
|
||||
// custom messages specific to the funding type.
|
||||
protofsm.MsgEndpoint
|
||||
|
||||
// DescFromPendingChanID takes a pending channel ID, that may already be
|
||||
// known due to prior custom channel messages, and maybe returns an aux
|
||||
// funding desc which can be used to modify how a channel is funded.
|
||||
DescFromPendingChanID(pid PendingChanID,
|
||||
openChan *channeldb.OpenChannel,
|
||||
localKeyRing, remoteKeyRing lnwallet.CommitmentKeyRing,
|
||||
initiator bool) (fn.Option[lnwallet.AuxFundingDesc], error)
|
||||
|
||||
// DeriveTapscriptRoot takes a pending channel ID and maybe returns a
|
||||
// tapscript root that should be used when creating any MuSig2 sessions
|
||||
// for a channel.
|
||||
DeriveTapscriptRoot(PendingChanID) (fn.Option[chainhash.Hash], error)
|
||||
|
||||
// ChannelReady is called when a channel has been fully opened (multiple
|
||||
// confirmations) and is ready to be used. This can be used to perform
|
||||
// any final setup or cleanup.
|
||||
ChannelReady(openChan *channeldb.OpenChannel) error
|
||||
|
||||
// ChannelFinalized is called when a channel has been fully finalized.
|
||||
// In this state, we've received the commitment sig from the remote
|
||||
// party, so we are safe to broadcast the funding transaction.
|
||||
ChannelFinalized(PendingChanID) error
|
||||
}
|
||||
|
||||
// descFromPendingChanID takes a pending channel ID, that may already be known
|
||||
// due to prior custom channel messages, and maybe returns an aux funding desc
|
||||
// which can be used to modify how a channel is funded.
|
||||
func descFromPendingChanID(controller fn.Option[AuxFundingController],
|
||||
chanID PendingChanID, openChan *channeldb.OpenChannel,
|
||||
localKeyRing, remoteKeyRing lnwallet.CommitmentKeyRing,
|
||||
initiator bool) (fn.Option[lnwallet.AuxFundingDesc], error) {
|
||||
|
||||
var result fn.Option[lnwallet.AuxFundingDesc]
|
||||
mapErr := fn.MapOptionZ(controller, func(c AuxFundingController) error {
|
||||
var err error
|
||||
result, err = c.DescFromPendingChanID(
|
||||
chanID, openChan, localKeyRing, remoteKeyRing,
|
||||
initiator,
|
||||
)
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
return result, mapErr
|
||||
}
|
||||
|
||||
// deriveTapscriptRoot takes a pending channel ID and maybe returns a
|
||||
// tapscript root that should be used when creating any MuSig2 sessions for a
|
||||
// channel.
|
||||
func deriveTapscriptRoot(controller fn.Option[AuxFundingController],
|
||||
chanID PendingChanID) (fn.Option[chainhash.Hash], error) {
|
||||
|
||||
var result fn.Option[chainhash.Hash]
|
||||
mapErr := fn.MapOptionZ(controller, func(c AuxFundingController) error {
|
||||
var err error
|
||||
result, err = c.DeriveTapscriptRoot(chanID)
|
||||
return err
|
||||
})
|
||||
|
||||
return result, mapErr
|
||||
}
|
|
@ -543,6 +543,12 @@ type Config struct {
|
|||
// AuxLeafStore is an optional store that can be used to store auxiliary
|
||||
// leaves for certain custom channel types.
|
||||
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
||||
|
||||
// AuxFundingController is an optional controller that can be used to
|
||||
// modify the way we handle certain custom channel types. It's also
|
||||
// able to automatically handle new custom protocol messages related to
|
||||
// the funding process.
|
||||
AuxFundingController fn.Option[AuxFundingController]
|
||||
}
|
||||
|
||||
// Manager acts as an orchestrator/bridge between the wallet's
|
||||
|
@ -1613,6 +1619,18 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
|
|||
return
|
||||
}
|
||||
|
||||
// At this point, if we have an AuxFundingController active, we'll
|
||||
// check to see if we have a special tapscript root to use in our
|
||||
// MuSig funding output.
|
||||
tapscriptRoot, err := deriveTapscriptRoot(
|
||||
f.cfg.AuxFundingController, msg.PendingChannelID,
|
||||
)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error deriving tapscript root: %w", err)
|
||||
log.Error(err)
|
||||
f.failFundingFlow(peer, cid, err)
|
||||
}
|
||||
|
||||
req := &lnwallet.InitFundingReserveMsg{
|
||||
ChainHash: &msg.ChainHash,
|
||||
PendingChanID: msg.PendingChannelID,
|
||||
|
@ -1629,6 +1647,7 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
|
|||
ZeroConf: zeroConf,
|
||||
OptionScidAlias: scid,
|
||||
ScidAliasFeature: scidFeatureVal,
|
||||
TapscriptRoot: tapscriptRoot,
|
||||
}
|
||||
|
||||
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
|
||||
|
@ -4603,6 +4622,20 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
|
|||
scidFeatureVal = true
|
||||
}
|
||||
|
||||
// At this point, if we have an AuxFundingController active, we'll check
|
||||
// to see if we have a special tapscript root to use in our MuSig2
|
||||
// funding output.
|
||||
tapscriptRoot, err := deriveTapscriptRoot(
|
||||
f.cfg.AuxFundingController, chanID,
|
||||
)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error deriving tapscript root: %w", err)
|
||||
log.Error(err)
|
||||
msg.Err <- err
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
req := &lnwallet.InitFundingReserveMsg{
|
||||
ChainHash: &msg.ChainHash,
|
||||
PendingChanID: chanID,
|
||||
|
@ -4626,6 +4659,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
|
|||
OptionScidAlias: scid,
|
||||
ScidAliasFeature: scidFeatureVal,
|
||||
Memo: msg.Memo,
|
||||
TapscriptRoot: tapscriptRoot,
|
||||
}
|
||||
|
||||
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
|
||||
|
|
Loading…
Add table
Reference in a new issue