Browse Source

lnutil: restructure channel config namedtuples (local/remote config)

dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
SomberNight 6 years ago
committed by ThomasV
parent
commit
521fadb8cb
  1. 44
      electrum/lnbase.py
  2. 78
      electrum/lnutil.py

44
electrum/lnbase.py

@ -26,7 +26,7 @@ from .transaction import Transaction, TxOutput
from .lnonion import (new_onion_packet, decode_onion_error, OnionFailureCode, calc_hops_data_for_payment, from .lnonion import (new_onion_packet, decode_onion_error, OnionFailureCode, calc_hops_data_for_payment,
process_onion_packet, OnionPacket, construct_onion_error, OnionRoutingFailureMessage) process_onion_packet, OnionPacket, construct_onion_error, OnionRoutingFailureMessage)
from .lnchan import Channel, RevokeAndAck, htlcsum from .lnchan import Channel, RevokeAndAck, htlcsum
from .lnutil import (Outpoint, LocalConfig, ChannelConfig, from .lnutil import (Outpoint, LocalConfig,
RemoteConfig, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore, RemoteConfig, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore,
funding_output_script, get_per_commitment_secret_from_seed, funding_output_script, get_per_commitment_secret_from_seed,
secret_to_pubkey, LNPeerAddr, PaymentFailure, LnLocalFeatures, secret_to_pubkey, LNPeerAddr, PaymentFailure, LnLocalFeatures,
@ -381,7 +381,7 @@ class Peer(PrintError):
chan.set_state('DISCONNECTED') chan.set_state('DISCONNECTED')
self.network.trigger_callback('channel', chan) self.network.trigger_callback('channel', chan)
def make_local_config(self, funding_sat: int, push_msat: int, initiator: HTLCOwner) -> Tuple[ChannelConfig, bytes]: def make_local_config(self, funding_sat: int, push_msat: int, initiator: HTLCOwner) -> LocalConfig:
# key derivation # key derivation
channel_counter = self.lnworker.get_and_inc_counter_for_channel_keys() channel_counter = self.lnworker.get_and_inc_counter_for_channel_keys()
keypair_generator = lambda family: generate_keypair(self.lnworker.ln_keystore, family, channel_counter) keypair_generator = lambda family: generate_keypair(self.lnworker.ln_keystore, family, channel_counter)
@ -389,7 +389,7 @@ class Peer(PrintError):
initial_msat = funding_sat * 1000 - push_msat initial_msat = funding_sat * 1000 - push_msat
else: else:
initial_msat = push_msat initial_msat = push_msat
local_config=ChannelConfig( local_config=LocalConfig(
payment_basepoint=keypair_generator(LnKeyFamily.PAYMENT_BASE), payment_basepoint=keypair_generator(LnKeyFamily.PAYMENT_BASE),
multisig_key=keypair_generator(LnKeyFamily.MULTISIG), multisig_key=keypair_generator(LnKeyFamily.MULTISIG),
htlc_basepoint=keypair_generator(LnKeyFamily.HTLC_BASE), htlc_basepoint=keypair_generator(LnKeyFamily.HTLC_BASE),
@ -404,9 +404,13 @@ class Peer(PrintError):
next_htlc_id=0, next_htlc_id=0,
amount_msat=initial_msat, amount_msat=initial_msat,
reserve_sat=546, reserve_sat=546,
per_commitment_secret_seed=keypair_generator(LnKeyFamily.REVOCATION_ROOT).privkey,
funding_locked_received=False,
was_announced=False,
current_commitment_signature=None,
current_htlc_signatures=[],
) )
per_commitment_secret_seed = keypair_generator(LnKeyFamily.REVOCATION_ROOT).privkey return local_config
return local_config, per_commitment_secret_seed
@log_exceptions @log_exceptions
async def channel_establishment_flow(self, password: Optional[str], funding_sat: int, async def channel_establishment_flow(self, password: Optional[str], funding_sat: int,
@ -417,9 +421,10 @@ class Peer(PrintError):
password, self.lnworker.config, nonlocal_only=True) password, self.lnworker.config, nonlocal_only=True)
await self.initialized await self.initialized
feerate = self.current_feerate_per_kw() feerate = self.current_feerate_per_kw()
local_config, per_commitment_secret_seed = self.make_local_config(funding_sat, push_msat, LOCAL) local_config = self.make_local_config(funding_sat, push_msat, LOCAL)
# for the first commitment transaction # for the first commitment transaction
per_commitment_secret_first = get_per_commitment_secret_from_seed(per_commitment_secret_seed, RevocationStore.START_INDEX) per_commitment_secret_first = get_per_commitment_secret_from_seed(local_config.per_commitment_secret_seed,
RevocationStore.START_INDEX)
per_commitment_point_first = secret_to_pubkey(int.from_bytes(per_commitment_secret_first, 'big')) per_commitment_point_first = secret_to_pubkey(int.from_bytes(per_commitment_secret_first, 'big'))
self.send_message( self.send_message(
"open_channel", "open_channel",
@ -488,14 +493,7 @@ class Peer(PrintError):
"short_channel_id": None, "short_channel_id": None,
"funding_outpoint": Outpoint(funding_txid, funding_index), "funding_outpoint": Outpoint(funding_txid, funding_index),
"remote_config": remote_config, "remote_config": remote_config,
"local_config": LocalConfig( "local_config": local_config,
**local_config._asdict(),
per_commitment_secret_seed=per_commitment_secret_seed,
funding_locked_received = False,
was_announced = False,
current_commitment_signature = None,
current_htlc_signatures = None,
),
"constraints": ChannelConstraints(capacity=funding_sat, is_initiator=True, funding_txn_minimum_depth=funding_txn_minimum_depth, feerate=feerate), "constraints": ChannelConstraints(capacity=funding_sat, is_initiator=True, funding_txn_minimum_depth=funding_txn_minimum_depth, feerate=feerate),
"remote_commitment_to_be_revoked": None, "remote_commitment_to_be_revoked": None,
} }
@ -530,12 +528,11 @@ class Peer(PrintError):
feerate = int.from_bytes(payload['feerate_per_kw'], 'big') feerate = int.from_bytes(payload['feerate_per_kw'], 'big')
temp_chan_id = payload['temporary_channel_id'] temp_chan_id = payload['temporary_channel_id']
local_config, per_commitment_secret_seed = self.make_local_config(funding_sat * 1000, push_msat, REMOTE) local_config = self.make_local_config(funding_sat * 1000, push_msat, REMOTE)
# for the first commitment transaction # for the first commitment transaction
per_commitment_secret_first = get_per_commitment_secret_from_seed(per_commitment_secret_seed, RevocationStore.START_INDEX) per_commitment_secret_first = get_per_commitment_secret_from_seed(local_config.per_commitment_secret_seed,
RevocationStore.START_INDEX)
per_commitment_point_first = secret_to_pubkey(int.from_bytes(per_commitment_secret_first, 'big')) per_commitment_point_first = secret_to_pubkey(int.from_bytes(per_commitment_secret_first, 'big'))
min_depth = 3 min_depth = 3
self.send_message('accept_channel', self.send_message('accept_channel',
temporary_channel_id=temp_chan_id, temporary_channel_id=temp_chan_id,
@ -586,14 +583,7 @@ class Peer(PrintError):
current_per_commitment_point=None, current_per_commitment_point=None,
revocation_store=their_revocation_store, revocation_store=their_revocation_store,
), ),
"local_config": LocalConfig( "local_config": local_config,
**local_config._asdict(),
per_commitment_secret_seed=per_commitment_secret_seed,
funding_locked_received = False,
was_announced = False,
current_commitment_signature = None,
current_htlc_signatures = None,
),
"constraints": ChannelConstraints(capacity=funding_sat, is_initiator=False, funding_txn_minimum_depth=min_depth, feerate=feerate), "constraints": ChannelConstraints(capacity=funding_sat, is_initiator=False, funding_txn_minimum_depth=min_depth, feerate=feerate),
"remote_commitment_to_be_revoked": None, "remote_commitment_to_be_revoked": None,
} }

