Browse Source

db upgrade: store channel tx height and timestamps in 'channels'

hard-fail-on-bad-server-string
ThomasV 5 years ago
parent
commit
20d8da7e24
  1. 2
      electrum/gui/qt/channels_list.py
  2. 18
      electrum/lnchannel.py
  3. 4
      electrum/lnwatcher.py
  4. 19
      electrum/lnworker.py
  5. 18
      electrum/wallet_db.py

2
electrum/gui/qt/channels_list.py

@ -120,7 +120,7 @@ class ChannelsList(MyTreeView):
menu.addAction(_("Close channel"), lambda: self.close_channel(channel_id))
menu.addAction(_("Force-close channel"), lambda: self.force_close(channel_id))
else:
txid = chan.get_closing_txid()
txid, height, timestamp = chan.get_closing_height()
closing_tx = self.lnworker.lnwatcher.db.get_transaction(txid)
if closing_tx:
menu.addAction(_("View closing transaction"), lambda: self.parent.show_transaction(closing_tx))

18
electrum/lnchannel.py

@ -312,10 +312,20 @@ class Channel(Logger):
# the closing txid has been saved
return self.get_state() >= channel_states.CLOSED
def get_closing_txid(self):
item = self.lnworker.channel_timestamps.get(self.channel_id.hex())
funding_txid, funding_height, funding_timestamp, closing_txid, closing_height, closing_timestamp = item
return closing_txid
def save_funding_height(self, txid, height, timestamp):
self.storage['funding_height'] = txid, height, timestamp
def get_funding_height(self):
return self.storage.get('funding_height')
def delete_funding_height(self):
self.storage.pop('funding_height', None)
def save_closing_height(self, txid, height, timestamp):
self.storage['closing_height'] = txid, height, timestamp
def get_closing_height(self):
return self.storage.get('closing_height')
def is_redeemed(self):
return self.get_state() == channel_states.REDEEMED

4
electrum/lnwatcher.py

@ -336,11 +336,13 @@ class LNWalletWatcher(LNWatcher):
if not chan:
return
if funding_height.height == TX_HEIGHT_LOCAL:
self.lnworker.channel_timestamps.pop(bh2u(chan.channel_id), None)
chan.delete_funding_height()
return
elif closing_height.height == TX_HEIGHT_LOCAL:
chan.save_funding_height(funding_txid, funding_height.height, funding_height.timestamp)
await self.lnworker.update_open_channel(chan, funding_txid, funding_height)
else:
chan.save_closing_height(closing_txid, closing_height.height, closing_height.timestamp)
await self.lnworker.update_closed_channel(chan, funding_txid, funding_height, closing_txid, closing_height, keep_watching)
async def do_breach_remedy(self, funding_outpoint, closing_tx, spenders):

19
electrum/lnworker.py

@ -376,7 +376,6 @@ class LNWallet(LNWorker):
self.channels[bfh(channel_id)] = Channel(c, sweep_address=self.sweep_address, lnworker=self)
# timestamps of opening and closing transactions
self.channel_timestamps = self.db.get_dict('lightning_channel_timestamps')
self.pending_payments = defaultdict(asyncio.Future)
@ignore_exceptions
@ -544,10 +543,10 @@ class LNWallet(LNWorker):
with self.lock:
channels = list(self.channels.values())
for chan in channels:
item = self.channel_timestamps.get(chan.channel_id.hex())
item = chan.get_funding_height()
if item is None:
continue
funding_txid, funding_height, funding_timestamp, closing_txid, closing_height, closing_timestamp = item
funding_txid, funding_height, funding_timestamp = item
item = {
'channel_id': bh2u(chan.channel_id),
'type': 'channel_opening',
@ -559,9 +558,10 @@ class LNWallet(LNWorker):
'fee_msat': None,
}
out[funding_txid] = item
if not chan.is_closed():
item = chan.get_closing_height()
if item is None:
continue
assert closing_txid
closing_txid, closing_height, closing_timestamp = item
item = {
'channel_id': bh2u(chan.channel_id),
'txid': closing_txid,
@ -655,11 +655,6 @@ class LNWallet(LNWorker):
return chan
async def update_open_channel(self, chan, funding_txid, funding_height):
# return early to prevent overwriting closing_txid with None
if chan.is_closed():
return
# save timestamp regardless of state, so that funding tx is returned in get_history
self.channel_timestamps[bh2u(chan.channel_id)] = chan.funding_outpoint.txid, funding_height.height, funding_height.timestamp, None, None, None
if chan.get_state() == channel_states.OPEN and self.should_channel_be_closed_due_to_expiring_htlcs(chan):
self.logger.info(f"force-closing due to expiring htlcs")
@ -700,9 +695,6 @@ class LNWallet(LNWorker):
async def update_closed_channel(self, chan, funding_txid, funding_height, closing_txid, closing_height, keep_watching):
# fixme: this is wasteful
self.channel_timestamps[bh2u(chan.channel_id)] = funding_txid, funding_height.height, funding_height.timestamp, closing_txid, closing_height.height, closing_height.timestamp
# remove from channel_db
if chan.short_channel_id is not None:
self.channel_db.remove_channel(chan.short_channel_id)
@ -1226,7 +1218,6 @@ class LNWallet(LNWorker):
assert chan.get_state() == channel_states.REDEEMED
with self.lock:
self.channels.pop(chan_id)
self.channel_timestamps.pop(chan_id.hex())
self.db.get('channels').pop(chan_id.hex())
self.network.trigger_callback('channels_updated', self.wallet)

18
electrum/wallet_db.py

@ -50,7 +50,7 @@ if TYPE_CHECKING:
OLD_SEED_VERSION = 4 # electrum versions < 2.0
NEW_SEED_VERSION = 11 # electrum versions >= 2.0
FINAL_SEED_VERSION = 25 # electrum >= 2.7 will set this to prevent
FINAL_SEED_VERSION = 26 # electrum >= 2.7 will set this to prevent
# old versions from overwriting new format
@ -171,6 +171,7 @@ class WalletDB(JsonDB):
self._convert_version_23()
self._convert_version_24()
self._convert_version_25()
self._convert_version_26()
self.put('seed_version', FINAL_SEED_VERSION) # just to be sure
self._after_upgrade_tasks()
@ -571,6 +572,21 @@ class WalletDB(JsonDB):
}
self.data['seed_version'] = 25
def _convert_version_26(self):
if not self._is_upgrade_method_needed(25, 25):
return
channels = self.data.get('channels', {})
channel_timestamps = self.data.pop('lightning_channel_timestamps', {})
for channel_id, c in channels.items():
item = channel_timestamps.get(channel_id)
if item:
funding_txid, funding_height, funding_timestamp, closing_txid, closing_height, closing_timestamp = item
if funding_txid:
c['funding_height'] = funding_txid, funding_height, funding_timestamp
if closing_txid:
c['closing_height'] = closing_txid, closing_height, closing_timestamp
self.data['seed_version'] = 26
def _convert_imported(self):
if not self._is_upgrade_method_needed(0, 13):
return

Loading…
Cancel
Save