lnwallet + funding: move funding tx publish to fundingmgr

This commit moves the responsibility for publishing the funding tx to
the network from the wallet to the funding manager. This is done to
distinguish the failure of completing the reservation within the wallet
and failure of publishing the transaction.

Earlier we could fail to broadcast the transaction, which would cause us
to fail the funding flow. This is not something we can do directly,
since the CompeteReservation call will mark the channel IsPending in the
databas.e
This commit is contained in:
Johan T. Halseth 2018-07-26 15:16:47 +02:00
parent 8865bcf3d9
commit 2a77b57788
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
3 changed files with 35 additions and 26 deletions

@ -1539,9 +1539,12 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
// transaction. We'll verify the signature for validity, then commit
// the state to disk as we can now open the channel.
commitSig := fmsg.msg.CommitSig.ToSignatureBytes()
completeChan, err := resCtx.reservation.CompleteReservation(nil, commitSig)
completeChan, err := resCtx.reservation.CompleteReservation(
nil, commitSig,
)
if err != nil {
fndgLog.Errorf("Unable to complete reservation sign complete: %v", err)
fndgLog.Errorf("Unable to complete reservation sign "+
"complete: %v", err)
f.failFundingFlow(fmsg.peer, pendingChanID, err)
return
}
@ -1550,6 +1553,22 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
// delete it from our set of active reservations.
f.deleteReservationCtx(peerKey, pendingChanID)
// Broadcast the finalized funding transaction to the network.
fundingTx := completeChan.FundingTxn
fndgLog.Infof("Broadcasting funding tx for ChannelPoint(%v): %v",
completeChan.FundingOutpoint, spew.Sdump(fundingTx))
err = f.cfg.PublishTransaction(fundingTx)
if err != nil {
fndgLog.Errorf("unable to broadcast funding "+
"txn: %v", err)
// We failed to broadcast the funding transaction, but watch
// the channel regardless, in case the transaction made it to
// the network. We will retry broadcast at startup.
// TODO(halseth): retry more often? Handle with CPFP? Just
// delete from the DB?
}
// Now that we have a finalized reservation for this funding flow,
// we'll send the to be active channel to the ChainArbitrator so it can
// watch for any on-chin actions before the channel has fully

@ -4,12 +4,12 @@ import (
"net"
"sync"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnwire"
)
// ChannelContribution is the primary constituent of the funding workflow
@ -434,11 +434,11 @@ func (r *ChannelReservation) OurSignatures() ([]*InputScript, []byte) {
// https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki.
// Additionally, verification is performed in order to ensure that the
// counterparty supplied a valid signature to our version of the commitment
// transaction. Once this method returns, caller's should then call
// .WaitForChannelOpen() which will block until the funding transaction obtains
// the configured number of confirmations. Once the method unblocks, a
// LightningChannel instance is returned, marking the channel available for
// updates.
// transaction. Once this method returns, caller's should broadcast the
// created funding transaction, then call .WaitForChannelOpen() which will
// block until the funding transaction obtains the configured number of
// confirmations. Once the method unblocks, a LightningChannel instance is
// returned, marking the channel available for updates.
func (r *ChannelReservation) CompleteReservation(fundingInputScripts []*InputScript,
commitmentSig []byte) (*channeldb.OpenChannel, error) {

@ -8,20 +8,20 @@ import (
"sync"
"sync/atomic"
"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/lightningnetwork/lnd/shachain"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/txsort"
"github.com/lightningnetwork/lnd/shachain"
)
const (
@ -262,15 +262,15 @@ type LightningWallet struct {
// is removed from limbo. Each reservation is tracked by a unique
// monotonically integer. All requests concerning the channel MUST
// carry a valid, active funding ID.
fundingLimbo map[uint64]*ChannelReservation
limboMtx sync.RWMutex
fundingLimbo map[uint64]*ChannelReservation
limboMtx sync.RWMutex
// lockedOutPoints is a set of the currently locked outpoint. This
// information is kept in order to provide an easy way to unlock all
// the currently locked outpoints.
lockedOutPoints map[wire.OutPoint]struct{}
quit chan struct{}
quit chan struct{}
wg sync.WaitGroup
@ -1086,16 +1086,6 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
return
}
walletLog.Infof("Broadcasting funding tx for ChannelPoint(%v): %v",
res.partialState.FundingOutpoint, spew.Sdump(fundingTx))
// Broadcast the finalized funding transaction to the network.
if err := l.PublishTransaction(fundingTx); err != nil {
msg.err <- err
msg.completeChan <- nil
return
}
msg.completeChan <- res.partialState
msg.err <- nil
}