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

This commit is contained in:
SomberNight 2018-11-07 17:54:46 +01:00
parent 405ed49028
commit ce1ff477d0
No known key found for this signature in database
GPG key ID: B33B5F232C6271E9
2 changed files with 62 additions and 56 deletions

View file

@ -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,
} }

View file

@ -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),
('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),
]
ChannelConfig = NamedTuple('ChannelConfig', common) # NamedTuples cannot subclass NamedTuples :'( https://github.com/python/typing/issues/427
class LocalConfig(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 "LOCAL" config
per_commitment_secret_seed: bytes
funding_locked_received: bool
was_announced: bool
current_commitment_signature: Optional[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]
LocalConfig = NamedTuple('LocalConfig', common + [
('per_commitment_secret_seed', bytes),
('funding_locked_received', bool),
('was_announced', bool),
('current_commitment_signature', bytes),
('current_htlc_signatures', List[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) """