From 44384a1b5be314f6a2b0275f2cb367e3cffaca9b Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Thu, 11 Jul 2019 13:14:36 +0200 Subject: [PATCH] lnwallet: move coin selection before ChannelReservation Now that coin selection is independent of creating the channel reservation, we can move it first, in preparation for doing custom coin selection. --- lnwallet/interface_test.go | 8 +++---- lnwallet/wallet.go | 44 +++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/lnwallet/interface_test.go b/lnwallet/interface_test.go index 866e79e4..ac650778 100644 --- a/lnwallet/interface_test.go +++ b/lnwallet/interface_test.go @@ -753,9 +753,9 @@ func testCancelNonExistentReservation(miner *rpctest.Harness, func testReservationInitiatorBalanceBelowDustCancel(miner *rpctest.Harness, alice, _ *lnwallet.LightningWallet, t *testing.T) { - // We'll attempt to create a new reservation with an extremely high fee - // rate. This should push our balance into the negative and result in a - // failure to create the reservation. + // We'll attempt to create a new reservation with an extremely high + // commitment fee rate. This should push our balance into the negative + // and result in a failure to create the reservation. const numBTC = 4 fundingAmount, err := btcutil.NewAmount(numBTC) if err != nil { @@ -772,7 +772,7 @@ func testReservationInitiatorBalanceBelowDustCancel(miner *rpctest.Harness, LocalFundingAmt: fundingAmount, RemoteFundingAmt: 0, CommitFeePerKw: feePerKw, - FundingFeePerKw: feePerKw, + FundingFeePerKw: 1000, PushMSat: 0, Flags: lnwire.FFAnnounceChannel, } diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index 57fa5b21..122c7a2e 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -453,6 +453,29 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg capacity := req.LocalFundingAmt + req.RemoteFundingAmt localFundingAmt := req.LocalFundingAmt + var ( + selected *coinSelection + err error + ) + + // If we're on the receiving end of a single funder channel then we + // don't need to perform any coin selection, and the remote contributes + // all funds. Otherwise, attempt to obtain enough coins to meet the + // required funding amount. + if req.LocalFundingAmt != 0 { + // Coin selection is done on the basis of sat/kw, so we'll use + // the fee rate passed in to perform coin selection. + var err error + selected, err = l.selectCoinsAndChange( + req.FundingFeePerKw, req.LocalFundingAmt, req.MinConfs, + ) + if err != nil { + req.err <- err + req.resp <- nil + return + } + } + id := atomic.AddUint64(&l.nextFundingID, 1) reservation, err := NewChannelReservation( capacity, localFundingAmt, req.CommitFeePerKw, l, id, @@ -468,27 +491,14 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg reservation.Lock() defer reservation.Unlock() - reservation.nodeAddr = req.NodeAddr - reservation.partialState.IdentityPub = req.NodeID - - // If we're on the receiving end of a single funder channel then we - // don't need to perform any coin selection. Otherwise, attempt to - // obtain enough coins to meet the required funding amount. - if req.LocalFundingAmt != 0 { - // Coin selection is done on the basis of sat/kw, so we'll use - // the fee rate passed in to perform coin selection. - selected, err := l.selectCoinsAndChange( - req.FundingFeePerKw, req.LocalFundingAmt, req.MinConfs, - ) - if err != nil { - req.err <- err - req.resp <- nil - return - } + if selected != nil { reservation.ourContribution.Inputs = selected.coins reservation.ourContribution.ChangeOutputs = selected.change } + reservation.nodeAddr = req.NodeAddr + reservation.partialState.IdentityPub = req.NodeID + // Next, we'll grab a series of keys from the wallet which will be used // for the duration of the channel. The keys include: our multi-sig // key, the base revocation key, the base htlc key,the base payment