From 258996233f9a7ffe6e21b9c68775b587caea1dd0 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 8 Jul 2020 17:12:57 -0700 Subject: [PATCH] lnwallet+rpcserver: add no_publish flag to PSBT assembler --- lnwallet/chanfunding/assembler.go | 15 ++++++++++ lnwallet/chanfunding/psbt_assembler.go | 31 +++++++++++++-------- lnwallet/chanfunding/psbt_assembler_test.go | 8 +++--- rpcserver.go | 1 + 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/lnwallet/chanfunding/assembler.go b/lnwallet/chanfunding/assembler.go index 208cab68b..2a78f3758 100644 --- a/lnwallet/chanfunding/assembler.go +++ b/lnwallet/chanfunding/assembler.go @@ -135,3 +135,18 @@ type FundingTxAssembler interface { // transaction for the channel via the intent it returns. FundingTxAvailable() } + +// ConditionalPublishAssembler is an assembler that can dynamically define if +// the funding transaction should be published after channel negotiations or +// not. Not publishing the transaction is only useful if the particular channel +// the assembler is in charge of is part of a batch of channels. In that case +// it is only safe to wait for all channel negotiations of the batch to complete +// before publishing the batch transaction. +type ConditionalPublishAssembler interface { + Assembler + + // ShouldPublishFundingTx is a method of the assembler that signals if + // the funding transaction should be published after the channel + // negotiations are completed with the remote peer. + ShouldPublishFundingTx() bool +} diff --git a/lnwallet/chanfunding/psbt_assembler.go b/lnwallet/chanfunding/psbt_assembler.go index a65cc624a..9f82e0beb 100644 --- a/lnwallet/chanfunding/psbt_assembler.go +++ b/lnwallet/chanfunding/psbt_assembler.go @@ -387,6 +387,10 @@ type PsbtAssembler struct { // netParams are the network parameters used to encode the P2WSH funding // address. netParams *chaincfg.Params + + // shouldPublish specifies if the assembler should publish the + // transaction once the channel funding has completed. + shouldPublish bool } // NewPsbtAssembler creates a new CannedAssembler from the material required @@ -394,12 +398,13 @@ type PsbtAssembler struct { // be supplied which will be used to add the channel output to instead of // creating a new one. func NewPsbtAssembler(fundingAmt btcutil.Amount, basePsbt *psbt.Packet, - netParams *chaincfg.Params) *PsbtAssembler { + netParams *chaincfg.Params, shouldPublish bool) *PsbtAssembler { return &PsbtAssembler{ - fundingAmt: fundingAmt, - basePsbt: basePsbt, - netParams: netParams, + fundingAmt: fundingAmt, + basePsbt: basePsbt, + netParams: netParams, + shouldPublish: shouldPublish, } } @@ -436,16 +441,18 @@ func (p *PsbtAssembler) ProvisionChannel(req *Request) (Intent, error) { return intent, nil } -// FundingTxAvailable is an empty method that an assembler can implement to -// signal to callers that its able to provide the funding transaction for the -// channel via the intent it returns. +// ShouldPublishFundingTx is a method of the assembler that signals if the +// funding transaction should be published after the channel negotiations are +// completed with the remote peer. // -// NOTE: This method is a part of the FundingTxAssembler interface. -func (p *PsbtAssembler) FundingTxAvailable() {} +// NOTE: This method is a part of the ConditionalPublishAssembler interface. +func (p *PsbtAssembler) ShouldPublishFundingTx() bool { + return p.shouldPublish +} -// A compile-time assertion to ensure PsbtAssembler meets the Assembler -// interface. -var _ Assembler = (*PsbtAssembler)(nil) +// A compile-time assertion to ensure PsbtAssembler meets the +// ConditionalPublishAssembler interface. +var _ ConditionalPublishAssembler = (*PsbtAssembler)(nil) // sumUtxoInputValues tries to extract the sum of all inputs specified in the // UTXO fields of the PSBT. An error is returned if an input is specified that diff --git a/lnwallet/chanfunding/psbt_assembler_test.go b/lnwallet/chanfunding/psbt_assembler_test.go index 5367ecdbe..a58ea38bf 100644 --- a/lnwallet/chanfunding/psbt_assembler_test.go +++ b/lnwallet/chanfunding/psbt_assembler_test.go @@ -34,7 +34,7 @@ func TestPsbtIntent(t *testing.T) { // Create a simple assembler and ask it to provision a channel to get // the funding intent. - a := NewPsbtAssembler(chanCapacity, nil, ¶ms) + a := NewPsbtAssembler(chanCapacity, nil, ¶ms, true) intent, err := a.ProvisionChannel(&Request{LocalAmt: chanCapacity}) if err != nil { t.Fatalf("error provisioning channel: %v", err) @@ -215,7 +215,7 @@ func TestPsbtIntentBasePsbt(t *testing.T) { // Now as the next step, create a new assembler/intent pair with a base // PSBT to see that we can add an additional output to it. - a := NewPsbtAssembler(chanCapacity, pendingPsbt, ¶ms) + a := NewPsbtAssembler(chanCapacity, pendingPsbt, ¶ms, true) intent, err := a.ProvisionChannel(&Request{LocalAmt: chanCapacity}) if err != nil { t.Fatalf("error provisioning channel: %v", err) @@ -373,7 +373,7 @@ func TestPsbtVerify(t *testing.T) { // Create a simple assembler and ask it to provision a channel to get // the funding intent. - a := NewPsbtAssembler(chanCapacity, nil, ¶ms) + a := NewPsbtAssembler(chanCapacity, nil, ¶ms, true) intent, err := a.ProvisionChannel(&Request{LocalAmt: chanCapacity}) if err != nil { t.Fatalf("error provisioning channel: %v", err) @@ -500,7 +500,7 @@ func TestPsbtFinalize(t *testing.T) { // Create a simple assembler and ask it to provision a channel to get // the funding intent. - a := NewPsbtAssembler(chanCapacity, nil, ¶ms) + a := NewPsbtAssembler(chanCapacity, nil, ¶ms, true) intent, err := a.ProvisionChannel(&Request{LocalAmt: chanCapacity}) if err != nil { t.Fatalf("error provisioning channel: %v", err) diff --git a/rpcserver.go b/rpcserver.go index 0130a4072..4ed0e0f8d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1672,6 +1672,7 @@ func newPsbtAssembler(req *lnrpc.OpenChannelRequest, normalizedMinConfs int32, // to pass into the wallet. return chanfunding.NewPsbtAssembler( btcutil.Amount(req.LocalFundingAmount), packet, netParams, + !psbtShim.NoPublish, ), nil }