ln: avoid recursive dependencies, make new lnutil
This commit is contained in:
366
lib/lnbase.py
366
lib/lnbase.py
@@ -5,49 +5,12 @@
|
||||
"""
|
||||
|
||||
from collections import namedtuple, defaultdict, OrderedDict, defaultdict
|
||||
Keypair = namedtuple("Keypair", ["pubkey", "privkey"])
|
||||
Outpoint = namedtuple("Outpoint", ["txid", "output_index"])
|
||||
ChannelConfig = namedtuple("ChannelConfig", [
|
||||
"payment_basepoint", "multisig_key", "htlc_basepoint", "delayed_basepoint", "revocation_basepoint",
|
||||
"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_msat", "revocation_store", "current_per_commitment_point", "next_htlc_id"])
|
||||
LocalState = namedtuple("LocalState", ["ctn", "per_commitment_secret_seed", "amount_msat", "next_htlc_id", "funding_locked_received", "was_announced", "current_commitment_signature"])
|
||||
ChannelConstraints = namedtuple("ChannelConstraints", ["feerate", "capacity", "is_initiator", "funding_txn_minimum_depth"])
|
||||
#OpenChannel = namedtuple("OpenChannel", ["channel_id", "short_channel_id", "funding_outpoint", "local_config", "remote_config", "remote_state", "local_state", "constraints", "node_id"])
|
||||
|
||||
class RevocationStore:
|
||||
""" taken from lnd """
|
||||
def __init__(self):
|
||||
self.buckets = [None] * 48
|
||||
self.index = 2**48 - 1
|
||||
def add_next_entry(self, hsh):
|
||||
new_element = ShachainElement(index=self.index, secret=hsh)
|
||||
bucket = count_trailing_zeros(self.index)
|
||||
for i in range(0, bucket):
|
||||
this_bucket = self.buckets[i]
|
||||
e = shachain_derive(new_element, this_bucket.index)
|
||||
|
||||
if e != this_bucket:
|
||||
raise Exception("hash is not derivable: {} {} {}".format(bh2u(e.secret), bh2u(this_bucket.secret), this_bucket.index))
|
||||
self.buckets[bucket] = new_element
|
||||
self.index -= 1
|
||||
def serialize(self):
|
||||
return {"index": self.index, "buckets": [[bh2u(k.secret), k.index] if k is not None else None for k in self.buckets]}
|
||||
@staticmethod
|
||||
def from_json_obj(decoded_json_obj):
|
||||
store = RevocationStore()
|
||||
decode = lambda to_decode: ShachainElement(bfh(to_decode[0]), int(to_decode[1]))
|
||||
store.buckets = [k if k is None else decode(k) for k in decoded_json_obj["buckets"]]
|
||||
store.index = decoded_json_obj["index"]
|
||||
return store
|
||||
def __eq__(self, o):
|
||||
return type(o) is RevocationStore and self.serialize() == o.serialize()
|
||||
def __hash__(self):
|
||||
return hash(json.dumps(self.serialize(), sort_keys=True))
|
||||
from .lnutil import Outpoint, ChannelConfig, LocalState, RemoteState, Keypair, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore
|
||||
from .lnutil import sign_and_get_sig_string, funding_output_script, get_ecdh, get_per_commitment_secret_from_seed
|
||||
from .lnutil import secret_to_pubkey
|
||||
from .bitcoin import COIN
|
||||
|
||||
from ecdsa.util import sigdecode_der, sigencode_string_canonize, sigdecode_string
|
||||
from ecdsa.curves import SECP256k1
|
||||
import queue
|
||||
import traceback
|
||||
import json
|
||||
@@ -58,18 +21,8 @@ import time
|
||||
import binascii
|
||||
import hashlib
|
||||
import hmac
|
||||
from typing import Sequence, Union, Tuple
|
||||
import cryptography.hazmat.primitives.ciphers.aead as AEAD
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
HTLC_TIMEOUT_WEIGHT = 663
|
||||
HTLC_SUCCESS_WEIGHT = 703
|
||||
|
||||
from .ecc import ser_to_point, point_to_ser, string_to_number
|
||||
from .bitcoin import (deserialize_privkey, rev_hex, int_to_hex,
|
||||
push_script, script_num_to_hex,
|
||||
add_number_to_script, var_int, COIN)
|
||||
from . import bitcoin
|
||||
from . import ecc
|
||||
from . import crypto
|
||||
@@ -82,6 +35,8 @@ from .lnrouter import new_onion_packet, OnionHopsDataSingle, OnionPerHop, decode
|
||||
from .lightning_payencode.lnaddr import lndecode
|
||||
from .lnhtlc import UpdateAddHtlc, HTLCStateMachine, RevokeAndAck, SettleHtlc
|
||||
|
||||
REV_GENESIS = bytes.fromhex(bitcoin.rev_hex(constants.net.GENESIS))
|
||||
|
||||
def channel_id_from_funding_tx(funding_txid, funding_index):
|
||||
funding_txid_bytes = bytes.fromhex(funding_txid)[::-1]
|
||||
i = int.from_bytes(funding_txid_bytes, 'big') ^ funding_index
|
||||
@@ -289,10 +244,6 @@ def get_bolt8_hkdf(salt, ikm):
|
||||
assert len(T1 + T2) == 64
|
||||
return T1, T2
|
||||
|
||||
def get_ecdh(priv: bytes, pub: bytes) -> bytes:
|
||||
pt = ecc.ECPubkey(pub) * string_to_number(priv)
|
||||
return sha256(pt.get_public_key_bytes())
|
||||
|
||||
def act1_initiator_message(hs, my_privkey):
|
||||
#Get a new ephemeral key
|
||||
epriv, epub = create_ephemeral_key(my_privkey)
|
||||
@@ -328,290 +279,6 @@ def aiosafe(f):
|
||||
traceback.print_exc()
|
||||
return f2
|
||||
|
||||
def get_obscured_ctn(ctn, local, remote):
|
||||
mask = int.from_bytes(sha256(local + remote)[-6:], 'big')
|
||||
return ctn ^ mask
|
||||
|
||||
def secret_to_pubkey(secret):
|
||||
assert type(secret) is int
|
||||
return point_to_ser(SECP256k1.generator * secret)
|
||||
|
||||
def derive_pubkey(basepoint, per_commitment_point):
|
||||
p = ecc.ECPubkey(basepoint) + ecc.generator() * ecc.string_to_number(sha256(per_commitment_point + basepoint))
|
||||
return p.get_public_key_bytes()
|
||||
|
||||
def derive_privkey(secret, per_commitment_point):
|
||||
assert type(secret) is int
|
||||
basepoint = point_to_ser(SECP256k1.generator * secret)
|
||||
basepoint = secret + ecc.string_to_number(sha256(per_commitment_point + basepoint))
|
||||
basepoint %= SECP256k1.order
|
||||
return basepoint
|
||||
|
||||
def derive_blinded_pubkey(basepoint, per_commitment_point):
|
||||
k1 = ecc.ECPubkey(basepoint) * ecc.string_to_number(sha256(basepoint + per_commitment_point))
|
||||
k2 = ecc.ECPubkey(per_commitment_point) * ecc.string_to_number(sha256(per_commitment_point + basepoint))
|
||||
return (k1 + k2).get_public_key_bytes()
|
||||
|
||||
def shachain_derive(element, toIndex):
|
||||
return ShachainElement(get_per_commitment_secret_from_seed(element.secret, toIndex, count_trailing_zeros(element.index)), toIndex)
|
||||
|
||||
|
||||
def get_per_commitment_secret_from_seed(seed: bytes, i: int, bits: int = 48) -> bytes:
|
||||
"""Generate per commitment secret."""
|
||||
per_commitment_secret = bytearray(seed)
|
||||
for bitindex in range(bits - 1, -1, -1):
|
||||
mask = 1 << bitindex
|
||||
if i & mask:
|
||||
per_commitment_secret[bitindex // 8] ^= 1 << (bitindex % 8)
|
||||
per_commitment_secret = bytearray(sha256(per_commitment_secret))
|
||||
bajts = bytes(per_commitment_secret)
|
||||
return bajts
|
||||
|
||||
|
||||
def overall_weight(num_htlc):
|
||||
return 500 + 172 * num_htlc + 224
|
||||
|
||||
def make_htlc_tx_output(amount_msat, local_feerate, revocationpubkey, local_delayedpubkey, success, to_self_delay):
|
||||
assert type(amount_msat) is int
|
||||
assert type(local_feerate) is int
|
||||
assert type(revocationpubkey) is bytes
|
||||
assert type(local_delayedpubkey) is bytes
|
||||
script = bytes([opcodes.OP_IF]) \
|
||||
+ bfh(push_script(bh2u(revocationpubkey))) \
|
||||
+ bytes([opcodes.OP_ELSE]) \
|
||||
+ bitcoin.add_number_to_script(to_self_delay) \
|
||||
+ bytes([opcodes.OP_CSV, opcodes.OP_DROP]) \
|
||||
+ bfh(push_script(bh2u(local_delayedpubkey))) \
|
||||
+ bytes([opcodes.OP_ENDIF, opcodes.OP_CHECKSIG])
|
||||
|
||||
p2wsh = bitcoin.redeem_script_to_address('p2wsh', bh2u(script))
|
||||
weight = HTLC_SUCCESS_WEIGHT if success else HTLC_TIMEOUT_WEIGHT
|
||||
fee = local_feerate * weight
|
||||
final_amount_sat = (amount_msat - fee) // 1000
|
||||
assert final_amount_sat > 0, final_amount_sat
|
||||
output = (bitcoin.TYPE_ADDRESS, p2wsh, final_amount_sat)
|
||||
return output
|
||||
|
||||
def make_htlc_tx_witness(remotehtlcsig, localhtlcsig, payment_preimage, witness_script):
|
||||
assert type(remotehtlcsig) is bytes
|
||||
assert type(localhtlcsig) is bytes
|
||||
assert type(payment_preimage) is bytes
|
||||
assert type(witness_script) is bytes
|
||||
return bfh(transaction.construct_witness([0, remotehtlcsig, localhtlcsig, payment_preimage, witness_script]))
|
||||
|
||||
def make_htlc_tx_inputs(htlc_output_txid, htlc_output_index, revocationpubkey, local_delayedpubkey, amount_msat, witness_script):
|
||||
assert type(htlc_output_txid) is str
|
||||
assert type(htlc_output_index) is int
|
||||
assert type(revocationpubkey) is bytes
|
||||
assert type(local_delayedpubkey) is bytes
|
||||
assert type(amount_msat) is int
|
||||
assert type(witness_script) is str
|
||||
c_inputs = [{
|
||||
'scriptSig': '',
|
||||
'type': 'p2wsh',
|
||||
'signatures': [],
|
||||
'num_sig': 0,
|
||||
'prevout_n': htlc_output_index,
|
||||
'prevout_hash': htlc_output_txid,
|
||||
'value': amount_msat // 1000,
|
||||
'coinbase': False,
|
||||
'sequence': 0x0,
|
||||
'preimage_script': witness_script,
|
||||
}]
|
||||
return c_inputs
|
||||
|
||||
def make_htlc_tx(cltv_timeout, inputs, output):
|
||||
assert type(cltv_timeout) is int
|
||||
c_outputs = [output]
|
||||
tx = Transaction.from_io(inputs, c_outputs, locktime=cltv_timeout, version=2)
|
||||
tx.BIP_LI01_sort()
|
||||
return tx
|
||||
|
||||
def make_offered_htlc(revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, payment_hash):
|
||||
assert type(revocation_pubkey) is bytes
|
||||
assert type(remote_htlcpubkey) is bytes
|
||||
assert type(local_htlcpubkey) is bytes
|
||||
assert type(payment_hash) is bytes
|
||||
return bytes([opcodes.OP_DUP, opcodes.OP_HASH160]) + bfh(push_script(bh2u(bitcoin.hash_160(revocation_pubkey))))\
|
||||
+ bytes([opcodes.OP_EQUAL, opcodes.OP_IF, opcodes.OP_CHECKSIG, opcodes.OP_ELSE]) \
|
||||
+ bfh(push_script(bh2u(remote_htlcpubkey)))\
|
||||
+ bytes([opcodes.OP_SWAP, opcodes.OP_SIZE]) + bitcoin.add_number_to_script(32) + bytes([opcodes.OP_EQUAL, opcodes.OP_NOTIF, opcodes.OP_DROP])\
|
||||
+ bitcoin.add_number_to_script(2) + bytes([opcodes.OP_SWAP]) + bfh(push_script(bh2u(local_htlcpubkey))) + bitcoin.add_number_to_script(2)\
|
||||
+ bytes([opcodes.OP_CHECKMULTISIG, opcodes.OP_ELSE, opcodes.OP_HASH160])\
|
||||
+ bfh(push_script(bh2u(crypto.ripemd(payment_hash)))) + bytes([opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG, opcodes.OP_ENDIF, opcodes.OP_ENDIF])
|
||||
|
||||
def make_received_htlc(revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, payment_hash, cltv_expiry):
|
||||
for i in [revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, payment_hash]:
|
||||
assert type(i) is bytes
|
||||
assert type(cltv_expiry) is int
|
||||
|
||||
return bytes([opcodes.OP_DUP, opcodes.OP_HASH160]) \
|
||||
+ bfh(push_script(bh2u(bitcoin.hash_160(revocation_pubkey)))) \
|
||||
+ bytes([opcodes.OP_EQUAL, opcodes.OP_IF, opcodes.OP_CHECKSIG, opcodes.OP_ELSE]) \
|
||||
+ bfh(push_script(bh2u(remote_htlcpubkey))) \
|
||||
+ bytes([opcodes.OP_SWAP, opcodes.OP_SIZE]) \
|
||||
+ bitcoin.add_number_to_script(32) \
|
||||
+ bytes([opcodes.OP_EQUAL, opcodes.OP_IF, opcodes.OP_HASH160]) \
|
||||
+ bfh(push_script(bh2u(crypto.ripemd(payment_hash)))) \
|
||||
+ bytes([opcodes.OP_EQUALVERIFY]) \
|
||||
+ bitcoin.add_number_to_script(2) \
|
||||
+ bytes([opcodes.OP_SWAP]) \
|
||||
+ bfh(push_script(bh2u(local_htlcpubkey))) \
|
||||
+ bitcoin.add_number_to_script(2) \
|
||||
+ bytes([opcodes.OP_CHECKMULTISIG, opcodes.OP_ELSE, opcodes.OP_DROP]) \
|
||||
+ bitcoin.add_number_to_script(cltv_expiry) \
|
||||
+ bytes([opcodes.OP_CLTV, opcodes.OP_DROP, opcodes.OP_CHECKSIG, opcodes.OP_ENDIF, opcodes.OP_ENDIF])
|
||||
|
||||
def make_htlc_tx_with_open_channel(chan, pcp, for_us, we_receive, amount_msat, cltv_expiry, payment_hash, commit, original_htlc_output_index):
|
||||
conf = chan.local_config if for_us else chan.remote_config
|
||||
other_conf = chan.local_config if not for_us else chan.remote_config
|
||||
|
||||
revocation_pubkey = derive_blinded_pubkey(other_conf.revocation_basepoint.pubkey, pcp)
|
||||
delayedpubkey = derive_pubkey(conf.delayed_basepoint.pubkey, pcp)
|
||||
other_revocation_pubkey = derive_blinded_pubkey(other_conf.revocation_basepoint.pubkey, pcp)
|
||||
other_htlc_pubkey = derive_pubkey(other_conf.htlc_basepoint.pubkey, pcp)
|
||||
htlc_pubkey = derive_pubkey(conf.htlc_basepoint.pubkey, pcp)
|
||||
# HTLC-success for the HTLC spending from a received HTLC output
|
||||
# if we do not receive, and the commitment tx is not for us, they receive, so it is also an HTLC-success
|
||||
is_htlc_success = for_us == we_receive
|
||||
htlc_tx_output = make_htlc_tx_output(
|
||||
amount_msat = amount_msat,
|
||||
local_feerate = chan.constraints.feerate,
|
||||
revocationpubkey=revocation_pubkey,
|
||||
local_delayedpubkey=delayedpubkey,
|
||||
success = is_htlc_success,
|
||||
to_self_delay = other_conf.to_self_delay)
|
||||
if is_htlc_success:
|
||||
preimage_script = make_received_htlc(other_revocation_pubkey, other_htlc_pubkey, htlc_pubkey, payment_hash, cltv_expiry)
|
||||
else:
|
||||
preimage_script = make_offered_htlc(other_revocation_pubkey, other_htlc_pubkey, htlc_pubkey, payment_hash)
|
||||
htlc_tx_inputs = make_htlc_tx_inputs(
|
||||
commit.txid(), commit.htlc_output_indices[original_htlc_output_index],
|
||||
revocationpubkey=revocation_pubkey,
|
||||
local_delayedpubkey=delayedpubkey,
|
||||
amount_msat=amount_msat,
|
||||
witness_script=bh2u(preimage_script))
|
||||
if is_htlc_success:
|
||||
cltv_expiry = 0
|
||||
htlc_tx = make_htlc_tx(cltv_expiry, inputs=htlc_tx_inputs, output=htlc_tx_output)
|
||||
return htlc_tx
|
||||
|
||||
def make_commitment_using_open_channel(chan, ctn, for_us, pcp, local_msat, remote_msat, htlcs=[], trimmed=0):
|
||||
conf = chan.local_config if for_us else chan.remote_config
|
||||
other_conf = chan.local_config if not for_us else chan.remote_config
|
||||
payment_pubkey = derive_pubkey(other_conf.payment_basepoint.pubkey, pcp)
|
||||
remote_revocation_pubkey = derive_blinded_pubkey(other_conf.revocation_basepoint.pubkey, pcp)
|
||||
return make_commitment(
|
||||
ctn,
|
||||
conf.multisig_key.pubkey,
|
||||
other_conf.multisig_key.pubkey,
|
||||
payment_pubkey,
|
||||
chan.local_config.payment_basepoint.pubkey,
|
||||
chan.remote_config.payment_basepoint.pubkey,
|
||||
remote_revocation_pubkey,
|
||||
derive_pubkey(conf.delayed_basepoint.pubkey, pcp),
|
||||
other_conf.to_self_delay,
|
||||
*chan.funding_outpoint,
|
||||
chan.constraints.capacity,
|
||||
local_msat,
|
||||
remote_msat,
|
||||
chan.local_config.dust_limit_sat,
|
||||
chan.constraints.feerate,
|
||||
for_us,
|
||||
chan.constraints.is_initiator,
|
||||
htlcs=htlcs,
|
||||
trimmed=trimmed)
|
||||
|
||||
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_sat, local_amount, remote_amount,
|
||||
dust_limit_sat, local_feerate, for_us, we_are_initiator,
|
||||
htlcs, trimmed=0):
|
||||
|
||||
pubkeys = sorted([bh2u(local_funding_pubkey), bh2u(remote_funding_pubkey)])
|
||||
payments = [payment_basepoint, remote_payment_basepoint]
|
||||
if not we_are_initiator:
|
||||
payments.reverse()
|
||||
obs = get_obscured_ctn(ctn, *payments)
|
||||
locktime = (0x20 << 24) + (obs & 0xffffff)
|
||||
sequence = (0x80 << 24) + (obs >> 24)
|
||||
print_error('locktime', locktime, hex(locktime))
|
||||
# commitment tx input
|
||||
c_inputs = [{
|
||||
'type': 'p2wsh',
|
||||
'x_pubkeys': pubkeys,
|
||||
'signatures': [None, None],
|
||||
'num_sig': 2,
|
||||
'prevout_n': funding_pos,
|
||||
'prevout_hash': funding_txid,
|
||||
'value': funding_sat,
|
||||
'coinbase': False,
|
||||
'sequence': sequence
|
||||
}]
|
||||
# commitment tx outputs
|
||||
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(remote_payment_pubkey))
|
||||
# TODO trim htlc outputs here while also considering 2nd stage htlc transactions
|
||||
fee = local_feerate * overall_weight(len(htlcs))
|
||||
fee -= trimmed * 1000
|
||||
assert type(fee) is int
|
||||
we_pay_fee = for_us == we_are_initiator
|
||||
to_local_amt = local_amount - (fee if we_pay_fee else 0)
|
||||
assert type(to_local_amt) is int
|
||||
to_local = (bitcoin.TYPE_ADDRESS, local_address, to_local_amt // 1000)
|
||||
to_remote_amt = remote_amount - (fee if not we_pay_fee else 0)
|
||||
assert type(to_remote_amt) is int
|
||||
to_remote = (bitcoin.TYPE_ADDRESS, remote_address, to_remote_amt // 1000)
|
||||
c_outputs = [to_local, to_remote]
|
||||
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_filtered = 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_filtered, locktime=locktime, version=2)
|
||||
tx.BIP_LI01_sort()
|
||||
|
||||
tx.htlc_output_indices = {}
|
||||
for idx, output in enumerate(c_outputs):
|
||||
if output in tx.outputs():
|
||||
# minus the first two outputs (to_local, to_remote)
|
||||
tx.htlc_output_indices[idx - 2] = tx.outputs().index(output)
|
||||
|
||||
return tx
|
||||
|
||||
|
||||
def calc_short_channel_id(block_height: int, tx_pos_in_block: int, output_index: int) -> bytes:
|
||||
bh = block_height.to_bytes(3, byteorder='big')
|
||||
tpos = tx_pos_in_block.to_bytes(3, byteorder='big')
|
||||
oi = output_index.to_bytes(2, byteorder='big')
|
||||
return bh + tpos + oi
|
||||
|
||||
|
||||
def sign_and_get_sig_string(tx, local_config, remote_config):
|
||||
pubkeys = sorted([bh2u(local_config.multisig_key.pubkey), bh2u(remote_config.multisig_key.pubkey)])
|
||||
tx.sign({bh2u(local_config.multisig_key.pubkey): (local_config.multisig_key.privkey, True)})
|
||||
sig_index = pubkeys.index(bh2u(local_config.multisig_key.pubkey))
|
||||
sig = bytes.fromhex(tx.inputs()[0]["signatures"][sig_index])
|
||||
r, s = sigdecode_der(sig[:-1], SECP256k1.generator.order())
|
||||
sig_64 = sigencode_string_canonize(r, s, SECP256k1.generator.order())
|
||||
return sig_64
|
||||
|
||||
def is_synced(network):
|
||||
local_height, server_height = network.get_status_value("updated")
|
||||
synced = server_height != 0 and network.is_up_to_date() and local_height >= server_height
|
||||
return synced
|
||||
|
||||
def funding_output_script(local_config, remote_config):
|
||||
pubkeys = sorted([bh2u(local_config.multisig_key.pubkey), bh2u(remote_config.multisig_key.pubkey)])
|
||||
return transaction.multisig_script(pubkeys, 2)
|
||||
|
||||
class Peer(PrintError):
|
||||
|
||||
def __init__(self, lnworker, host, port, pubkey, request_initial_sync=False):
|
||||
@@ -864,7 +531,7 @@ class Peer(PrintError):
|
||||
msg = gen_msg(
|
||||
"open_channel",
|
||||
temporary_channel_id=temp_channel_id,
|
||||
chain_hash=bytes.fromhex(rev_hex(constants.net.GENESIS)),
|
||||
chain_hash=REV_GENESIS,
|
||||
funding_satoshis=funding_sat,
|
||||
push_msat=push_msat,
|
||||
dust_limit_satoshis=local_config.dust_limit_sat,
|
||||
@@ -1065,7 +732,7 @@ class Peer(PrintError):
|
||||
bitcoin_signature_2=bitcoin_sigs[1],
|
||||
len=0,
|
||||
#features not set (defaults to zeros)
|
||||
chain_hash=bytes.fromhex(rev_hex(constants.net.GENESIS)),
|
||||
chain_hash=REV_GENESIS,
|
||||
short_channel_id=chan.short_channel_id,
|
||||
node_id_1=node_ids[0],
|
||||
node_id_2=node_ids[1],
|
||||
@@ -1107,7 +774,7 @@ class Peer(PrintError):
|
||||
chan_ann = gen_msg("channel_announcement",
|
||||
len=0,
|
||||
#features not set (defaults to zeros)
|
||||
chain_hash=bytes.fromhex(rev_hex(constants.net.GENESIS)),
|
||||
chain_hash=REV_GENESIS,
|
||||
short_channel_id=chan.short_channel_id,
|
||||
node_id_1=node_ids[0],
|
||||
node_id_2=node_ids[1],
|
||||
@@ -1217,7 +884,7 @@ class Peer(PrintError):
|
||||
self.revoke(chan)
|
||||
# TODO process above commitment transactions
|
||||
|
||||
bare_ctx = make_commitment_using_open_channel(chan, chan.remote_state.ctn + 1, False, chan.remote_state.next_per_commitment_point,
|
||||
bare_ctx = chan.make_commitment(chan.remote_state.ctn + 1, False, chan.remote_state.next_per_commitment_point,
|
||||
msat_remote, msat_local)
|
||||
|
||||
sig_64 = sign_and_get_sig_string(bare_ctx, chan.local_config, chan.remote_config)
|
||||
@@ -1249,7 +916,7 @@ class Peer(PrintError):
|
||||
async def receive_commitment_revoke_ack(self, htlc, decoded, payment_preimage):
|
||||
chan = self.channels[htlc['channel_id']]
|
||||
channel_id = chan.channel_id
|
||||
expected_received_msat = int(decoded.amount * COIN * 1000)
|
||||
expected_received_msat = int(decoded.amount * bitcoin.COIN * 1000)
|
||||
htlc_id = int.from_bytes(htlc["id"], 'big')
|
||||
assert htlc_id == chan.remote_state.next_htlc_id, (htlc_id, chan.remote_state.next_htlc_id)
|
||||
|
||||
@@ -1279,7 +946,7 @@ class Peer(PrintError):
|
||||
self.send_message(gen_msg("update_fulfill_htlc", channel_id=channel_id, id=htlc_id, payment_preimage=payment_preimage))
|
||||
|
||||
# remote commitment transaction without htlcs
|
||||
bare_ctx = make_commitment_using_open_channel(m, m.remote_state.ctn + 1, False, m.remote_state.next_per_commitment_point,
|
||||
bare_ctx = chan.make_commitment(m.remote_state.ctn + 1, False, m.remote_state.next_per_commitment_point,
|
||||
m.remote_state.amount_msat - expected_received_msat, m.local_state.amount_msat + expected_received_msat)
|
||||
sig_64 = sign_and_get_sig_string(bare_ctx, m.local_config, m.remote_config)
|
||||
self.send_message(gen_msg("commitment_signed", channel_id=channel_id, signature=sig_64, num_htlcs=0))
|
||||
@@ -1333,13 +1000,4 @@ class Peer(PrintError):
|
||||
self.channels[channel_id].update_fee(int.from_bytes(payload["feerate_per_kw"], "big"))
|
||||
|
||||
|
||||
def count_trailing_zeros(index):
|
||||
""" BOLT-03 (where_to_put_secret) """
|
||||
try:
|
||||
return list(reversed(bin(index)[2:])).index("1")
|
||||
except ValueError:
|
||||
return 48
|
||||
|
||||
ShachainElement = namedtuple("ShachainElement", ["secret", "index"])
|
||||
ShachainElement.__str__ = lambda self: "ShachainElement(" + bh2u(self.secret) + "," + str(self.index) + ")"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user