78
electrum/lnutil.py

@ -27,32 +27,53 @@ HTLC_SUCCESS_WEIGHT = 703
Keypair = namedtuple("Keypair", ["pubkey", "privkey"]) Keypair = namedtuple("Keypair", ["pubkey", "privkey"])
OnlyPubkeyKeypair = namedtuple("OnlyPubkeyKeypair", ["pubkey"]) OnlyPubkeyKeypair = namedtuple("OnlyPubkeyKeypair", ["pubkey"])
common = [
('ctn' , int), # NamedTuples cannot subclass NamedTuples :'( https://github.com/python/typing/issues/427
('amount_msat' , int), class LocalConfig(NamedTuple):
('next_htlc_id' , int), # shared channel config fields (DUPLICATED code!!)
('payment_basepoint' , Keypair), ctn: int
('multisig_key' , Keypair), amount_msat: int
('htlc_basepoint' , Keypair), next_htlc_id: int
('delayed_basepoint' , Keypair), payment_basepoint: 'Keypair'
('revocation_basepoint' , Keypair), multisig_key: 'Keypair'
('to_self_delay' , int), htlc_basepoint: 'Keypair'
('dust_limit_sat' , int), delayed_basepoint: 'Keypair'
('max_htlc_value_in_flight_msat' , int), revocation_basepoint: 'Keypair'
('max_accepted_htlcs' , int), to_self_delay: int
('initial_msat' , int), dust_limit_sat: int
('reserve_sat', int), max_htlc_value_in_flight_msat: int
] max_accepted_htlcs: int
initial_msat: int
ChannelConfig = NamedTuple('ChannelConfig', common) reserve_sat: int
# specific to "LOCAL" config
LocalConfig = NamedTuple('LocalConfig', common + [ per_commitment_secret_seed: bytes
('per_commitment_secret_seed', bytes), funding_locked_received: bool
('funding_locked_received', bool), was_announced: bool
('was_announced', bool), current_commitment_signature: Optional[bytes]
('current_commitment_signature', bytes), current_htlc_signatures: List[bytes]
('current_htlc_signatures', List[bytes]),
])
class RemoteConfig(NamedTuple):
# shared channel config fields (DUPLICATED code!!)
ctn: int
amount_msat: int
next_htlc_id: int
payment_basepoint: 'Keypair'
multisig_key: 'Keypair'
htlc_basepoint: 'Keypair'
delayed_basepoint: 'Keypair'
revocation_basepoint: 'Keypair'
to_self_delay: int
dust_limit_sat: int
max_htlc_value_in_flight_msat: int
max_accepted_htlcs: int
initial_msat: int
reserve_sat: int
# specific to "REMOTE" config
next_per_commitment_point: bytes
revocation_store: 'RevocationStore'
current_per_commitment_point: Optional[bytes]
ChannelConstraints = namedtuple("ChannelConstraints", ["capacity", "is_initiator", "funding_txn_minimum_depth", "feerate"]) ChannelConstraints = namedtuple("ChannelConstraints", ["capacity", "is_initiator", "funding_txn_minimum_depth", "feerate"])
@ -129,11 +150,6 @@ class RevocationStore:
def __hash__(self): def __hash__(self):
return hash(json.dumps(self.serialize(), sort_keys=True)) return hash(json.dumps(self.serialize(), sort_keys=True))
RemoteConfig = NamedTuple('RemoteConfig', common + [
('next_per_commitment_point' , bytes),
('revocation_store' , RevocationStore),
('current_per_commitment_point' , bytes),
])
def count_trailing_zeros(index): def count_trailing_zeros(index):
""" BOLT-03 (where_to_put_secret) """ """ BOLT-03 (where_to_put_secret) """

Loading…
Cancel
Save