From 0a6b05d2de5ab01334172dfb805a9b71925b9b9e Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Tue, 22 Aug 2023 08:08:58 +0800 Subject: [PATCH] funding: catching barrier signal in `receivedChannelReady` There is a race condition, - goroutine_1: performing `stateStep` under `channelReadySent`. Once `receivedChannelReady` returns true, it will mark the channel state as `addedToRouterGraph`, which will delete the initial forwarding policy for private channels. - goroutine_2: performing `handleChannelReady`, which processes the remote's channelReady message. It will ask brontide to `AddNewChannel` in the end. - goroutine_3: performing `handleNewActiveChannel` in brontide, which will query the initial forwarding policy and fail to find it because it's already deleted in goroutine_1. To fix it, we require `receivedChannelReady` to also check that the channel's barrier signal in the map `handleChannelReadyBarriers` doesn't exist, as this signal is removed once `handleChannelReady` finishes adding the channel in brontide. --- funding/manager.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/funding/manager.go b/funding/manager.go index bba42642c..9fa860a58 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -3070,6 +3070,8 @@ func (f *Manager) receivedChannelReady(node *btcec.PublicKey, return false, err } + // If we cannot find the channel, then we haven't processed the + // remote's channelReady message. channel, err := f.cfg.FindChannel(node, chanID) if err != nil { log.Errorf("Unable to locate ChannelID(%v) to determine if "+ @@ -3077,7 +3079,18 @@ func (f *Manager) receivedChannelReady(node *btcec.PublicKey, return false, err } - return channel.RemoteNextRevocation != nil, nil + // If we haven't insert the next revocation point, we haven't finished + // processing the channel ready message. + if channel.RemoteNextRevocation == nil { + return false, nil + } + + // Finally, the barrier signal is removed once we finish + // `handleChannelReady`. If we can still find the signal, we haven't + // finished processing it yet. + _, loaded := f.handleChannelReadyBarriers.Load(chanID) + + return !loaded, nil } // extractAnnounceParams extracts the various channel announcement and update