mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-31 16:09:02 +02:00
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.
This commit is contained in:
parent
73aa617d9b
commit
17e9758ee7
@ -2,6 +2,7 @@ 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"
|
||||
@ -17,16 +18,46 @@ type AuxFundingController interface {
|
||||
// handle custom messages specific to the funding type.
|
||||
protofsm.MsgEndpoint
|
||||
|
||||
// DescPendingChanID takes a pending channel ID, that may already be
|
||||
// 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.
|
||||
//
|
||||
// TODO(roasbeef): erorr on validation if fail due to invalid root
|
||||
// match?
|
||||
DescFromPendingChanID(PendingChanID) fn.Option[lnwallet.AuxFundingDesc]
|
||||
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]
|
||||
DeriveTapscriptRoot(PendingChanID) (fn.Option[chainhash.Hash], 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) {
|
||||
|
||||
if controller.IsNone() {
|
||||
return fn.None[lnwallet.AuxFundingDesc](), nil
|
||||
}
|
||||
|
||||
return controller.UnsafeFromSome().DescFromPendingChanID(
|
||||
chanID, openChan, localKeyRing, remoteKeyRing, initiator,
|
||||
)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
if controller.IsNone() {
|
||||
return fn.None[chainhash.Hash](), nil
|
||||
}
|
||||
|
||||
return controller.UnsafeFromSome().DeriveTapscriptRoot(chanID)
|
||||
}
|
||||
|
@ -99,7 +99,6 @@ const (
|
||||
// you and limitless channel size (apart from 21 million cap).
|
||||
MaxBtcFundingAmountWumbo = btcutil.Amount(1000000000)
|
||||
|
||||
// TODO(roasbeef): tune.
|
||||
msgBufferSize = 50
|
||||
|
||||
// MaxWaitNumBlocksFundingConf is the maximum number of blocks to wait
|
||||
@ -1622,11 +1621,14 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
|
||||
// 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 := fn.MapOption(
|
||||
func(a AuxFundingController) fn.Option[chainhash.Hash] {
|
||||
return a.DeriveTapscriptRoot(msg.PendingChannelID)
|
||||
},
|
||||
)(f.cfg.AuxFundingController)
|
||||
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,
|
||||
@ -1644,7 +1646,7 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
|
||||
ZeroConf: zeroConf,
|
||||
OptionScidAlias: scid,
|
||||
ScidAliasFeature: scidFeatureVal,
|
||||
TapscriptRoot: fn.FlattenOption(tapscriptRoot),
|
||||
TapscriptRoot: tapscriptRoot,
|
||||
}
|
||||
|
||||
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
|
||||
@ -2241,10 +2243,27 @@ func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
|
||||
return
|
||||
}
|
||||
|
||||
// At this point, we'll see if there's an AuxFundingDesc we
|
||||
// need to deliver so the funding process can continue
|
||||
// properly.
|
||||
chanState := resCtx.reservation.ChanState()
|
||||
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
|
||||
auxFundingDesc, err := descFromPendingChanID(
|
||||
f.cfg.AuxFundingController, cid.tempChanID, chanState,
|
||||
*localKeys, *remoteKeys, true,
|
||||
)
|
||||
if err != nil {
|
||||
failFlow("error continuing PSBT flow", err)
|
||||
return
|
||||
}
|
||||
|
||||
// A non-nil error means we can continue the funding flow.
|
||||
// Notify the wallet so it can prepare everything we need to
|
||||
// continue.
|
||||
err = resCtx.reservation.ProcessPsbt()
|
||||
//
|
||||
// We'll also pass along the aux funding controller as well,
|
||||
// which may be used to help process the finalized PSBT.
|
||||
err = resCtx.reservation.ProcessPsbt(auxFundingDesc)
|
||||
if err != nil {
|
||||
failFlow("error continuing PSBT flow", err)
|
||||
return
|
||||
@ -2253,8 +2272,8 @@ func (f *Manager) waitForPsbt(intent *chanfunding.PsbtIntent,
|
||||
// We are now ready to continue the funding flow.
|
||||
f.continueFundingAccept(resCtx, cid)
|
||||
|
||||
// Handle a server shutdown as well because the reservation won't
|
||||
// survive a restart as it's in memory only.
|
||||
// Handle a server shutdown as well because the reservation won't
|
||||
// survive a restart as it's in memory only.
|
||||
case <-f.quit:
|
||||
log.Errorf("Unable to handle funding accept message "+
|
||||
"for peer_key=%x, pending_chan_id=%x: funding manager "+
|
||||
@ -2308,6 +2327,10 @@ func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
|
||||
// funding flow fails.
|
||||
cid.setChanID(channelID)
|
||||
|
||||
// Now that we're ready to resume the funding flow, we'll call into the
|
||||
// aux controller with the final funding details so we can obtain the
|
||||
// funding descs we need.
|
||||
|
||||
// Send the FundingCreated msg.
|
||||
fundingCreated := &lnwire.FundingCreated{
|
||||
PendingChannelID: cid.tempChanID,
|
||||
@ -2370,7 +2393,6 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
|
||||
// final funding transaction, as well as a signature for our version of
|
||||
// the commitment transaction. So at this point, we can validate the
|
||||
// initiator's commitment transaction, then send our own if it's valid.
|
||||
// TODO(roasbeef): make case (p vs P) consistent throughout
|
||||
fundingOut := msg.FundingPoint
|
||||
log.Infof("completing pending_id(%x) with ChannelPoint(%v)",
|
||||
pendingChanID[:], fundingOut)
|
||||
@ -2402,16 +2424,33 @@ func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, we'll see if there's an AuxFundingDesc we need to
|
||||
// deliver so the funding process can continue properly.
|
||||
chanState := resCtx.reservation.ChanState()
|
||||
localKeys, remoteKeys := resCtx.reservation.CommitmentKeyRings()
|
||||
auxFundingDesc, err := descFromPendingChanID(
|
||||
f.cfg.AuxFundingController, cid.tempChanID, chanState,
|
||||
*localKeys, *remoteKeys, true,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("error continuing PSBT flow: %v", err)
|
||||
f.failFundingFlow(peer, cid, err)
|
||||
return
|
||||
}
|
||||
|
||||
// With all the necessary data available, attempt to advance the
|
||||
// funding workflow to the next stage. If this succeeds then the
|
||||
// funding transaction will broadcast after our next message.
|
||||
// CompleteReservationSingle will also mark the channel as 'IsPending'
|
||||
// in the database.
|
||||
//
|
||||
// We'll also directly pass in the AuxFundiner controller as well,
|
||||
// which may be used by the reservation system to finalize funding our
|
||||
// side.
|
||||
completeChan, err := resCtx.reservation.CompleteReservationSingle(
|
||||
&fundingOut, commitSig,
|
||||
&fundingOut, commitSig, auxFundingDesc,
|
||||
)
|
||||
if err != nil {
|
||||
// TODO(roasbeef): better error logging: peerID, channelID, etc.
|
||||
log.Errorf("unable to complete single reservation: %v", err)
|
||||
f.failFundingFlow(peer, cid, err)
|
||||
return
|
||||
@ -2722,9 +2761,6 @@ func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
|
||||
|
||||
// Send an update to the upstream client that the negotiation process
|
||||
// is over.
|
||||
//
|
||||
// TODO(roasbeef): add abstraction over updates to accommodate
|
||||
// long-polling, or SSE, etc.
|
||||
upd := &lnrpc.OpenStatusUpdate{
|
||||
Update: &lnrpc.OpenStatusUpdate_ChanPending{
|
||||
ChanPending: &lnrpc.PendingUpdate{
|
||||
@ -4429,7 +4465,6 @@ func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
|
||||
|
||||
// InitFundingWorkflow sends a message to the funding manager instructing it
|
||||
// to initiate a single funder workflow with the source peer.
|
||||
// TODO(roasbeef): re-visit blocking nature..
|
||||
func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) {
|
||||
f.fundingRequests <- msg
|
||||
}
|
||||
@ -4622,11 +4657,14 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
|
||||
// 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 := fn.MapOption(
|
||||
func(a AuxFundingController) fn.Option[chainhash.Hash] {
|
||||
return a.DeriveTapscriptRoot(chanID)
|
||||
},
|
||||
)(f.cfg.AuxFundingController)
|
||||
tapscriptRoot, err := deriveTapscriptRoot(
|
||||
f.cfg.AuxFundingController, chanID,
|
||||
)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error deriving tapscript root: %w", err)
|
||||
msg.Err <- err
|
||||
return
|
||||
}
|
||||
|
||||
req := &lnwallet.InitFundingReserveMsg{
|
||||
ChainHash: &msg.ChainHash,
|
||||
@ -4651,7 +4689,7 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
|
||||
OptionScidAlias: scid,
|
||||
ScidAliasFeature: scidFeatureVal,
|
||||
Memo: msg.Memo,
|
||||
TapscriptRoot: fn.FlattenOption(tapscriptRoot),
|
||||
TapscriptRoot: tapscriptRoot,
|
||||
}
|
||||
|
||||
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
|
||||
|
@ -218,10 +218,14 @@ type ChannelReservation struct {
|
||||
|
||||
fundingIntent chanfunding.Intent
|
||||
|
||||
// initAuxLeaves is an optional set of aux commitment leaves that'll
|
||||
// modify the way we construct the commitment transaction, in
|
||||
// localInitAuxLeaves is an optional set of aux commitment leaves
|
||||
// that'll modify the way we construct the commitment transaction, in
|
||||
// particular the tapscript leaves.
|
||||
initAuxLeaves fn.Option[CommitAuxLeaves]
|
||||
localInitAuxLeaves fn.Option[CommitAuxLeaves]
|
||||
|
||||
// remoteInitAuxLeaves is an optional set of aux commitment leaves for
|
||||
// the remote party.
|
||||
remoteInitAuxLeaves fn.Option[CommitAuxLeaves]
|
||||
|
||||
// nextRevocationKeyLoc stores the key locator information for this
|
||||
// channel.
|
||||
@ -608,12 +612,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,
|
||||
}
|
||||
@ -715,8 +722,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)
|
||||
@ -726,6 +735,7 @@ func (r *ChannelReservation) CompleteReservationSingle(fundingPoint *wire.OutPoi
|
||||
fundingOutpoint: fundingPoint,
|
||||
theirCommitmentSig: commitSig,
|
||||
completeChan: completeChan,
|
||||
auxFundingDesc: auxFundingDesc,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
@ -811,6 +821,36 @@ 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.
|
||||
func (r *ChannelReservation) CommitmentKeyRings() (*CommitmentKeyRing, *CommitmentKeyRing) {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
|
||||
chanType := r.partialState.ChanType
|
||||
ourChanCfg := r.ourContribution.ChannelConfig
|
||||
theirChanCfg := r.theirContribution.ChannelConfig
|
||||
|
||||
localKeys := DeriveCommitmentKeys(
|
||||
r.ourContribution.FirstCommitmentPoint, true, chanType,
|
||||
ourChanCfg, theirChanCfg,
|
||||
)
|
||||
|
||||
remoteKeys := DeriveCommitmentKeys(
|
||||
r.theirContribution.FirstCommitmentPoint, false, chanType,
|
||||
ourChanCfg, theirChanCfg,
|
||||
)
|
||||
|
||||
return localKeys, remoteKeys
|
||||
}
|
||||
|
||||
// VerifyConstraints is a helper function that can be used to check the sanity
|
||||
// of various channel constraints.
|
||||
func VerifyConstraints(c *channeldb.ChannelConstraints,
|
||||
|
@ -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"
|
||||
@ -936,6 +937,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")
|
||||
|
||||
|
@ -108,9 +108,13 @@ type AuxFundingDesc struct {
|
||||
// first commitment entry for the remote party.
|
||||
CustomRemoteCommitBlob tlv.Blob
|
||||
|
||||
// InitAuxLeaves is the set of aux leaves that'll be used for the very
|
||||
// first commitment state.
|
||||
InitAuxLeaves CommitAuxLeaves
|
||||
// LocalInitAuxLeaves is the set of aux leaves that'll be used for our
|
||||
// very first commitment state.
|
||||
LocalInitAuxLeaves CommitAuxLeaves
|
||||
|
||||
// RemoteInitAuxLeaves is the set of aux leaves that'll be used for the
|
||||
// very first commitment state for the remote party.
|
||||
RemoteInitAuxLeaves CommitAuxLeaves
|
||||
}
|
||||
|
||||
// InitFundingReserveMsg is the first message sent to initiate the workflow
|
||||
@ -276,6 +280,8 @@ type addContributionMsg struct {
|
||||
type continueContributionMsg struct {
|
||||
pendingFundingID uint64
|
||||
|
||||
auxFundingDesc fn.Option[AuxFundingDesc]
|
||||
|
||||
// NOTE: In order to avoid deadlocks, this channel MUST be buffered.
|
||||
err chan error
|
||||
}
|
||||
@ -331,6 +337,8 @@ type addCounterPartySigsMsg struct {
|
||||
type addSingleFunderSigsMsg struct {
|
||||
pendingFundingID uint64
|
||||
|
||||
auxFundingDesc fn.Option[AuxFundingDesc]
|
||||
|
||||
// fundingOutpoint is the outpoint of the completed funding
|
||||
// transaction as assembled by the workflow initiator.
|
||||
fundingOutpoint *wire.OutPoint
|
||||
@ -1474,7 +1482,8 @@ func (l *LightningWallet) handleFundingCancelRequest(req *fundingReserveCancelMs
|
||||
// createCommitOpts is a struct that holds the options for creating a a new
|
||||
// commitment transaction.
|
||||
type createCommitOpts struct {
|
||||
auxLeaves fn.Option[CommitAuxLeaves]
|
||||
localAuxLeaves fn.Option[CommitAuxLeaves]
|
||||
remoteAuxLeaves fn.Option[CommitAuxLeaves]
|
||||
}
|
||||
|
||||
// defaultCommitOpts returns a new createCommitOpts with default values.
|
||||
@ -1484,9 +1493,12 @@ func defaultCommitOpts() createCommitOpts {
|
||||
|
||||
// WithAuxLeaves is a functional option that can be used to set the aux leaves
|
||||
// for a new commitment transaction.
|
||||
func WithAuxLeaves(leaves fn.Option[CommitAuxLeaves]) CreateCommitOpt {
|
||||
func WithAuxLeaves(localLeaves,
|
||||
remoteLeaves fn.Option[CommitAuxLeaves]) CreateCommitOpt {
|
||||
|
||||
return func(o *createCommitOpts) {
|
||||
o.auxLeaves = leaves
|
||||
o.localAuxLeaves = localLeaves
|
||||
o.remoteAuxLeaves = remoteLeaves
|
||||
}
|
||||
}
|
||||
|
||||
@ -1521,7 +1533,7 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount,
|
||||
ourCommitTx, err := CreateCommitTx(
|
||||
chanType, fundingTxIn, localCommitmentKeys, ourChanCfg,
|
||||
theirChanCfg, localBalance, remoteBalance, 0, initiator,
|
||||
leaseExpiry, options.auxLeaves,
|
||||
leaseExpiry, options.localAuxLeaves,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -1535,7 +1547,7 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount,
|
||||
theirCommitTx, err := CreateCommitTx(
|
||||
chanType, fundingTxIn, remoteCommitmentKeys, theirChanCfg,
|
||||
ourChanCfg, remoteBalance, localBalance, 0, !initiator,
|
||||
leaseExpiry, options.auxLeaves,
|
||||
leaseExpiry, options.remoteAuxLeaves,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -1814,6 +1826,24 @@ 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
|
||||
@ -1872,7 +1902,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
|
||||
@ -1889,6 +1918,13 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
|
||||
leaseExpiry = pendingReservation.partialState.ThawHeight
|
||||
}
|
||||
|
||||
localAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
|
||||
return desc.LocalInitAuxLeaves
|
||||
})(req.auxFundingDesc)
|
||||
remoteAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
|
||||
return desc.RemoteInitAuxLeaves
|
||||
})(req.auxFundingDesc)
|
||||
|
||||
ourCommitTx, theirCommitTx, err := CreateCommitmentTxns(
|
||||
localBalance, remoteBalance, ourContribution.ChannelConfig,
|
||||
theirContribution.ChannelConfig,
|
||||
@ -1896,7 +1932,7 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) {
|
||||
theirContribution.FirstCommitmentPoint, fundingTxIn,
|
||||
pendingReservation.partialState.ChanType,
|
||||
pendingReservation.partialState.IsInitiator, leaseExpiry,
|
||||
WithAuxLeaves(pendingReservation.initAuxLeaves),
|
||||
WithAuxLeaves(localAuxLeaves, remoteAuxLeaves),
|
||||
)
|
||||
if err != nil {
|
||||
req.err <- err
|
||||
@ -2313,6 +2349,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)
|
||||
@ -2326,6 +2379,14 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
|
||||
if pendingReservation.partialState.ChanType.HasLeaseExpiration() {
|
||||
leaseExpiry = pendingReservation.partialState.ThawHeight
|
||||
}
|
||||
|
||||
localAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
|
||||
return desc.LocalInitAuxLeaves
|
||||
})(req.auxFundingDesc)
|
||||
remoteAuxLeaves := fn.MapOption(func(desc AuxFundingDesc) CommitAuxLeaves {
|
||||
return desc.RemoteInitAuxLeaves
|
||||
})(req.auxFundingDesc)
|
||||
|
||||
ourCommitTx, theirCommitTx, err := CreateCommitmentTxns(
|
||||
localBalance, remoteBalance,
|
||||
pendingReservation.ourContribution.ChannelConfig,
|
||||
@ -2334,7 +2395,7 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
|
||||
pendingReservation.theirContribution.FirstCommitmentPoint,
|
||||
*fundingTxIn, chanType,
|
||||
pendingReservation.partialState.IsInitiator, leaseExpiry,
|
||||
WithAuxLeaves(pendingReservation.initAuxLeaves),
|
||||
WithAuxLeaves(localAuxLeaves, remoteAuxLeaves),
|
||||
)
|
||||
if err != nil {
|
||||
req.err <- err
|
||||
|
Loading…
x
Reference in New Issue
Block a user