Browse Source

lnpeer: reestablish_channel - always replay unacked local updates

Even if we haven't signed them yet (did not send commitment_signed).
Alternatively, if they are not yet signed, we could discard them here,
like we do already for remote updates above (chan.hm.discard_unsigned_remote_updates).
One of these two options must be done, and before this commit we were not doing either.
dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
SomberNight 5 years ago
committed by ThomasV
parent
commit
4fc9f243f7
  1. 20
      electrum/lnpeer.py

20
electrum/lnpeer.py

@ -748,20 +748,24 @@ class Peer(Logger):
raise RemoteMisbehaving(f"channel reestablish: their_next_local_ctn < 0") raise RemoteMisbehaving(f"channel reestablish: their_next_local_ctn < 0")
if their_oldest_unrevoked_remote_ctn < 0: if their_oldest_unrevoked_remote_ctn < 0:
raise RemoteMisbehaving(f"channel reestablish: their_oldest_unrevoked_remote_ctn < 0") raise RemoteMisbehaving(f"channel reestablish: their_oldest_unrevoked_remote_ctn < 0")
# Replay un-acked local updates (including commitment_signed) byte-for-byte.
# If we have sent them a commitment signature that they "lost" (due to disconnect),
# we need to make sure we replay the same local updates, as otherwise they could
# end up with two (or more) signed valid commitment transactions at the same ctn.
# Multiple valid ctxs at the same ctn is a major headache for pre-signing spending txns,
# e.g. for watchtowers, hence we must ensure these ctxs coincide.
# We replay the local updates even if they were not yet committed.
for raw_upd_msg in chan.hm.get_unacked_local_updates():
self.transport.send_bytes(raw_upd_msg)
should_close_we_are_ahead = False should_close_we_are_ahead = False
should_close_they_are_ahead = False should_close_they_are_ahead = False
# compare remote ctns # compare remote ctns
if next_remote_ctn != their_next_local_ctn: if next_remote_ctn != their_next_local_ctn:
if their_next_local_ctn == latest_remote_ctn and chan.hm.is_revack_pending(REMOTE): if their_next_local_ctn == latest_remote_ctn and chan.hm.is_revack_pending(REMOTE):
# Replay un-acked local updates (including commitment_signed) byte-for-byte. # We replayed the local updates (see above), which should have contained a commitment_signed
# If we have sent them a commitment signature that they "lost" (due to disconnect), # (due to is_revack_pending being true), and this should have remedied this situation.
# we need to make sure we replay the same local updates, as otherwise they could pass
# end up with two (or more) signed valid commitment transactions at the same ctn.
# Multiple valid ctxs at the same ctn is a major headache for pre-signing spending txns,
# e.g. for watchtowers, hence we must ensure these ctxs coincide.
for raw_upd_msg in chan.hm.get_unacked_local_updates():
self.transport.send_bytes(raw_upd_msg)
else: else:
self.logger.warning(f"channel_reestablish: expected remote ctn {next_remote_ctn}, got {their_next_local_ctn}") self.logger.warning(f"channel_reestablish: expected remote ctn {next_remote_ctn}, got {their_next_local_ctn}")
if their_next_local_ctn < next_remote_ctn: if their_next_local_ctn < next_remote_ctn:

Loading…
Cancel
Save