lnwallet: ensure reservation state is cleaned up in case of Cancel

This commit fixes a bug in the wallet’s internal reservation manager
that prevented it from cleaning up the resources used by a reservation
after it was finished running through the workflow.

We fix this issue by ensuring the reservations context is deleted from
the funding limbo.

It is the callers responsibility to properly .Cancel() a reservation in
the case of an error during the funding workflow.
This commit is contained in:
Olaoluwa Osuntokun 2017-02-21 22:12:46 -08:00
parent d759e05a1c
commit bd775b9bb3
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
2 changed files with 25 additions and 0 deletions

View File

@ -96,6 +96,12 @@ func assertChannelOpen(t *testing.T, miner *rpctest.Harness, numConfs uint32,
}
}
func assertReservationDeleted(res *lnwallet.ChannelReservation, t *testing.T) {
if err := res.Cancel(); err == nil {
t.Fatalf("reservation wasn't deleted from wallet")
}
}
// bobNode represents the other party involved as a node within LN. Bob is our
// only "default-route", we have a direct connection with him.
type bobNode struct {
@ -526,6 +532,10 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness, wallet *lnwallet
if err := wallet.PublishTransaction(bobCloseTx); err != nil {
t.Fatalf("broadcast of close tx rejected: %v", err)
}
// Now that the reservation has conclued, ensure that the wallet has
// cleaned up the state allocated to the reservation.
assertReservationDeleted(chanReservation, t)
}
func testFundingTransactionLockedOutputs(miner *rpctest.Harness,
@ -774,6 +784,8 @@ func testSingleFunderReservationWorkflowInitiator(miner *rpctest.Harness,
lnChan <- openDetails.Channel
}()
assertChannelOpen(t, miner, uint32(numReqConfs), lnChan)
assertReservationDeleted(chanReservation, t)
}
func testSingleFunderReservationWorkflowResponder(miner *rpctest.Harness,
@ -934,6 +946,7 @@ func testSingleFunderReservationWorkflowResponder(miner *rpctest.Harness,
}
// TODO(roasbeef): bob verify alice's sig
assertReservationDeleted(chanReservation, t)
}
func testListTransactionDetails(miner *rpctest.Harness, wallet *lnwallet.LightningWallet, t *testing.T) {

View File

@ -1242,6 +1242,12 @@ func (l *LightningWallet) handleChannelOpen(req *channelOpenMsg) {
res.chanOpen <- &openChanDetails{
channel: channel,
}
// As this reservation has concluded, we can now safely remove the
// reservation from the limbo map.
l.limboMtx.Lock()
delete(l.fundingLimbo, req.pendingFundingID)
l.limboMtx.Unlock()
}
// openChannelAfterConfirmations creates, and opens a payment channel after
@ -1299,6 +1305,12 @@ out:
blockHeight: confDetails.BlockHeight,
txIndex: confDetails.TxIndex,
}
// As this reservation has concluded, we can now safely remove the
// reservation from the limbo map.
l.limboMtx.Lock()
delete(l.fundingLimbo, res.reservationID)
l.limboMtx.Unlock()
}
// selectCoinsAndChange performs coin selection in order to obtain witness