diff --git a/electrum/lnhtlc.py b/electrum/lnhtlc.py index 5025622db..bc495dd85 100644 --- a/electrum/lnhtlc.py +++ b/electrum/lnhtlc.py @@ -167,6 +167,25 @@ class HTLCManager: if fee_update.ctns[LOCAL] is None and fee_update.ctns[REMOTE] <= self.ctn_latest(REMOTE): fee_update.ctns[LOCAL] = self.ctn_latest(LOCAL) + 1 + def discard_unsigned_remote_updates(self): + """Discard updates sent by the remote, that the remote itself + did not yet sign (i.e. there was no corresponding commitment_signed msg) + """ + # htlcs + for htlc_id, ctns in list(self.log[REMOTE]['locked_in'].items()): + if ctns[LOCAL] > self.ctn_latest(LOCAL): + del self.log[REMOTE]['locked_in'][htlc_id] + del self.log[REMOTE]['adds'][htlc_id] + self.log[REMOTE]['next_htlc_id'] = max(self.log[REMOTE]['locked_in']) + 1 + for log_action in ('settles', 'fails'): + for htlc_id, ctns in list(self.log[LOCAL][log_action].items()): + if ctns[LOCAL] > self.ctn_latest(LOCAL): + del self.log[LOCAL][log_action][htlc_id] + # fee updates + for i, fee_update in enumerate(list(self.log[REMOTE]['fee_updates'])): + if fee_update.ctns[LOCAL] > self.ctn_latest(LOCAL): + del self.log[REMOTE]['fee_updates'][i] + ##### Queries re HTLCs: def htlcs_by_direction(self, subject: HTLCOwner, direction: Direction, diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py index 27fdf7a7e..4f70ef475 100644 --- a/electrum/lnpeer.py +++ b/electrum/lnpeer.py @@ -692,6 +692,8 @@ class Peer(Logger): return chan.set_state('REESTABLISHING') self.network.trigger_callback('channel', chan) + # BOLT-02: "A node [...] upon disconnection [...] MUST reverse any uncommitted updates sent by the other side" + chan.hm.discard_unsigned_remote_updates() # ctns oldest_unrevoked_local_ctn = chan.config[LOCAL].ctn latest_local_ctn = chan.hm.ctn_latest(LOCAL)