Browse Source

lnchannel: verify sig of remote chanupd (for inc edge of direct chan)

This is re the channel update for the incoming direction of our own channels.
This message can only come from the counterparty itself so maybe the sig check
is redundant... but for sanity I think we should check it anyway.
patch-4
SomberNight 4 years ago
parent
commit
468f3b2b8d
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 6
      electrum/channel_db.py
  2. 9
      electrum/lnchannel.py
  3. 6
      electrum/lnpeer.py
  4. 5
      electrum/lnworker.py

6
electrum/channel_db.py

@ -569,12 +569,14 @@ class ChannelDB(SqlDB):
c.execute("INSERT INTO address (node_id, host, port, timestamp) VALUES (?,?,?,?)", (addr.pubkey, addr.host, addr.port, 0))
@classmethod
def verify_channel_update(cls, payload) -> None:
def verify_channel_update(cls, payload, *, start_node: bytes = None) -> None:
short_channel_id = payload['short_channel_id']
short_channel_id = ShortChannelID(short_channel_id)
if constants.net.rev_genesis_bytes() != payload['chain_hash']:
raise InvalidGossipMsg('wrong chain hash')
if not verify_sig_for_channel_update(payload, payload['start_node']):
start_node = payload.get('start_node', None) or start_node
assert start_node is not None
if not verify_sig_for_channel_update(payload, start_node):
raise InvalidGossipMsg(f'failed verifying channel update for {short_channel_id}')
@classmethod

9
electrum/lnchannel.py

@ -580,7 +580,14 @@ class Channel(AbstractChannel):
raise Exception('lnworker not set for channel!')
return self.lnworker.node_keypair.pubkey
def set_remote_update(self, raw: bytes) -> None:
def set_remote_update(self, payload: dict) -> None:
"""Save the ChannelUpdate message for the incoming direction of this channel.
This message contains info we need to populate private route hints when
creating invoices.
"""
from .channel_db import ChannelDB
ChannelDB.verify_channel_update(payload, start_node=self.node_id)
raw = payload['raw']
self.storage['remote_update'] = raw.hex()
def get_remote_update(self) -> Optional[bytes]:

6
electrum/lnpeer.py

@ -97,7 +97,7 @@ class Peer(Logger):
self.funding_signed_sent = set() # for channels in PREOPENING
self.shutdown_received = {} # chan_id -> asyncio.Future()
self.announcement_signatures = defaultdict(asyncio.Queue)
self.orphan_channel_updates = OrderedDict()
self.orphan_channel_updates = OrderedDict() # type: OrderedDict[ShortChannelID, dict]
Logger.__init__(self)
self.taskgroup = SilentTaskGroup()
# HTLCs offered by REMOTE, that we started removing but are still active:
@ -273,7 +273,7 @@ class Peer(Logger):
return
for chan in self.channels.values():
if chan.short_channel_id == payload['short_channel_id']:
chan.set_remote_update(payload['raw'])
chan.set_remote_update(payload)
self.logger.info("saved remote_update")
break
else:
@ -1149,7 +1149,7 @@ class Peer(Logger):
# peer may have sent us a channel update for the incoming direction previously
pending_channel_update = self.orphan_channel_updates.get(chan.short_channel_id)
if pending_channel_update:
chan.set_remote_update(pending_channel_update['raw'])
chan.set_remote_update(pending_channel_update)
self.logger.info(f"CHANNEL OPENING COMPLETED ({chan.get_id_for_log()})")
forwarding_enabled = self.network.config.get('lightning_forward_payments', False)
if forwarding_enabled:

5
electrum/lnworker.py

@ -1284,10 +1284,11 @@ class LNWallet(LNWorker):
short_channel_id = ShortChannelID(payload['short_channel_id'])
if r == UpdateStatus.GOOD:
self.logger.info(f"applied channel update to {short_channel_id}")
# TODO: test this
# TODO: add test for this
# FIXME: this does not work for our own unannounced channels.
for chan in self.channels.values():
if chan.short_channel_id == short_channel_id:
chan.set_remote_update(payload['raw'])
chan.set_remote_update(payload)
update = True
elif r == UpdateStatus.ORPHANED:
# maybe it is a private channel (and data in invoice was outdated)

Loading…
Cancel
Save