mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
ln: do not use mSAT accuracy for commitment fees
This commit is contained in:
parent
66e7b4d250
commit
9853cc6f31
3 changed files with 24 additions and 14 deletions
|
@ -2,7 +2,7 @@
|
|||
from collections import namedtuple
|
||||
import binascii
|
||||
import json
|
||||
from .util import bfh, PrintError
|
||||
from .util import bfh, PrintError, bh2u
|
||||
from .bitcoin import Hash
|
||||
from .bitcoin import redeem_script_to_address
|
||||
from .crypto import sha256
|
||||
|
@ -199,14 +199,16 @@ class HTLCStateMachine(PrintError):
|
|||
|
||||
for_us = False
|
||||
|
||||
feerate = self.pending_remote_feerate
|
||||
|
||||
htlcsigs = []
|
||||
for we_receive, htlcs in zip([True, False], [self.htlcs_in_remote, self.htlcs_in_local]):
|
||||
assert len(htlcs) <= 1
|
||||
for htlc in htlcs:
|
||||
weight = HTLC_SUCCESS_WEIGHT if we_receive else HTLC_TIMEOUT_WEIGHT
|
||||
fee = self.remote_state.feerate // 1000 * weight
|
||||
fee = feerate // 1000 * weight
|
||||
if htlc.amount_msat // 1000 < self.remote_config.dust_limit_sat + fee:
|
||||
print("value too small, skipping. htlc amt: {}, weight: {}, remote feerate {}, remote dust limit {}".format( htlc.amount_msat, weight, self.remote_state.feerate, self.remote_config.dust_limit_sat))
|
||||
print("value too small, skipping. htlc amt: {}, weight: {}, remote feerate {}, remote dust limit {}".format( htlc.amount_msat, weight, feerate, self.remote_config.dust_limit_sat))
|
||||
continue
|
||||
original_htlc_output_index = 0
|
||||
args = [self.remote_state.next_per_commitment_point, for_us, we_receive, htlc.amount_msat + htlc.total_fee, htlc.cltv_expiry, htlc.payment_hash, self.pending_remote_commitment, original_htlc_output_index]
|
||||
|
@ -244,7 +246,7 @@ class HTLCStateMachine(PrintError):
|
|||
preimage_hex = self.pending_local_commitment.serialize_preimage(0)
|
||||
pre_hash = Hash(bfh(preimage_hex))
|
||||
if not ecc.verify_signature(self.remote_config.multisig_key.pubkey, sig, pre_hash):
|
||||
raise Exception('failed verifying signature of our updated commitment transaction: ' + str(sig))
|
||||
raise Exception('failed verifying signature of our updated commitment transaction: ' + bh2u(sig) + ' preimage is ' + preimage_hex)
|
||||
|
||||
_, this_point, _ = self.points
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ def make_htlc_tx_output(amount_msat, local_feerate, revocationpubkey, local_dela
|
|||
p2wsh = bitcoin.redeem_script_to_address('p2wsh', bh2u(script))
|
||||
weight = HTLC_SUCCESS_WEIGHT if success else HTLC_TIMEOUT_WEIGHT
|
||||
fee = local_feerate * weight
|
||||
fee = fee // 1000 * 1000
|
||||
final_amount_sat = (amount_msat - fee) // 1000
|
||||
assert final_amount_sat > 0, final_amount_sat
|
||||
output = (bitcoin.TYPE_ADDRESS, p2wsh, final_amount_sat)
|
||||
|
@ -242,7 +243,7 @@ def make_htlc_tx_with_open_channel(chan, pcp, for_us, we_receive, amount_msat, c
|
|||
is_htlc_success = for_us == we_receive
|
||||
htlc_tx_output = make_htlc_tx_output(
|
||||
amount_msat = amount_msat,
|
||||
local_feerate = chan.local_state.feerate if for_us else chan.remote_state.feerate,
|
||||
local_feerate = chan.pending_local_feerate if for_us else chan.pending_remote_feerate,
|
||||
revocationpubkey=revocation_pubkey,
|
||||
local_delayedpubkey=delayedpubkey,
|
||||
success = is_htlc_success,
|
||||
|
@ -295,13 +296,11 @@ def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey,
|
|||
remote_address = make_commitment_output_to_remote_address(remote_payment_pubkey)
|
||||
# TODO trim htlc outputs here while also considering 2nd stage htlc transactions
|
||||
fee = local_feerate * overall_weight(len(htlcs))
|
||||
assert type(fee) is int
|
||||
fee = fee // 1000 * 1000
|
||||
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:
|
||||
|
|
|
@ -74,12 +74,12 @@ def bip32(sequence):
|
|||
assert type(k) is bytes
|
||||
return k
|
||||
|
||||
def create_test_channels():
|
||||
def create_test_channels(feerate=6000, local=None, remote=None):
|
||||
funding_txid = binascii.hexlify(os.urandom(32)).decode("ascii")
|
||||
funding_index = 0
|
||||
funding_sat = bitcoin.COIN * 10
|
||||
local_amount = (funding_sat * 1000) // 2
|
||||
remote_amount = (funding_sat * 1000) // 2
|
||||
funding_sat = ((local + remote) // 1000) if local is not None and remote is not None else (bitcoin.COIN * 10)
|
||||
local_amount = local if local is not None else (funding_sat * 1000 // 2)
|
||||
remote_amount = remote if remote is not None else (funding_sat * 1000 // 2)
|
||||
alice_raw = [ bip32("m/" + str(i)) for i in range(5) ]
|
||||
bob_raw = [ bip32("m/" + str(i)) for i in range(5,11) ]
|
||||
alice_privkeys = [lnbase.Keypair(lnbase.privkey_to_pubkey(x), x) for x in alice_raw]
|
||||
|
@ -97,12 +97,21 @@ def create_test_channels():
|
|||
|
||||
return \
|
||||
lnhtlc.HTLCStateMachine(
|
||||
create_channel_state(funding_txid, funding_index, funding_sat, 6000, True, local_amount, remote_amount, alice_privkeys, bob_pubkeys, alice_seed, bob_cur, bob_next, b"\x02"*33, l_dust=200, r_dust=1300, l_csv=5, r_csv=4), "alice"), \
|
||||
create_channel_state(funding_txid, funding_index, funding_sat, feerate, True, local_amount, remote_amount, alice_privkeys, bob_pubkeys, alice_seed, bob_cur, bob_next, b"\x02"*33, l_dust=200, r_dust=1300, l_csv=5, r_csv=4), "alice"), \
|
||||
lnhtlc.HTLCStateMachine(
|
||||
create_channel_state(funding_txid, funding_index, funding_sat, 6000, False, remote_amount, local_amount, bob_privkeys, alice_pubkeys, bob_seed, alice_cur, alice_next, b"\x01"*33, l_dust=1300, r_dust=200, l_csv=4, r_csv=5), "bob")
|
||||
create_channel_state(funding_txid, funding_index, funding_sat, feerate, False, remote_amount, local_amount, bob_privkeys, alice_pubkeys, bob_seed, alice_cur, alice_next, b"\x01"*33, l_dust=1300, r_dust=200, l_csv=4, r_csv=5), "bob")
|
||||
|
||||
one_bitcoin_in_msat = bitcoin.COIN * 1000
|
||||
|
||||
class TestFee(unittest.TestCase):
|
||||
"""
|
||||
test
|
||||
https://github.com/lightningnetwork/lightning-rfc/blob/e0c436bd7a3ed6a028e1cb472908224658a14eca/03-transactions.md#requirements-2
|
||||
"""
|
||||
def test_SimpleAddSettleWorkflow(self):
|
||||
alice_channel, bob_channel = create_test_channels(253, 10000000000, 5000000000)
|
||||
self.assertIn(9999817, [x[2] for x in alice_channel.local_commitment.outputs()])
|
||||
|
||||
class TestLNBaseHTLCStateMachine(unittest.TestCase):
|
||||
def assertOutputExistsByValue(self, tx, amt_sat):
|
||||
for typ, scr, val in tx.outputs():
|
||||
|
|
Loading…
Add table
Reference in a new issue