Skip to content

Commit

Permalink
fundingmanager: hold mutex during ctx cancellation
Browse files Browse the repository at this point in the history
This commit changes cancelReservationCtx to gold the resMtx from start
to finish. Earlier it would lock at different times only when accessing
the maps, meaning that other goroutines (I'm looking at you
PeerTerminationWatcher) could come in and grab the context in between
locks, possibly leading to a race.
  • Loading branch information
halseth committed Jun 1, 2018
1 parent 3d96462 commit cdaafc4
Showing 1 changed file with 24 additions and 7 deletions.
31 changes: 24 additions & 7 deletions fundingmanager.go
Expand Up @@ -2749,18 +2749,35 @@ func (f *fundingManager) cancelReservationCtx(peerKey *btcec.PublicKey,
fndgLog.Infof("Cancelling funding reservation for node_key=%x, "+
"chan_id=%x", peerKey.SerializeCompressed(), pendingChanID[:])

ctx, err := f.getReservationCtx(peerKey, pendingChanID)
if err != nil {
return nil, errors.Errorf("unable to find reservation: %v",
err)
peerIDKey := newSerializedKey(peerKey)
f.resMtx.Lock()
defer f.resMtx.Unlock()

nodeReservations, ok := f.activeReservations[peerIDKey]
if !ok {
// No reservations for this node.
return nil, errors.Errorf("no active reservations for peer(%x)",
peerIDKey[:])
}

ctx, ok := nodeReservations[pendingChanID]
if !ok {
return nil, errors.Errorf("unknown channel (id: %x) for "+
"peer(%x)", pendingChanID[:], peerIDKey[:])
}

if err := ctx.reservation.Cancel(); err != nil {
return nil, errors.Errorf("unable to cancel reservation: %v",
err)
}

f.deleteReservationCtx(peerKey, pendingChanID)
delete(nodeReservations, pendingChanID)

// If this was the last active reservation for this peer, delete the
// peer's entry altogether.
if len(nodeReservations) == 0 {
delete(f.activeReservations, peerIDKey)
}
return ctx, nil
}

Expand Down Expand Up @@ -2800,8 +2817,8 @@ func (f *fundingManager) getReservationCtx(peerKey *btcec.PublicKey,
f.resMtx.RUnlock()

if !ok {
return nil, errors.Errorf("unknown channel (id: %x)",
pendingChanID[:])
return nil, errors.Errorf("unknown channel (id: %x) for "+
"peer(%x)", pendingChanID[:], peerIDKey[:])
}

return resCtx, nil
Expand Down

0 comments on commit cdaafc4

Please sign in to comment.