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.
This commit is contained in:
yyforyongyu
2023-08-22 08:08:58 +08:00
parent 32d8208272
commit 0a6b05d2de

View File

@@ -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