Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions channeldb/models/channel_edge_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/fn"
)

// ChannelEdgeInfo represents a fully authenticated channel along with all its
Expand Down Expand Up @@ -62,6 +63,11 @@ type ChannelEdgeInfo struct {
// the value output in the outpoint that created this channel.
Capacity btcutil.Amount

// TapscriptRoot is the optional Merkle root of the tapscript tree if
// this channel is a taproot channel that also commits to a tapscript
// tree (custom channel).
TapscriptRoot fn.Option[chainhash.Hash]

// ExtraOpaqueData is the set of data that was appended to this
// message, some of which we may not actually know how to iterate or
// parse. By holding onto this data, we ensure that we're able to
Expand Down
12 changes: 12 additions & 0 deletions config_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/funding"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/kvdb"
Expand All @@ -44,6 +45,7 @@ import (
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
"github.com/lightningnetwork/lnd/lnwallet/rpcwallet"
"github.com/lightningnetwork/lnd/macaroons"
"github.com/lightningnetwork/lnd/protofsm"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/rpcperms"
"github.com/lightningnetwork/lnd/signal"
Expand Down Expand Up @@ -162,6 +164,16 @@ type AuxComponents struct {
// TrafficShaper is an optional traffic shaper that can be used to
// control the outgoing channel of a payment.
TrafficShaper fn.Option[routing.TlvTrafficShaper]

// MsgRouter is an optional message router that if set will be used in
// place of a new blank default message router.
MsgRouter fn.Option[protofsm.MsgRouter]

// AuxFundingController is an optional controller that can be used to
// modify the way we handle certain custom chanenl types. It's also
// able to automatically handle new custom protocol messages related to
// the funding process.
AuxFundingController fn.Option[funding.AuxFundingController]
}

// DefaultWalletImpl is the default implementation of our normal, btcwallet
Expand Down
19 changes: 16 additions & 3 deletions discovery/gossiper.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channeldb/models"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnpeer"
Expand Down Expand Up @@ -82,9 +83,10 @@ var (
// can provide that serve useful when processing a specific network
// announcement.
type optionalMsgFields struct {
capacity *btcutil.Amount
channelPoint *wire.OutPoint
remoteAlias *lnwire.ShortChannelID
capacity *btcutil.Amount
channelPoint *wire.OutPoint
remoteAlias *lnwire.ShortChannelID
tapscriptRoot fn.Option[chainhash.Hash]
}

// apply applies the optional fields within the functional options.
Expand Down Expand Up @@ -115,6 +117,14 @@ func ChannelPoint(op wire.OutPoint) OptionalMsgField {
}
}

// TapscriptRoot is an optional field that lets the gossiper know of the root of
// the tapscript tree for a custom channel.
func TapscriptRoot(root fn.Option[chainhash.Hash]) OptionalMsgField {
return func(f *optionalMsgFields) {
f.tapscriptRoot = root
}
}

// RemoteAlias is an optional field that lets the gossiper know that a locally
// sent channel update is actually an update for the peer that should replace
// the ShortChannelID field with the remote's alias. This is only used for
Expand Down Expand Up @@ -2513,6 +2523,9 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
cp := *nMsg.optionalMsgFields.channelPoint
edge.ChannelPoint = cp
}

// Optional tapscript root for custom channels.
edge.TapscriptRoot = nMsg.optionalMsgFields.tapscriptRoot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for other nodes in the network what purpose does this field have?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For being able to verify the pkScript of the channel. Without the tapscript root the validation nodes would assume 2-of-2 MuSig2 with BIP-0086 tweak.

}

log.Debugf("Adding edge for short_chan_id: %v",
Expand Down
82 changes: 82 additions & 0 deletions funding/aux_funding.go
Original file line number Diff line number Diff line change
@@ -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
}
Loading