|
|
@ -12,6 +12,7 @@ import time |
|
|
|
import hashlib |
|
|
|
import hmac |
|
|
|
from functools import partial |
|
|
|
from typing import List |
|
|
|
|
|
|
|
import cryptography.hazmat.primitives.ciphers.aead as AEAD |
|
|
|
import aiorpcx |
|
|
@ -31,6 +32,7 @@ from .lnutil import (Outpoint, ChannelConfig, LocalState, |
|
|
|
funding_output_script, get_ecdh, get_per_commitment_secret_from_seed, |
|
|
|
secret_to_pubkey, LNPeerAddr, PaymentFailure, |
|
|
|
LOCAL, REMOTE, HTLCOwner, generate_keypair, LnKeyFamily) |
|
|
|
from .lnrouter import NotFoundChanAnnouncementForUpdate, RouteEdge |
|
|
|
|
|
|
|
|
|
|
|
def channel_id_from_funding_tx(funding_txid, funding_index): |
|
|
@ -443,7 +445,16 @@ class Peer(PrintError): |
|
|
|
pass |
|
|
|
|
|
|
|
def on_channel_update(self, payload): |
|
|
|
self.channel_db.on_channel_update(payload) |
|
|
|
try: |
|
|
|
self.channel_db.on_channel_update(payload) |
|
|
|
except NotFoundChanAnnouncementForUpdate: |
|
|
|
# If it's for a direct channel with this peer, save it in chan. |
|
|
|
# Note that this is prone to a race.. we might not have a short_channel_id |
|
|
|
# associated with the channel in some cases |
|
|
|
short_channel_id = payload['short_channel_id'] |
|
|
|
for chan in self.channels.values(): |
|
|
|
if chan.short_channel_id_predicted == short_channel_id: |
|
|
|
chan.pending_channel_update_message = payload |
|
|
|
|
|
|
|
def on_channel_announcement(self, payload): |
|
|
|
self.channel_db.on_channel_announcement(payload) |
|
|
@ -550,7 +561,7 @@ class Peer(PrintError): |
|
|
|
first_per_commitment_point=per_commitment_point_first, |
|
|
|
to_self_delay=local_config.to_self_delay, |
|
|
|
max_htlc_value_in_flight_msat=local_config.max_htlc_value_in_flight_msat, |
|
|
|
channel_flags=0x01, # publicly announcing channel |
|
|
|
channel_flags=0x00, # not willing to announce channel |
|
|
|
channel_reserve_satoshis=546 |
|
|
|
) |
|
|
|
self.send_message(msg) |
|
|
@ -833,6 +844,9 @@ class Peer(PrintError): |
|
|
|
Runs on the Network thread. |
|
|
|
""" |
|
|
|
if not chan.local_state.was_announced and funding_tx_depth >= 6: |
|
|
|
# don't announce our channels |
|
|
|
# FIXME should this be a field in chan.local_state maybe? |
|
|
|
return |
|
|
|
chan.local_state=chan.local_state._replace(was_announced=True) |
|
|
|
coro = self.handle_announcements(chan) |
|
|
|
self.lnworker.save_channel(chan) |
|
|
@ -887,25 +901,39 @@ class Peer(PrintError): |
|
|
|
chan.set_state("OPEN") |
|
|
|
self.network.trigger_callback('channel', chan) |
|
|
|
# add channel to database |
|
|
|
node_ids = [self.pubkey, self.lnworker.node_keypair.pubkey] |
|
|
|
pubkey_ours = self.lnworker.node_keypair.pubkey |
|
|
|
pubkey_theirs = self.pubkey |
|
|
|
node_ids = [pubkey_theirs, pubkey_ours] |
|
|
|
bitcoin_keys = [chan.local_config.multisig_key.pubkey, chan.remote_config.multisig_key.pubkey] |
|
|
|
sorted_node_ids = list(sorted(node_ids)) |
|
|
|
if sorted_node_ids != node_ids: |
|
|
|
node_ids = sorted_node_ids |
|
|
|
bitcoin_keys.reverse() |
|
|
|
now = int(time.time()).to_bytes(4, byteorder="big") |
|
|
|
# note: we inject a channel announcement, and a channel update (for outgoing direction) |
|
|
|
# This is atm needed for |
|
|
|
# - finding routes |
|
|
|
# - the ChanAnn is needed so that we can anchor to it a future ChanUpd |
|
|
|
# that the remote sends, even if the channel was not announced |
|
|
|
# (from BOLT-07: "MAY create a channel_update to communicate the channel |
|
|
|
# parameters to the final node, even though the channel has not yet been announced") |
|
|
|
self.channel_db.on_channel_announcement({"short_channel_id": chan.short_channel_id, "node_id_1": node_ids[0], "node_id_2": node_ids[1], |
|
|
|
'chain_hash': constants.net.rev_genesis_bytes(), 'len': b'\x00\x00', 'features': b'', |
|
|
|
'bitcoin_key_1': bitcoin_keys[0], 'bitcoin_key_2': bitcoin_keys[1]}, |
|
|
|
trusted=True) |
|
|
|
self.channel_db.on_channel_update({"short_channel_id": chan.short_channel_id, 'flags': b'\x01', 'cltv_expiry_delta': b'\x90', |
|
|
|
'htlc_minimum_msat': b'\x03\xe8', 'fee_base_msat': b'\x03\xe8', 'fee_proportional_millionths': b'\x01', |
|
|
|
'chain_hash': constants.net.rev_genesis_bytes(), 'timestamp': now}, |
|
|
|
trusted=True) |
|
|
|
self.channel_db.on_channel_update({"short_channel_id": chan.short_channel_id, 'flags': b'\x00', 'cltv_expiry_delta': b'\x90', |
|
|
|
# only inject outgoing direction: |
|
|
|
flags = b'\x00' if node_ids[0] == pubkey_ours else b'\x01' |
|
|
|
now = int(time.time()).to_bytes(4, byteorder="big") |
|
|
|
self.channel_db.on_channel_update({"short_channel_id": chan.short_channel_id, 'flags': flags, 'cltv_expiry_delta': b'\x90', |
|
|
|
'htlc_minimum_msat': b'\x03\xe8', 'fee_base_msat': b'\x03\xe8', 'fee_proportional_millionths': b'\x01', |
|
|
|
'chain_hash': constants.net.rev_genesis_bytes(), 'timestamp': now}, |
|
|
|
trusted=True) |
|
|
|
# peer may have sent us a channel update for the incoming direction previously |
|
|
|
# note: if we were offline when the 3rd conf happened, lnd will never send us this channel_update |
|
|
|
# see https://github.com/lightningnetwork/lnd/issues/1347 |
|
|
|
#self.send_message(gen_msg("query_short_channel_ids", chain_hash=constants.net.rev_genesis_bytes(), |
|
|
|
# len=9, encoded_short_ids=b'\x00'+chan.short_channel_id)) |
|
|
|
if hasattr(chan, 'pending_channel_update_message'): |
|
|
|
self.on_channel_update(chan.pending_channel_update_message) |
|
|
|
|
|
|
|
self.print_error("CHANNEL OPENING COMPLETED") |
|
|
|
|
|
|
|