funding: use SyncMap to simplify map usage
This commit is contained in:
1 file changed
+38
-68
+38
-68
@@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/labels"
|
"github.com/lightningnetwork/lnd/labels"
|
||||||
"github.com/lightningnetwork/lnd/lnpeer"
|
"github.com/lightningnetwork/lnd/lnpeer"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
|
"github.com/lightningnetwork/lnd/lnutils"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
|
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
|
||||||
@@ -583,14 +584,11 @@ type Manager struct {
|
|||||||
// be signalled once the channel is fully open. This barrier acts as a
|
// be signalled once the channel is fully open. This barrier acts as a
|
||||||
// synchronization point for any incoming/outgoing HTLCs before the
|
// synchronization point for any incoming/outgoing HTLCs before the
|
||||||
// channel has been fully opened.
|
// channel has been fully opened.
|
||||||
barrierMtx sync.RWMutex
|
newChanBarriers *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
|
||||||
newChanBarriers map[lnwire.ChannelID]chan struct{}
|
|
||||||
|
|
||||||
localDiscoveryMtx sync.Mutex
|
localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]
|
||||||
localDiscoverySignals map[lnwire.ChannelID]chan struct{}
|
|
||||||
|
|
||||||
handleChannelReadyMtx sync.RWMutex
|
handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
|
||||||
handleChannelReadyBarriers map[lnwire.ChannelID]struct{}
|
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
@@ -644,21 +642,21 @@ func NewFundingManager(cfg Config) (*Manager, error) {
|
|||||||
signedReservations: make(
|
signedReservations: make(
|
||||||
map[lnwire.ChannelID][32]byte,
|
map[lnwire.ChannelID][32]byte,
|
||||||
),
|
),
|
||||||
newChanBarriers: make(
|
newChanBarriers: &lnutils.SyncMap[
|
||||||
map[lnwire.ChannelID]chan struct{},
|
lnwire.ChannelID, chan struct{},
|
||||||
),
|
]{},
|
||||||
fundingMsgs: make(
|
fundingMsgs: make(
|
||||||
chan *fundingMsg, msgBufferSize,
|
chan *fundingMsg, msgBufferSize,
|
||||||
),
|
),
|
||||||
fundingRequests: make(
|
fundingRequests: make(
|
||||||
chan *InitFundingMsg, msgBufferSize,
|
chan *InitFundingMsg, msgBufferSize,
|
||||||
),
|
),
|
||||||
localDiscoverySignals: make(
|
localDiscoverySignals: &lnutils.SyncMap[
|
||||||
map[lnwire.ChannelID]chan struct{},
|
lnwire.ChannelID, chan struct{},
|
||||||
),
|
]{},
|
||||||
handleChannelReadyBarriers: make(
|
handleChannelReadyBarriers: &lnutils.SyncMap[
|
||||||
map[lnwire.ChannelID]struct{},
|
lnwire.ChannelID, struct{},
|
||||||
),
|
]{},
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -694,17 +692,14 @@ func (f *Manager) start() error {
|
|||||||
// re-initialize the channel barriers, and republish the
|
// re-initialize the channel barriers, and republish the
|
||||||
// funding transaction if we're the initiator.
|
// funding transaction if we're the initiator.
|
||||||
if channel.IsPending {
|
if channel.IsPending {
|
||||||
f.barrierMtx.Lock()
|
|
||||||
log.Tracef("Loading pending ChannelPoint(%v), "+
|
log.Tracef("Loading pending ChannelPoint(%v), "+
|
||||||
"creating chan barrier",
|
"creating chan barrier",
|
||||||
channel.FundingOutpoint)
|
channel.FundingOutpoint)
|
||||||
|
|
||||||
f.newChanBarriers[chanID] = make(chan struct{})
|
f.newChanBarriers.Store(chanID, make(chan struct{}))
|
||||||
f.barrierMtx.Unlock()
|
f.localDiscoverySignals.Store(
|
||||||
|
chanID, make(chan struct{}),
|
||||||
f.localDiscoveryMtx.Lock()
|
)
|
||||||
f.localDiscoverySignals[chanID] = make(chan struct{})
|
|
||||||
f.localDiscoveryMtx.Unlock()
|
|
||||||
|
|
||||||
// Rebroadcast the funding transaction for any pending
|
// Rebroadcast the funding transaction for any pending
|
||||||
// channel that we initiated. No error will be returned
|
// channel that we initiated. No error will be returned
|
||||||
@@ -1247,12 +1242,9 @@ func (f *Manager) advancePendingChannelState(
|
|||||||
|
|
||||||
// Find and close the discoverySignal for this channel such
|
// Find and close the discoverySignal for this channel such
|
||||||
// that ChannelReady messages will be processed.
|
// that ChannelReady messages will be processed.
|
||||||
chanID := lnwire.NewChanIDFromOutPoint(
|
chanID := lnwire.NewChanIDFromOutPoint(&channel.FundingOutpoint)
|
||||||
&channel.FundingOutpoint,
|
discoverySignal, ok := f.localDiscoverySignals.Load(chanID)
|
||||||
)
|
if ok {
|
||||||
f.localDiscoveryMtx.Lock()
|
|
||||||
defer f.localDiscoveryMtx.Unlock()
|
|
||||||
if discoverySignal, ok := f.localDiscoverySignals[chanID]; ok {
|
|
||||||
close(discoverySignal)
|
close(discoverySignal)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2158,11 +2150,9 @@ func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
|
|||||||
// properly synchronize with the writeHandler goroutine, we add a new
|
// properly synchronize with the writeHandler goroutine, we add a new
|
||||||
// channel to the barriers map which will be closed once the channel is
|
// channel to the barriers map which will be closed once the channel is
|
||||||
// fully open.
|
// fully open.
|
||||||
f.barrierMtx.Lock()
|
|
||||||
channelID := lnwire.NewChanIDFromOutPoint(outPoint)
|
channelID := lnwire.NewChanIDFromOutPoint(outPoint)
|
||||||
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
|
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
|
||||||
f.newChanBarriers[channelID] = make(chan struct{})
|
f.newChanBarriers.Store(channelID, make(chan struct{}))
|
||||||
f.barrierMtx.Unlock()
|
|
||||||
|
|
||||||
// The next message that advances the funding flow will reference the
|
// The next message that advances the funding flow will reference the
|
||||||
// channel via its permanent channel ID, so we'll set up this mapping
|
// channel via its permanent channel ID, so we'll set up this mapping
|
||||||
@@ -2279,11 +2269,9 @@ func (f *Manager) handleFundingCreated(peer lnpeer.Peer,
|
|||||||
// properly synchronize with the writeHandler goroutine, we add a new
|
// properly synchronize with the writeHandler goroutine, we add a new
|
||||||
// channel to the barriers map which will be closed once the channel is
|
// channel to the barriers map which will be closed once the channel is
|
||||||
// fully open.
|
// fully open.
|
||||||
f.barrierMtx.Lock()
|
|
||||||
channelID := lnwire.NewChanIDFromOutPoint(&fundingOut)
|
channelID := lnwire.NewChanIDFromOutPoint(&fundingOut)
|
||||||
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
|
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
|
||||||
f.newChanBarriers[channelID] = make(chan struct{})
|
f.newChanBarriers.Store(channelID, make(chan struct{}))
|
||||||
f.barrierMtx.Unlock()
|
|
||||||
|
|
||||||
log.Infof("sending FundingSigned for pending_id(%x) over "+
|
log.Infof("sending FundingSigned for pending_id(%x) over "+
|
||||||
"ChannelPoint(%v)", pendingChanID[:], fundingOut)
|
"ChannelPoint(%v)", pendingChanID[:], fundingOut)
|
||||||
@@ -2329,9 +2317,7 @@ func (f *Manager) handleFundingCreated(peer lnpeer.Peer,
|
|||||||
// Create an entry in the local discovery map so we can ensure that we
|
// Create an entry in the local discovery map so we can ensure that we
|
||||||
// process the channel confirmation fully before we receive a
|
// process the channel confirmation fully before we receive a
|
||||||
// channel_ready message.
|
// channel_ready message.
|
||||||
f.localDiscoveryMtx.Lock()
|
f.localDiscoverySignals.Store(channelID, make(chan struct{}))
|
||||||
f.localDiscoverySignals[channelID] = make(chan struct{})
|
|
||||||
f.localDiscoveryMtx.Unlock()
|
|
||||||
|
|
||||||
// Inform the ChannelNotifier that the channel has entered
|
// Inform the ChannelNotifier that the channel has entered
|
||||||
// pending open state.
|
// pending open state.
|
||||||
@@ -2395,9 +2381,7 @@ func (f *Manager) handleFundingSigned(peer lnpeer.Peer,
|
|||||||
// channel_ready message.
|
// channel_ready message.
|
||||||
fundingPoint := resCtx.reservation.FundingOutpoint()
|
fundingPoint := resCtx.reservation.FundingOutpoint()
|
||||||
permChanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
|
permChanID := lnwire.NewChanIDFromOutPoint(fundingPoint)
|
||||||
f.localDiscoveryMtx.Lock()
|
f.localDiscoverySignals.Store(permChanID, make(chan struct{}))
|
||||||
f.localDiscoverySignals[permChanID] = make(chan struct{})
|
|
||||||
f.localDiscoveryMtx.Unlock()
|
|
||||||
|
|
||||||
// We have to store the forwardingPolicy before the reservation context
|
// We have to store the forwardingPolicy before the reservation context
|
||||||
// is deleted. The policy will then be read and applied in
|
// is deleted. The policy will then be read and applied in
|
||||||
@@ -2914,11 +2898,9 @@ func (f *Manager) handleFundingConfirmation(
|
|||||||
// goroutine that the channel now is marked as open in the database
|
// goroutine that the channel now is marked as open in the database
|
||||||
// and that it is acceptable to process channel_ready messages
|
// and that it is acceptable to process channel_ready messages
|
||||||
// from the peer.
|
// from the peer.
|
||||||
f.localDiscoveryMtx.Lock()
|
if discoverySignal, ok := f.localDiscoverySignals.Load(chanID); ok {
|
||||||
if discoverySignal, ok := f.localDiscoverySignals[chanID]; ok {
|
|
||||||
close(discoverySignal)
|
close(discoverySignal)
|
||||||
}
|
}
|
||||||
f.localDiscoveryMtx.Unlock()
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -3456,32 +3438,25 @@ func (f *Manager) handleChannelReady(peer lnpeer.Peer,
|
|||||||
"peer %x", msg.ChanID,
|
"peer %x", msg.ChanID,
|
||||||
peer.IdentityKey().SerializeCompressed())
|
peer.IdentityKey().SerializeCompressed())
|
||||||
|
|
||||||
|
// We now load or create a new channel barrier for this channel.
|
||||||
|
_, loaded := f.handleChannelReadyBarriers.LoadOrStore(
|
||||||
|
msg.ChanID, struct{}{},
|
||||||
|
)
|
||||||
|
|
||||||
// If we are currently in the process of handling a channel_ready
|
// If we are currently in the process of handling a channel_ready
|
||||||
// message for this channel, ignore.
|
// message for this channel, ignore.
|
||||||
f.handleChannelReadyMtx.Lock()
|
if loaded {
|
||||||
_, ok := f.handleChannelReadyBarriers[msg.ChanID]
|
|
||||||
if ok {
|
|
||||||
log.Infof("Already handling channelReady for "+
|
log.Infof("Already handling channelReady for "+
|
||||||
"ChannelID(%v), ignoring.", msg.ChanID)
|
"ChannelID(%v), ignoring.", msg.ChanID)
|
||||||
f.handleChannelReadyMtx.Unlock()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not already handling channelReady for this channel, set up
|
// If not already handling channelReady for this channel, then the
|
||||||
// barrier, and move on.
|
// `LoadOrStore` has set up a barrier, and it will be removed once this
|
||||||
f.handleChannelReadyBarriers[msg.ChanID] = struct{}{}
|
// function exits.
|
||||||
f.handleChannelReadyMtx.Unlock()
|
defer f.handleChannelReadyBarriers.Delete(msg.ChanID)
|
||||||
|
|
||||||
defer func() {
|
|
||||||
f.handleChannelReadyMtx.Lock()
|
|
||||||
delete(f.handleChannelReadyBarriers, msg.ChanID)
|
|
||||||
f.handleChannelReadyMtx.Unlock()
|
|
||||||
}()
|
|
||||||
|
|
||||||
f.localDiscoveryMtx.Lock()
|
|
||||||
localDiscoverySignal, ok := f.localDiscoverySignals[msg.ChanID]
|
|
||||||
f.localDiscoveryMtx.Unlock()
|
|
||||||
|
|
||||||
|
localDiscoverySignal, ok := f.localDiscoverySignals.Load(msg.ChanID)
|
||||||
if ok {
|
if ok {
|
||||||
// Before we proceed with processing the channel_ready
|
// Before we proceed with processing the channel_ready
|
||||||
// message, we'll wait for the local waitForFundingConfirmation
|
// message, we'll wait for the local waitForFundingConfirmation
|
||||||
@@ -3497,9 +3472,7 @@ func (f *Manager) handleChannelReady(peer lnpeer.Peer,
|
|||||||
|
|
||||||
// With the signal received, we can now safely delete the entry
|
// With the signal received, we can now safely delete the entry
|
||||||
// from the map.
|
// from the map.
|
||||||
f.localDiscoveryMtx.Lock()
|
f.localDiscoverySignals.Delete(msg.ChanID)
|
||||||
delete(f.localDiscoverySignals, msg.ChanID)
|
|
||||||
f.localDiscoveryMtx.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, we'll attempt to locate the channel whose funding workflow is
|
// First, we'll attempt to locate the channel whose funding workflow is
|
||||||
@@ -3617,15 +3590,12 @@ func (f *Manager) handleChannelReady(peer lnpeer.Peer,
|
|||||||
// Close the active channel barrier signaling the readHandler
|
// Close the active channel barrier signaling the readHandler
|
||||||
// that commitment related modifications to this channel can
|
// that commitment related modifications to this channel can
|
||||||
// now proceed.
|
// now proceed.
|
||||||
f.barrierMtx.Lock()
|
chanBarrier, ok := f.newChanBarriers.LoadAndDelete(chanID)
|
||||||
chanBarrier, ok := f.newChanBarriers[chanID]
|
|
||||||
if ok {
|
if ok {
|
||||||
log.Tracef("Closing chan barrier for ChanID(%v)",
|
log.Tracef("Closing chan barrier for ChanID(%v)",
|
||||||
chanID)
|
chanID)
|
||||||
close(chanBarrier)
|
close(chanBarrier)
|
||||||
delete(f.newChanBarriers, chanID)
|
|
||||||
}
|
}
|
||||||
f.barrierMtx.Unlock()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := peer.AddNewChannel(channel, f.quit); err != nil {
|
if err := peer.AddNewChannel(channel, f.quit); err != nil {
|
||||||
|
|||||||
Reference in new issue
Block a user