Merge pull request #4455 from cfromknecht/psbt-no-publish
PSBT: add no_publish flag for safe batch channel opens v2
This commit is contained in:
11 files changed
+988
-751
No files matched your search
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+15
-1
@@ -287,10 +287,24 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
chanType |= channeldb.SingleFunderBit
|
||||
}
|
||||
|
||||
switch a := fundingAssembler.(type) {
|
||||
// The first channels of a batch shouldn't publish the batch TX
|
||||
// to avoid problems if some of the funding flows can't be
|
||||
// completed. Only the last channel of a batch should publish.
|
||||
case chanfunding.ConditionalPublishAssembler:
|
||||
if !a.ShouldPublishFundingTx() {
|
||||
chanType |= channeldb.NoFundingTxBit
|
||||
}
|
||||
|
||||
// Normal funding flow, the assembler creates a TX from the
|
||||
// internal wallet.
|
||||
case chanfunding.FundingTxAssembler:
|
||||
// Do nothing, a FundingTxAssembler has the transaction.
|
||||
|
||||
// If this intent isn't one that's able to provide us with a
|
||||
// funding transaction, then we'll set the chanType bit to
|
||||
// signal that we don't have access to one.
|
||||
if _, ok := fundingAssembler.(chanfunding.FundingTxAssembler); !ok {
|
||||
default:
|
||||
chanType |= channeldb.NoFundingTxBit
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user