funding+lnwallet: finish hook up new aux funding flow
For the initiator, once we get the signal that the PSBT has been finalized, we'll call into the aux funder to get the funding desc. For the responder, once we receive the funding_created message, we'll do the same. We now also have local+remote aux leaves for the commitment transaction. Some old TODO comments that in retrospect aren't required anymore are removed as well.
This commit is contained in:
1 parent
7ec48a5054
commit
bcb66585d4
4 files changed
+181
-19
No files matched your search
+90
-6
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
@@ -25,7 +26,7 @@ type CommitmentType int
|
||||
const (
|
||||
// CommitmentTypeLegacy is the legacy commitment format with a tweaked
|
||||
// to_remote key.
|
||||
CommitmentTypeLegacy = iota
|
||||
CommitmentTypeLegacy CommitmentType = iota
|
||||
|
||||
// CommitmentTypeTweakless is a newer commitment format where the
|
||||
// to_remote key is static.
|
||||
@@ -100,6 +101,28 @@ func (c CommitmentType) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// ReservationState is a type that represents the current state of a channel
|
||||
// reservation within the funding workflow.
|
||||
type ReservationState int
|
||||
|
||||
const (
|
||||
// WaitingToSend is the state either the funder/fundee is in after
|
||||
// creating a reservation, but hasn't sent a message yet.
|
||||
WaitingToSend ReservationState = iota
|
||||
|
||||
// SentOpenChannel is the state the funder is in after sending the
|
||||
// OpenChannel message.
|
||||
SentOpenChannel
|
||||
|
||||
// SentAcceptChannel is the state the fundee is in after sending the
|
||||
// AcceptChannel message.
|
||||
SentAcceptChannel
|
||||
|
||||
// SentFundingCreated is the state the funder is in after sending the
|
||||
// FundingCreated message.
|
||||
SentFundingCreated
|
||||
)
|
||||
|
||||
// ChannelContribution is the primary constituent of the funding workflow
|
||||
// within lnwallet. Each side first exchanges their respective contributions
|
||||
// along with channel specific parameters like the min fee/KB. Once
|
||||
@@ -223,6 +246,8 @@ type ChannelReservation struct {
|
||||
nextRevocationKeyLoc keychain.KeyLocator
|
||||
|
||||
musigSessions *MusigPairSession
|
||||
|
||||
state ReservationState
|
||||
}
|
||||
|
||||
// NewChannelReservation creates a new channel reservation. This function is
|
||||
@@ -459,6 +484,7 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
reservationID: id,
|
||||
wallet: wallet,
|
||||
chanFunder: req.ChanFunder,
|
||||
state: WaitingToSend,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -470,6 +496,22 @@ func (r *ChannelReservation) AddAlias(scid lnwire.ShortChannelID) {
|
||||
r.partialState.ShortChannelID = scid
|
||||
}
|
||||
|
||||
// SetState sets the ReservationState.
|
||||
func (r *ChannelReservation) SetState(state ReservationState) {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
r.state = state
|
||||
}
|
||||
|
||||
// State returns the current ReservationState.
|
||||
func (r *ChannelReservation) State() ReservationState {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
|
||||
return r.state
|
||||
}
|
||||
|
||||
// SetNumConfsRequired sets the number of confirmations that are required for
|
||||
// the ultimate funding transaction before the channel can be considered open.
|
||||
// This is distinct from the main reservation workflow as it allows
|
||||
@@ -610,12 +652,15 @@ func (r *ChannelReservation) IsCannedShim() bool {
|
||||
}
|
||||
|
||||
// ProcessPsbt continues a previously paused funding flow that involves PSBT to
|
||||
// construct the funding transaction. This method can be called once the PSBT is
|
||||
// finalized and the signed transaction is available.
|
||||
func (r *ChannelReservation) ProcessPsbt() error {
|
||||
// construct the funding transaction. This method can be called once the PSBT
|
||||
// is finalized and the signed transaction is available.
|
||||
func (r *ChannelReservation) ProcessPsbt(
|
||||
auxFundingDesc fn.Option[AuxFundingDesc]) error {
|
||||
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
r.wallet.msgChan <- &continueContributionMsg{
|
||||
auxFundingDesc: auxFundingDesc,
|
||||
pendingFundingID: r.reservationID,
|
||||
err: errChan,
|
||||
}
|
||||
@@ -717,8 +762,10 @@ func (r *ChannelReservation) CompleteReservation(fundingInputScripts []*input.Sc
|
||||
// available via the .OurSignatures() method. As this method should only be
|
||||
// called as a response to a single funder channel, only a commitment signature
|
||||
// will be populated.
|
||||
func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoint,
|
||||
commitSig input.Signature) (*channeldb.OpenChannel, error) {
|
||||
func (r *ChannelReservation) CompleteReservationSingle(
|
||||
fundingPoint *wire.OutPoint, commitSig input.Signature,
|
||||
auxFundingDesc fn.Option[AuxFundingDesc]) (*channeldb.OpenChannel,
|
||||
error) {
|
||||
|
||||
errChan := make(chan error, 1)
|
||||
completeChan := make(chan *channeldb.OpenChannel, 1)
|
||||
@@ -728,6 +775,7 @@ func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoi
|
||||
fundingOutpoint: fundingPoint,
|
||||
theirCommitmentSig: commitSig,
|
||||
completeChan: completeChan,
|
||||
auxFundingDesc: auxFundingDesc,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
@@ -813,6 +861,42 @@ func (r *ChannelReservation) Cancel() error {
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
// ChanState the current open channel state.
|
||||
func (r *ChannelReservation) ChanState() *channeldb.OpenChannel {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
|
||||
return r.partialState
|
||||
}
|
||||
|
||||
// CommitmentKeyRings returns the local+remote key ring used for the very first
|
||||
// commitment transaction both parties.
|
||||
//
|
||||
//nolint:lll
|
||||
func (r *ChannelReservation) CommitmentKeyRings() lntypes.Dual[CommitmentKeyRing] {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
|
||||
chanType := r.partialState.ChanType
|
||||
ourChanCfg := r.ourContribution.ChannelConfig
|
||||
theirChanCfg := r.theirContribution.ChannelConfig
|
||||
|
||||
localKeys := DeriveCommitmentKeys(
|
||||
r.ourContribution.FirstCommitmentPoint, lntypes.Local, chanType,
|
||||
ourChanCfg, theirChanCfg,
|
||||
)
|
||||
|
||||
remoteKeys := DeriveCommitmentKeys(
|
||||
r.theirContribution.FirstCommitmentPoint, lntypes.Remote,
|
||||
chanType, ourChanCfg, theirChanCfg,
|
||||
)
|
||||
|
||||
return lntypes.Dual[CommitmentKeyRing]{
|
||||
Local: *localKeys,
|
||||
Remote: *remoteKeys,
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyConstraints is a helper function that can be used to check the sanity
|
||||
// of various channel constraints.
|
||||
func VerifyConstraints(bounds *channeldb.ChannelStateBounds,
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
@@ -940,6 +941,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
|
||||
fundingPoint := aliceChanReservation.FundingOutpoint()
|
||||
_, err = bobChanReservation.CompleteReservationSingle(
|
||||
fundingPoint, aliceCommitSig,
|
||||
fn.None[lnwallet.AuxFundingDesc](),
|
||||
)
|
||||
require.NoError(t, err, "bob unable to consume single reservation")
|
||||
|
||||
|
||||
+37
-1
@@ -1844,6 +1844,26 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
chanState := pendingReservation.partialState
|
||||
|
||||
// If we have an aux funding desc, then we can use it to populate some
|
||||
// of the optional, but opaque TLV blobs we'll carry for the channel.
|
||||
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
|
||||
return desc.CustomFundingBlob
|
||||
})(req.auxFundingDesc)
|
||||
|
||||
chanState.LocalCommitment.CustomBlob = fn.MapOption(
|
||||
func(desc AuxFundingDesc) tlv.Blob {
|
||||
return desc.CustomLocalCommitBlob
|
||||
},
|
||||
)(req.auxFundingDesc)
|
||||
|
||||
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
|
||||
func(desc AuxFundingDesc) tlv.Blob {
|
||||
return desc.CustomRemoteCommitBlob
|
||||
},
|
||||
)(req.auxFundingDesc)
|
||||
|
||||
ourContribution := pendingReservation.ourContribution
|
||||
theirContribution := pendingReservation.theirContribution
|
||||
chanPoint := pendingReservation.partialState.FundingOutpoint
|
||||
@@ -1902,7 +1922,6 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
|
||||
// Store their current commitment point. We'll need this after the
|
||||
// first state transition in order to verify the authenticity of the
|
||||
// revocation.
|
||||
chanState := pendingReservation.partialState
|
||||
chanState.RemoteCurrentRevocation = theirContribution.FirstCommitmentPoint
|
||||
|
||||
// Create the txin to our commitment transaction; required to construct
|
||||
@@ -2349,6 +2368,23 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
|
||||
defer pendingReservation.Unlock()
|
||||
|
||||
chanState := pendingReservation.partialState
|
||||
|
||||
// If we have an aux funding desc, then we can use it to populate some
|
||||
// of the optional, but opaque TLV blobs we'll carry for the channel.
|
||||
chanState.CustomBlob = fn.MapOption(func(desc AuxFundingDesc) tlv.Blob {
|
||||
return desc.CustomFundingBlob
|
||||
})(req.auxFundingDesc)
|
||||
chanState.LocalCommitment.CustomBlob = fn.MapOption(
|
||||
func(desc AuxFundingDesc) tlv.Blob {
|
||||
return desc.CustomLocalCommitBlob
|
||||
},
|
||||
)(req.auxFundingDesc)
|
||||
chanState.RemoteCommitment.CustomBlob = fn.MapOption(
|
||||
func(desc AuxFundingDesc) tlv.Blob {
|
||||
return desc.CustomRemoteCommitBlob
|
||||
},
|
||||
)(req.auxFundingDesc)
|
||||
|
||||
chanType := pendingReservation.partialState.ChanType
|
||||
chanState.FundingOutpoint = *req.fundingOutpoint
|
||||
fundingTxIn := wire.NewTxIn(req.fundingOutpoint, nil, nil)
|
||||
|
||||
Reference in new issue
Block a user