commit 39dcc2413303addae2fb5dac5c334c31abc06f3a
parent c2bbc1ec6050963db654b18013ce39616729a0f9
Author: Janus <ysangkok@gmail.com>
Date: Mon, 30 Apr 2018 23:34:33 +0200
lnbase: organize channel data
Diffstat:
2 files changed, 164 insertions(+), 91 deletions(-)
diff --git a/lib/lnbase.py b/lib/lnbase.py
@@ -32,14 +32,6 @@ from .util import PrintError, bh2u, print_error, bfh, profiler
from .transaction import opcodes, Transaction
from collections import namedtuple, defaultdict
-LocalCtxArgs = namedtuple("LocalCtxArgs",
- ["ctn",
- "funding_pubkey", "remote_funding_pubkey", "remotepubkey",
- "base_point", "remote_payment_basepoint",
- "remote_revocation_pubkey", "local_delayedpubkey", "to_self_delay",
- "funding_txid", "funding_index", "funding_satoshis",
- "local_amount", "remote_amount", "dust_limit_satoshis", "local_feerate",
- "commitment_owner"])
# hardcoded nodes
node_list = [
@@ -289,6 +281,17 @@ def create_ephemeral_key(privkey):
pub = privkey_to_pubkey(privkey)
return (privkey[:32], pub)
+Keypair = namedtuple("Keypair", ["pubkey", "privkey"])
+Outpoint = namedtuple("Outpoint", ["txid", "output_index"])
+ChannelConfig = namedtuple("ChannelConfig", [
+ "payment_key", "multisig_key", "htlc_key", "delayed_key", "revocation_key",
+ "to_self_delay", "dust_limit_sat", "max_htlc_value_in_flight_msat", "max_accepted_htlcs"])
+OnlyPubkeyKeypair = namedtuple("OnlyPubkeyKeypair", ["pubkey"])
+RemoteState = namedtuple("RemoteState", ["ctn", "next_per_commitment_point", "amount_sat"])
+LocalState = namedtuple("LocalState", ["ctn", "per_commitment_secret_seed", "amount_sat"])
+ChannelConstraints = namedtuple("ChannelConstraints", ["feerate", "capacity", "is_initiator"])
+OpenChannel = namedtuple("OpenChannel", ["channel_id", "funding_outpoint", "local_config", "remote_config", "remote_state", "local_state", "constraints"])
+
class KeypairGenerator:
def __init__(self, seed):
self.xprv, xpub = bitcoin.bip32_root(seed, "p2wpkh")
@@ -297,7 +300,7 @@ class KeypairGenerator:
_, _, _, _, child_c, child_cK = bitcoin.deserialize_xpub(childxpub)
_, _, _, _, _, k = bitcoin.deserialize_xprv(childxprv)
assert len(k) == 32
- return child_cK, k
+ return Keypair(pubkey=child_cK, privkey=k)
def aiosafe(f):
async def f2(*args, **kwargs):
@@ -446,12 +449,12 @@ def make_received_htlc(revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, p
+ bytes([opcodes.OP_CLTV, opcodes.OP_DROP, opcodes.OP_CHECKSIG, opcodes.OP_ENDIF, opcodes.OP_ENDIF])
-def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remotepubkey,
+def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remote_payment_pubkey,
payment_basepoint, remote_payment_basepoint,
revocation_pubkey, delayed_pubkey, to_self_delay,
- funding_txid, funding_pos, funding_satoshis,
+ funding_txid, funding_pos, funding_sat,
local_amount, remote_amount,
- dust_limit_satoshis, local_feerate, for_us, htlcs):
+ dust_limit_sat, local_feerate, for_us, htlcs):
pubkeys = sorted([bh2u(local_funding_pubkey), bh2u(remote_funding_pubkey)])
obs = get_obscured_ctn(ctn, payment_basepoint, remote_payment_basepoint)
@@ -466,7 +469,7 @@ def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remotepubk
'num_sig': 2,
'prevout_n': funding_pos,
'prevout_hash': funding_txid,
- 'value': funding_satoshis,
+ 'value': funding_sat,
'coinbase': False,
'sequence':sequence
}]
@@ -474,7 +477,7 @@ def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remotepubk
local_script = bytes([opcodes.OP_IF]) + bfh(push_script(bh2u(revocation_pubkey))) + bytes([opcodes.OP_ELSE]) + add_number_to_script(to_self_delay) \
+ bytes([opcodes.OP_CSV, opcodes.OP_DROP]) + bfh(push_script(bh2u(delayed_pubkey))) + bytes([opcodes.OP_ENDIF, opcodes.OP_CHECKSIG])
local_address = bitcoin.redeem_script_to_address('p2wsh', bh2u(local_script))
- remote_address = bitcoin.pubkey_to_address('p2wpkh', bh2u(remotepubkey))
+ remote_address = bitcoin.pubkey_to_address('p2wpkh', bh2u(remote_payment_pubkey))
# TODO trim htlc outputs here while also considering 2nd stage htlc transactions
fee = local_feerate * overall_weight(len(htlcs)) // 1000 # TODO incorrect if anything is trimmed
to_local = (bitcoin.TYPE_ADDRESS, local_address, local_amount - (fee if for_us else 0))
@@ -483,7 +486,8 @@ def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remotepubk
for script, msat_amount in htlcs:
c_outputs += [(bitcoin.TYPE_ADDRESS, bitcoin.redeem_script_to_address('p2wsh', bh2u(script)), msat_amount // 1000)]
# trim outputs
- c_outputs = list(filter(lambda x:x[2]>= dust_limit_satoshis, c_outputs))
+ c_outputs = list(filter(lambda x:x[2]>= dust_limit_sat, c_outputs))
+ assert sum(x[2] for x in c_outputs) <= funding_sat
# create commitment tx
tx = Transaction.from_io(c_inputs, c_outputs, locktime=locktime, version=2)
@@ -687,7 +691,7 @@ class Peer(PrintError):
self.channel_db.on_channel_announcement(payload)
#def open_channel(self, funding_sat, push_msat):
- # self.send_message(gen_msg('open_channel', funding_satoshis=funding_sat, push_msat=push_msat))
+ # self.send_message(gen_msg('open_channel', funding_sat=funding_sat, push_msat=push_msat))
@aiosafe
async def main_loop(self):
@@ -710,7 +714,7 @@ class Peer(PrintError):
self.writer.close()
@aiosafe
- async def channel_establishment_flow(self, wallet, config, funding_satoshis, push_msat, temp_channel_id, keypair_generator=None):
+ async def channel_establishment_flow(self, wallet, config, funding_sat, push_msat, temp_channel_id, keypair_generator=None):
await self.initialized
if keypair_generator is None:
@@ -725,40 +729,41 @@ class Peer(PrintError):
keyfamilyrevocationroot = 5
keyfamilynodekey = 6 # TODO currently unused
- funding_pubkey, funding_privkey = keypair_generator.get(keyfamilymultisig, 0)
- revocation_basepoint, _ = keypair_generator.get(keyfamilyrevocationbase, 0)
- htlc_basepoint, htlc_privkey = keypair_generator.get(keyfamilyhtlcbase, 0)
- delayed_payment_basepoint, delayed_privkey = keypair_generator.get(keyfamilydelaybase, 0)
- base_point, _ = keypair_generator.get(keyfamilypaymentbase, 0)
+ funding_key = keypair_generator.get(keyfamilymultisig, 0)
+ revocation_key = keypair_generator.get(keyfamilyrevocationbase, 0)
+ htlc_key = keypair_generator.get(keyfamilyhtlcbase, 0)
+ delayed_key = keypair_generator.get(keyfamilydelaybase, 0)
+ base_point = keypair_generator.get(keyfamilypaymentbase, 0)
per_commitment_secret_seed = 0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100.to_bytes(32, "big")
per_commitment_secret_index = 2**48 - 1
# amounts
local_feerate = 20000
- dust_limit_satoshis = 10
to_self_delay = 144
- ctn = 0
+ dust_limit_sat = 10
#
per_commitment_secret_first = get_per_commitment_secret_from_seed(per_commitment_secret_seed, per_commitment_secret_index)
per_commitment_point_first = secret_to_pubkey(int.from_bytes(
per_commitment_secret_first,
byteorder="big"))
+ local_max_htlc_value_in_flight_msat = 500000 * 1000
+ local_max_accepted_htlcs = 5
msg = gen_msg(
"open_channel",
temporary_channel_id=temp_channel_id,
chain_hash=bytes.fromhex(rev_hex(constants.net.GENESIS)),
- funding_satoshis=funding_satoshis,
+ funding_satoshis=funding_sat,
push_msat=push_msat,
- dust_limit_satoshis=dust_limit_satoshis,
+ dust_limit_satoshis=dust_limit_sat,
feerate_per_kw=local_feerate,
- max_accepted_htlcs=5,
- funding_pubkey=funding_pubkey,
- revocation_basepoint=revocation_basepoint,
- htlc_basepoint=htlc_basepoint,
- payment_basepoint=base_point,
- delayed_payment_basepoint=delayed_payment_basepoint,
+ max_accepted_htlcs=local_max_accepted_htlcs,
+ funding_pubkey=funding_key.pubkey,
+ revocation_basepoint=revocation_key.pubkey,
+ htlc_basepoint=htlc_key.pubkey,
+ payment_basepoint=base_point.pubkey,
+ delayed_payment_basepoint=delayed_key.pubkey,
first_per_commitment_point=per_commitment_point_first,
to_self_delay=to_self_delay,
- max_htlc_value_in_flight_msat=500000 * 1000
+ max_htlc_value_in_flight_msat=local_max_htlc_value_in_flight_msat
)
#self.channel_accepted[temp_channel_id] = asyncio.Future()
self.send_message(msg)
@@ -766,10 +771,11 @@ class Peer(PrintError):
payload = await self.channel_accepted[temp_channel_id]
finally:
del self.channel_accepted[temp_channel_id]
+ remote_max_accepted_htlcs = payload["max_accepted_htlcs"]
remote_per_commitment_point = payload['first_per_commitment_point']
remote_funding_pubkey = payload["funding_pubkey"]
remote_delay = int.from_bytes(payload['to_self_delay'], byteorder="big")
- remote_dust_limit_satoshis = int.from_bytes(payload['dust_limit_satoshis'], byteorder="big")
+ remote_dust_limit_sat = int.from_bytes(payload['dust_limit_satoshis'], byteorder="big")
remote_revocation_basepoint = payload['revocation_basepoint']
remote_payment_basepoint = payload['payment_basepoint']
remote_delayed_payment_basepoint = payload['delayed_payment_basepoint']
@@ -777,44 +783,44 @@ class Peer(PrintError):
remote_htlc_minimum_msat = int.from_bytes(payload['htlc_minimum_msat'], "big")
remote_max_htlc_value_in_flight_msat = int.from_bytes(payload['max_htlc_value_in_flight_msat'], "big")
funding_txn_minimum_depth = int.from_bytes(payload['minimum_depth'], byteorder="big")
- print('remote dust limit', remote_dust_limit_satoshis)
- assert remote_dust_limit_satoshis < 600
+ print('remote dust limit', remote_dust_limit_sat)
+ assert remote_dust_limit_sat < 600
assert remote_htlc_minimum_msat < 600 * 1000
assert remote_max_htlc_value_in_flight_msat >= 500 * 1000 * 1000, remote_max_htlc_value_in_flight_msat
self.print_error('remote delay', remote_delay)
self.print_error('funding_txn_minimum_depth', funding_txn_minimum_depth)
# create funding tx
- pubkeys = sorted([bh2u(funding_pubkey), bh2u(remote_funding_pubkey)])
+ pubkeys = sorted([bh2u(funding_key.pubkey), bh2u(remote_funding_pubkey)])
redeem_script = transaction.multisig_script(pubkeys, 2)
funding_address = bitcoin.redeem_script_to_address('p2wsh', redeem_script)
- funding_output = (bitcoin.TYPE_ADDRESS, funding_address, funding_satoshis)
+ funding_output = (bitcoin.TYPE_ADDRESS, funding_address, funding_sat)
funding_tx = wallet.mktx([funding_output], None, config, 1000)
funding_txid = funding_tx.txid()
funding_index = funding_tx.outputs().index(funding_output)
# derive keys
- localpubkey = derive_pubkey(base_point, remote_per_commitment_point) #local_payment_pubkey
- #localprivkey = derive_privkey(base_secret, remote_per_commitment_point)
- remotepubkey = derive_pubkey(remote_payment_basepoint, per_commitment_point_first)
- revocation_pubkey = derive_blinded_pubkey(revocation_basepoint, remote_per_commitment_point)
+ local_payment_pubkey = derive_pubkey(base_point.pubkey, remote_per_commitment_point)
+ #local_payment_privkey = derive_privkey(base_secret, remote_per_commitment_point)
+ remote_payment_pubkey = derive_pubkey(remote_payment_basepoint, per_commitment_point_first)
+ revocation_pubkey = derive_blinded_pubkey(revocation_key.pubkey, remote_per_commitment_point)
remote_revocation_pubkey = derive_blinded_pubkey(remote_revocation_basepoint, per_commitment_point_first)
- local_delayedpubkey = derive_pubkey(delayed_payment_basepoint, per_commitment_point_first)
+ local_delayedpubkey = derive_pubkey(delayed_key.pubkey, per_commitment_point_first)
remote_delayedpubkey = derive_pubkey(remote_delayed_payment_basepoint, remote_per_commitment_point)
# compute amounts
htlcs = []
- to_local_msat = funding_satoshis*1000 - push_msat
+ to_local_msat = funding_sat*1000 - push_msat
to_remote_msat = push_msat
local_amount = to_local_msat // 1000
remote_amount = to_remote_msat // 1000
# remote commitment transaction
remote_ctx = make_commitment(
- ctn,
- remote_funding_pubkey, funding_pubkey, localpubkey,
- base_point, remote_payment_basepoint,
+ 0,
+ remote_funding_pubkey, funding_key.pubkey, local_payment_pubkey,
+ base_point.pubkey, remote_payment_basepoint,
revocation_pubkey, remote_delayedpubkey, remote_delay,
- funding_txid, funding_index, funding_satoshis,
- remote_amount, local_amount, remote_dust_limit_satoshis, local_feerate, False, htlcs=[])
- remote_ctx.sign({bh2u(funding_pubkey): (funding_privkey, True)})
- sig_index = pubkeys.index(bh2u(funding_pubkey))
+ funding_txid, funding_index, funding_sat,
+ remote_amount, local_amount, remote_dust_limit_sat, local_feerate, False, htlcs=[])
+ remote_ctx.sign({bh2u(funding_key.pubkey): (funding_key.privkey, True)})
+ sig_index = pubkeys.index(bh2u(funding_key.pubkey))
sig = bytes.fromhex(remote_ctx.inputs()[0]["signatures"][sig_index])
r, s = sigdecode_der(sig[:-1], SECP256k1.generator.order())
sig_64 = sigencode_string_canonize(r, s, SECP256k1.generator.order())
@@ -829,14 +835,13 @@ class Peer(PrintError):
self.print_error('received funding_signed')
remote_sig = payload['signature']
# verify remote signature
- local_ctx_args = LocalCtxArgs(
- ctn,
- funding_pubkey, remote_funding_pubkey, remotepubkey,
- base_point, remote_payment_basepoint,
+ local_ctx = make_commitment(
+ 0,
+ funding_key.pubkey, remote_funding_pubkey, remote_payment_pubkey,
+ base_point.pubkey, remote_payment_basepoint,
remote_revocation_pubkey, local_delayedpubkey, to_self_delay,
- funding_txid, funding_index, funding_satoshis,
- local_amount, remote_amount, dust_limit_satoshis, local_feerate, True)
- local_ctx = make_commitment(*local_ctx_args, htlcs=[])
+ funding_txid, funding_index, funding_sat,
+ local_amount, remote_amount, dust_limit_sat, local_feerate, True, htlcs=[])
pre_hash = bitcoin.Hash(bfh(local_ctx.serialize_preimage(0)))
if not bitcoin.verify_signature(remote_funding_pubkey, remote_sig, pre_hash):
raise Exception('verifying remote signature failed.')
@@ -876,18 +881,68 @@ class Peer(PrintError):
del self.remote_funding_locked[channel_id]
self.print_error('Done waiting for remote_funding_locked', remote_funding_locked_msg)
#self.commitment_signed[channel_id] = asyncio.Future()
- return channel_id, per_commitment_secret_seed, local_ctx_args, remote_funding_pubkey, remote_funding_locked_msg, remote_revocation_basepoint, remote_htlc_basepoint, htlc_basepoint, delayed_payment_basepoint, revocation_basepoint, remote_delayed_payment_basepoint, remote_delay, remote_dust_limit_satoshis, funding_privkey, htlc_privkey
- async def receive_commitment_revoke_ack(self, channel_id, local_per_commitment_secret_seed, local_last_pcs_index, local_ctx_args, expected_received_sat, remote_funding_pubkey, local_next_commitment_number, remote_next_commitment_point, remote_revocation_basepoint, remote_htlc_basepoint, local_htlc_basepoint, delayed_payment_basepoint, revocation_basepoint, remote_delayed_payment_basepoint, remote_delay, remote_dust_limit_satoshis, funding_privkey, payment_preimage, htlc_privkey):
+ return OpenChannel(
+ channel_id=channel_id,
+ funding_outpoint=Outpoint(funding_txid, funding_index),
+ local_config=ChannelConfig(
+ payment_key=base_point,
+ multisig_key=funding_key,
+ htlc_key=htlc_key,
+ delayed_key=delayed_key,
+ revocation_key=revocation_key,
+ to_self_delay=to_self_delay,
+ dust_limit_sat=dust_limit_sat,
+ max_htlc_value_in_flight_msat=local_max_htlc_value_in_flight_msat,
+ max_accepted_htlcs=local_max_accepted_htlcs
+ ),
+ remote_config=ChannelConfig(
+ payment_key=OnlyPubkeyKeypair(remote_payment_basepoint),
+ multisig_key=OnlyPubkeyKeypair(remote_funding_pubkey),
+ htlc_key=OnlyPubkeyKeypair(remote_htlc_basepoint),
+ delayed_key=OnlyPubkeyKeypair(remote_delayed_payment_basepoint),
+ revocation_key=OnlyPubkeyKeypair(remote_revocation_basepoint),
+ to_self_delay=remote_delay,
+ dust_limit_sat=remote_dust_limit_sat,
+ max_htlc_value_in_flight_msat=remote_max_htlc_value_in_flight_msat,
+ max_accepted_htlcs=remote_max_accepted_htlcs
+ ),
+ remote_state=RemoteState(
+ ctn = 0,
+ next_per_commitment_point=remote_funding_locked_msg["next_per_commitment_point"],
+ amount_sat=remote_amount
+ ),
+ local_state=LocalState(
+ ctn = 0,
+ per_commitment_secret_seed=per_commitment_secret_seed,
+ amount_sat=local_amount
+ ),
+ constraints=ChannelConstraints(capacity=funding_sat, feerate=local_feerate, is_initiator=True)
+ )
+
+ async def receive_commitment_revoke_ack(self, openchannel, expected_received_sat, payment_preimage):
+ channel_id = openchannel.channel_id
+ local_per_commitment_secret_seed = openchannel.local_state.per_commitment_secret_seed
+ assert openchannel.local_state.ctn == 0
+ local_next_pcs_index = 2**48 - 2
+ remote_funding_pubkey = openchannel.remote_config.multisig_key.pubkey
+ remote_next_commitment_point = openchannel.remote_state.next_per_commitment_point
+ remote_revocation_basepoint = openchannel.remote_config.revocation_key.pubkey
+ remote_htlc_basepoint = openchannel.remote_config.htlc_key.pubkey
+ local_htlc_basepoint = openchannel.local_config.htlc_key.pubkey
+ delayed_payment_basepoint = openchannel.local_config.delayed_key.pubkey
+ revocation_basepoint = openchannel.local_config.revocation_key.pubkey
+ remote_delayed_payment_basepoint = openchannel.remote_config.delayed_key.pubkey
+ remote_delay = openchannel.remote_config.to_self_delay
+ remote_dust_limit_sat = openchannel.remote_config.dust_limit_sat
+ funding_privkey = openchannel.local_config.multisig_key.privkey
+ htlc_privkey = openchannel.local_config.htlc_key.privkey
try:
commitment_signed_msg = await self.commitment_signed[channel_id]
finally:
del self.commitment_signed[channel_id]
- # TODO make new future? (there could be more updates)
-
- local_last_per_commitment_secret = get_per_commitment_secret_from_seed(local_per_commitment_secret_seed, local_last_pcs_index)
- local_next_per_commitment_secret = get_per_commitment_secret_from_seed(local_per_commitment_secret_seed, local_last_pcs_index - 1)
+ local_next_per_commitment_secret = get_per_commitment_secret_from_seed(local_per_commitment_secret_seed, local_next_pcs_index)
local_next_per_commitment_point = secret_to_pubkey(int.from_bytes(
local_next_per_commitment_secret,
byteorder="big"))
@@ -902,11 +957,6 @@ class Peer(PrintError):
amount_msat = int.from_bytes(self.unfulfilled_htlcs[0]["amount_msat"], "big")
remote_revocation_pubkey = derive_blinded_pubkey(remote_revocation_basepoint, local_next_per_commitment_point)
- local_ctx_args = local_ctx_args._replace(remote_amount = local_ctx_args.remote_amount - expected_received_sat)
- local_ctx_args = local_ctx_args._replace(ctn = local_next_commitment_number)
- local_ctx_args = local_ctx_args._replace(remote_revocation_pubkey = remote_revocation_pubkey)
- local_ctx_args = local_ctx_args._replace(remotepubkey = derive_pubkey(local_ctx_args.remote_payment_basepoint, local_next_per_commitment_point))
- local_ctx_args = local_ctx_args._replace(local_delayedpubkey = derive_pubkey(delayed_payment_basepoint, local_next_per_commitment_point))
htlcs_in_local = [
(
@@ -915,7 +965,23 @@ class Peer(PrintError):
)
]
- new_commitment = make_commitment(*local_ctx_args, htlcs=htlcs_in_local)
+ new_commitment = make_commitment(
+ 1,
+ openchannel.local_config.multisig_key.pubkey,
+ openchannel.remote_config.multisig_key.pubkey,
+ derive_pubkey(openchannel.remote_config.payment_key.pubkey, local_next_per_commitment_point),
+ openchannel.local_config.payment_key.pubkey,
+ openchannel.remote_config.payment_key.pubkey,
+ remote_revocation_pubkey,
+ derive_pubkey(delayed_payment_basepoint, local_next_per_commitment_point),
+ openchannel.local_config.to_self_delay,
+ *openchannel.funding_outpoint,
+ openchannel.constraints.capacity,
+ openchannel.local_state.amount_sat,
+ openchannel.remote_state.amount_sat - expected_received_sat,
+ openchannel.local_config.dust_limit_sat,
+ openchannel.constraints.feerate,
+ True, htlcs=htlcs_in_local)
preimage_hex = new_commitment.serialize_preimage(0)
pre_hash = bitcoin.Hash(bfh(preimage_hex))
if not bitcoin.verify_signature(remote_funding_pubkey, commitment_signed_msg["signature"], pre_hash):
@@ -927,7 +993,13 @@ class Peer(PrintError):
# TODO verify htlc_signature
- pubkeys = sorted([bh2u(local_ctx_args.funding_pubkey), bh2u(remote_funding_pubkey)])
+ local_last_pcs_index = 2**48 - openchannel.local_state.ctn - 1
+ local_last_per_commitment_secret = get_per_commitment_secret_from_seed(local_per_commitment_secret_seed, local_last_pcs_index)
+
+ self.send_message(gen_msg("revoke_and_ack", channel_id=channel_id, per_commitment_secret=local_last_per_commitment_secret, next_per_commitment_point=local_next_per_commitment_point))
+
+ funding_pubkey = openchannel.local_config.multisig_key.pubkey
+ pubkeys = sorted([bh2u(funding_pubkey), bh2u(remote_funding_pubkey)])
revocation_pubkey = derive_blinded_pubkey(revocation_basepoint, remote_next_commitment_point)
remote_delayedpubkey = derive_pubkey(remote_delayed_payment_basepoint, remote_next_commitment_point)
their_local_htlc_pubkey = derive_pubkey(remote_htlc_basepoint, remote_next_commitment_point)
@@ -936,25 +1008,24 @@ class Peer(PrintError):
their_remote_htlc_privkey = their_remote_htlc_privkey_number.to_bytes(32, "big")
# TODO check payment_hash
htlcs_in_remote = [(make_offered_htlc(revocation_pubkey, their_remote_htlc_pubkey, their_local_htlc_pubkey, payment_hash), amount_msat)]
- local_payment_pubkey = derive_pubkey(local_ctx_args.base_point, remote_next_commitment_point)
+ local_payment_pubkey = derive_pubkey(openchannel.local_config.payment_key.pubkey, remote_next_commitment_point)
remote_ctx = make_commitment(
1,
- remote_funding_pubkey, local_ctx_args.funding_pubkey, local_payment_pubkey,
- local_ctx_args.base_point, local_ctx_args.remote_payment_basepoint,
+ remote_funding_pubkey, funding_pubkey, local_payment_pubkey,
+ openchannel.local_config.payment_key.pubkey, openchannel.remote_config.payment_key.pubkey,
revocation_pubkey, remote_delayedpubkey, remote_delay,
- local_ctx_args.funding_txid, local_ctx_args.funding_index, local_ctx_args.funding_satoshis,
- local_ctx_args.remote_amount, local_ctx_args.local_amount, remote_dust_limit_satoshis, local_ctx_args.local_feerate, False, htlcs=htlcs_in_remote)
- remote_ctx.sign({bh2u(local_ctx_args.funding_pubkey): (funding_privkey, True)})
- sig_index = pubkeys.index(bh2u(local_ctx_args.funding_pubkey))
+ *openchannel.funding_outpoint, openchannel.constraints.capacity,
+ openchannel.remote_state.amount_sat - expected_received_sat, openchannel.local_state.amount_sat, remote_dust_limit_sat,
+ openchannel.constraints.feerate, False, htlcs=htlcs_in_remote)
+ remote_ctx.sign({bh2u(funding_pubkey): (funding_privkey, True)})
+ sig_index = pubkeys.index(bh2u(funding_pubkey))
sig = bytes.fromhex(remote_ctx.inputs()[0]["signatures"][sig_index])
r, s = sigdecode_der(sig[:-1], SECP256k1.generator.order())
sig_64 = sigencode_string_canonize(r, s, SECP256k1.generator.order())
- self.send_message(gen_msg("revoke_and_ack", channel_id=channel_id, per_commitment_secret=local_last_per_commitment_secret, next_per_commitment_point=local_next_per_commitment_point))
-
htlc_tx_output = make_htlc_tx_output(
amount_msat = amount_msat,
- local_feerate = local_ctx_args.local_feerate,
+ local_feerate = openchannel.constraints.feerate,
revocationpubkey=revocation_pubkey,
local_delayedpubkey=remote_delayedpubkey,
success = False) # timeout for the one offering an HTLC
@@ -990,18 +1061,19 @@ class Peer(PrintError):
revocation_pubkey = derive_blinded_pubkey(revocation_basepoint, remote_next_commitment_point)
remote_delayedpubkey = derive_pubkey(remote_delayed_payment_basepoint, remote_next_commitment_point)
- local_payment_pubkey = derive_pubkey(local_ctx_args.base_point, remote_next_commitment_point)
- # local commitment transaction without htlcs
+ local_payment_pubkey = derive_pubkey(openchannel.local_config.payment_key.pubkey, remote_next_commitment_point)
+ # remote commitment transaction without htlcs
bare_ctx = make_commitment(
2,
- remote_funding_pubkey, local_ctx_args.funding_pubkey, local_payment_pubkey,
- local_ctx_args.base_point, local_ctx_args.remote_payment_basepoint,
+ remote_funding_pubkey, funding_pubkey, local_payment_pubkey,
+ openchannel.local_config.payment_key.pubkey, openchannel.remote_config.payment_key.pubkey,
revocation_pubkey, remote_delayedpubkey, remote_delay,
- local_ctx_args.funding_txid, local_ctx_args.funding_index, local_ctx_args.funding_satoshis,
- local_ctx_args.remote_amount, local_ctx_args.local_amount + expected_received_sat, remote_dust_limit_satoshis, local_ctx_args.local_feerate, False, htlcs=[])
+ *openchannel.funding_outpoint, openchannel.constraints.capacity,
+ openchannel.remote_state.amount_sat - expected_received_sat, openchannel.local_state.amount_sat + expected_received_sat,
+ remote_dust_limit_sat, openchannel.constraints.feerate, False, htlcs=[])
- bare_ctx.sign({bh2u(local_ctx_args.funding_pubkey): (funding_privkey, True)})
- sig_index = pubkeys.index(bh2u(local_ctx_args.funding_pubkey))
+ bare_ctx.sign({bh2u(funding_pubkey): (funding_privkey, True)})
+ sig_index = pubkeys.index(bh2u(funding_pubkey))
sig = bytes.fromhex(bare_ctx.inputs()[0]["signatures"][sig_index])
r, s = sigdecode_der(sig[:-1], SECP256k1.generator.order())
sig_64 = sigencode_string_canonize(r, s, SECP256k1.generator.order())
diff --git a/lib/tests/test_lnbase_online.py b/lib/tests/test_lnbase_online.py
@@ -4,6 +4,7 @@ import json
import binascii
import asyncio
import time
+import os
from lib.bitcoin import sha256
from decimal import Decimal
@@ -50,12 +51,12 @@ if __name__ == "__main__":
async def async_test():
payment_preimage = bytes.fromhex("01"*32)
RHASH = sha256(payment_preimage)
- channel_id, per_commitment_secret_seed, local_ctx_args, remote_funding_pubkey, remote_funding_locked_msg, remote_revocation_basepoint, remote_htlc_basepoint, local_htlc_basepoint, delayed_payment_basepoint, revocation_basepoint, remote_delayed_payment_basepoint, remote_delay, remote_dust_limit_satoshis, funding_privkey, htlc_privkey = await peer.channel_establishment_flow(wallet, config, funding_satoshis, push_msat)
+ openchannel = await peer.channel_establishment_flow(wallet, config, funding_satoshis, push_msat, temp_channel_id=os.urandom(32))
expected_received_sat = 400000
pay_req = lnencode(LnAddr(RHASH, amount=Decimal("0.00000001")*expected_received_sat, tags=[('d', 'one cup of coffee')]), peer.privkey[:32])
print("payment request", pay_req)
last_pcs_index = 2**48 - 1
- await peer.receive_commitment_revoke_ack(channel_id, per_commitment_secret_seed, last_pcs_index, local_ctx_args, expected_received_sat, remote_funding_pubkey, local_next_commitment_number=1, remote_next_commitment_point=remote_funding_locked_msg["next_per_commitment_point"], remote_revocation_basepoint=remote_revocation_basepoint, remote_htlc_basepoint=remote_htlc_basepoint, local_htlc_basepoint=local_htlc_basepoint, delayed_payment_basepoint=delayed_payment_basepoint, revocation_basepoint=revocation_basepoint, remote_delayed_payment_basepoint=remote_delayed_payment_basepoint, remote_delay=remote_delay, remote_dust_limit_satoshis=remote_dust_limit_satoshis, funding_privkey=funding_privkey, htlc_privkey=htlc_privkey, payment_preimage=payment_preimage)
+ await peer.receive_commitment_revoke_ack(openchannel, expected_received_sat, payment_preimage)
fut = asyncio.run_coroutine_threadsafe(async_test(), network.asyncio_loop)
while not fut.done():
time.sleep(1)