Fix EnforcingChannelKeys panic when our counterparty burns their $.
authorMatt Corallo <git@bluematt.me>
Sun, 12 Jan 2020 23:04:40 +0000 (18:04 -0500)
committerMatt Corallo <git@bluematt.me>
Sat, 25 Jan 2020 22:12:08 +0000 (17:12 -0500)
If our counterparty burns their funds by revoking their current
commitment transaction before we've sent them a new one, we'll step
forward the remote commitment number. This would be otherwise fine
(and may even encourage them to broadcast their revoked state(s) on
chain), except that our new EnforcingChannelKeys expects us to not
jump forward in time. Since it isn't too important that we punish
our counterparty in such a corner-case, we opt to just close the
channel in such a case and move on.

lightning/src/ln/channel.rs

index b50a701f17c1c3c016085ab98131403a491e21f1..07ad171aa20eb394ee8dbbab0201628348c6703c 100644 (file)
@@ -1993,6 +1993,17 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
                self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret)
                        .map_err(|e| ChannelError::Close(e.0))?;
 
+               if self.channel_state & ChannelState::AwaitingRemoteRevoke as u32 == 0 {
+                       // Our counterparty seems to have burned their coins to us (by revoking a state when we
+                       // haven't given them a new commitment transaction to broadcast). We should probably
+                       // take advantage of this by updating our channel monitor, sending them an error, and
+                       // waiting for them to broadcast their latest (now-revoked claim). But, that would be a
+                       // lot of work, and there's some chance this is all a misunderstanding anyway.
+                       // We have to do *something*, though, since our signer may get mad at us for otherwise
+                       // jumping a remote commitment number, so best to just force-close and move on.
+                       return Err(ChannelError::Close("Got a revoke when we weren't expecting one"));
+               }
+
                // Update state now that we've passed all the can-fail calls...
                // (note that we may still fail to generate the new commitment_signed message, but that's
                // OK, we step the channel here and *then* if the new generation fails we can fail the