diff --git a/lnwallet/chanfunding/psbt_assembler.go b/lnwallet/chanfunding/psbt_assembler.go index 1317d36c..3498785e 100644 --- a/lnwallet/chanfunding/psbt_assembler.go +++ b/lnwallet/chanfunding/psbt_assembler.go @@ -139,6 +139,11 @@ type PsbtIntent struct { // NOTE: This channel must always be buffered. PsbtReady chan error + // shouldPublish specifies if the intent assumes its assembler should + // publish the transaction once the channel funding has completed. If + // this is set to false then the finalize step can be skipped. + shouldPublish bool + // signalPsbtReady is a Once guard to make sure the PsbtReady channel is // only closed exactly once. signalPsbtReady sync.Once @@ -449,6 +454,12 @@ func (i *PsbtIntent) Outputs() []*wire.TxOut { } } +// ShouldPublishFundingTX returns true if the intent assumes that its assembler +// should publish the funding TX once the funding negotiation is complete. +func (i *PsbtIntent) ShouldPublishFundingTX() bool { + return i.shouldPublish +} + // PsbtAssembler is a type of chanfunding.Assembler wherein the funding // transaction is constructed outside of lnd by using partially signed bitcoin // transactions (PSBT). @@ -500,10 +511,11 @@ func (p *PsbtAssembler) ProvisionChannel(req *Request) (Intent, error) { ShimIntent: ShimIntent{ localFundingAmt: p.fundingAmt, }, - State: PsbtShimRegistered, - BasePsbt: p.basePsbt, - PsbtReady: make(chan error, 1), - netParams: p.netParams, + State: PsbtShimRegistered, + BasePsbt: p.basePsbt, + PsbtReady: make(chan error, 1), + shouldPublish: p.shouldPublish, + netParams: p.netParams, } // A simple sanity check to ensure the provisioned request matches the diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index b0ba460f..e15b1512 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -1454,9 +1454,11 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) { // is needed to construct and publish the full funding transaction. intent := pendingReservation.fundingIntent if psbtIntent, ok := intent.(*chanfunding.PsbtIntent); ok { - // With our keys bound, we can now construct+sign the final - // funding transaction and also obtain the chanPoint that - // creates the channel. + // With our keys bound, we can now construct and possibly sign + // the final funding transaction and also obtain the chanPoint + // that creates the channel. We _have_ to call CompileFundingTx + // even if we don't publish ourselves as that sets the actual + // funding outpoint in stone for this channel. fundingTx, err := psbtIntent.CompileFundingTx() if err != nil { req.err <- fmt.Errorf("unable to construct funding "+ @@ -1470,23 +1472,26 @@ func (l *LightningWallet) handleChanPointReady(req *continueContributionMsg) { return } - // Finally, we'll populate the relevant information in our - // pendingReservation so the rest of the funding flow can - // continue as normal. - pendingReservation.fundingTx = fundingTx pendingReservation.partialState.FundingOutpoint = *chanPointPtr chanPoint = *chanPointPtr - pendingReservation.ourFundingInputScripts = make( - []*input.Script, 0, len(ourContribution.Inputs), - ) - for _, txIn := range fundingTx.TxIn { - pendingReservation.ourFundingInputScripts = append( - pendingReservation.ourFundingInputScripts, - &input.Script{ - Witness: txIn.Witness, - SigScript: txIn.SignatureScript, - }, + + // Finally, we'll populate the relevant information in our + // pendingReservation so the rest of the funding flow can + // continue as normal in case we are going to publish ourselves. + if psbtIntent.ShouldPublishFundingTX() { + pendingReservation.fundingTx = fundingTx + pendingReservation.ourFundingInputScripts = make( + []*input.Script, 0, len(ourContribution.Inputs), ) + for _, txIn := range fundingTx.TxIn { + pendingReservation.ourFundingInputScripts = append( + pendingReservation.ourFundingInputScripts, + &input.Script{ + Witness: txIn.Witness, + SigScript: txIn.SignatureScript, + }, + ) + } } }