Browse Source

ln: fix forwarded payment fees by removing separation between fee and amount in htlc objects

dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
Janus 7 years ago
committed by ThomasV
parent
commit
96a16adf30
  1. 8
      electrum/lnbase.py
  2. 48
      electrum/lnhtlc.py

8
electrum/lnbase.py

@ -868,10 +868,10 @@ class Peer(PrintError):
self.secret_key = os.urandom(32) self.secret_key = os.urandom(32)
hops_data += [OnionHopsDataSingle(OnionPerHop(b"\x00"*8, amount_msat.to_bytes(8, "big"), (final_cltv_expiry_without_deltas).to_bytes(4, "big")))] hops_data += [OnionHopsDataSingle(OnionPerHop(b"\x00"*8, amount_msat.to_bytes(8, "big"), (final_cltv_expiry_without_deltas).to_bytes(4, "big")))]
onion = new_onion_packet([x.node_id for x in route], self.secret_key, hops_data, associated_data) onion = new_onion_packet([x.node_id for x in route], self.secret_key, hops_data, associated_data)
msat_local = chan.local_state.amount_msat - (amount_msat + total_fee)
msat_remote = chan.remote_state.amount_msat + (amount_msat + total_fee)
htlc = UpdateAddHtlc(amount_msat, payment_hash, final_cltv_expiry_with_deltas, total_fee)
amount_msat += total_fee amount_msat += total_fee
msat_local = chan.local_state.amount_msat - amount_msat
msat_remote = chan.remote_state.amount_msat + amount_msat
htlc = UpdateAddHtlc(amount_msat, payment_hash, final_cltv_expiry_with_deltas)
self.send_message(gen_msg("update_add_htlc", channel_id=chan.channel_id, id=chan.local_state.next_htlc_id, cltv_expiry=final_cltv_expiry_with_deltas, amount_msat=amount_msat, payment_hash=payment_hash, onion_routing_packet=onion.to_bytes())) self.send_message(gen_msg("update_add_htlc", channel_id=chan.channel_id, id=chan.local_state.next_htlc_id, cltv_expiry=final_cltv_expiry_with_deltas, amount_msat=amount_msat, payment_hash=payment_hash, onion_routing_packet=onion.to_bytes()))
@ -964,7 +964,7 @@ class Peer(PrintError):
assert amount_msat == expected_received_msat assert amount_msat == expected_received_msat
payment_hash = htlc["payment_hash"] payment_hash = htlc["payment_hash"]
htlc = UpdateAddHtlc(amount_msat, payment_hash, cltv_expiry, 0) htlc = UpdateAddHtlc(amount_msat, payment_hash, cltv_expiry)
chan.receive_htlc(htlc) chan.receive_htlc(htlc)

48
electrum/lnhtlc.py

@ -28,11 +28,10 @@ class FeeUpdate:
self.progress = 0 self.progress = 0
class UpdateAddHtlc: class UpdateAddHtlc:
def __init__(self, amount_msat, payment_hash, cltv_expiry, total_fee): def __init__(self, amount_msat, payment_hash, cltv_expiry):
self.amount_msat = amount_msat self.amount_msat = amount_msat
self.payment_hash = payment_hash self.payment_hash = payment_hash
self.cltv_expiry = cltv_expiry self.cltv_expiry = cltv_expiry
self.total_fee = total_fee
# the height the htlc was locked in at, or None # the height the htlc was locked in at, or None
self.r_locked_in = None self.r_locked_in = None
@ -41,7 +40,7 @@ class UpdateAddHtlc:
self.htlc_id = None self.htlc_id = None
def as_tuple(self): def as_tuple(self):
return (self.htlc_id, self.amount_msat, self.payment_hash, self.cltv_expiry, self.r_locked_in, self.l_locked_in, self.total_fee) return (self.htlc_id, self.amount_msat, self.payment_hash, self.cltv_expiry, self.r_locked_in, self.l_locked_in)
def __hash__(self): def __hash__(self):
return hash(self.as_tuple()) return hash(self.as_tuple())
@ -211,7 +210,7 @@ class HTLCStateMachine(PrintError):
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)) 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 continue
original_htlc_output_index = 0 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] args = [self.remote_state.next_per_commitment_point, for_us, we_receive, htlc.amount_msat, htlc.cltv_expiry, htlc.payment_hash, self.pending_remote_commitment, original_htlc_output_index]
htlc_tx = make_htlc_tx_with_open_channel(self, *args) htlc_tx = make_htlc_tx_with_open_channel(self, *args)
sig = bfh(htlc_tx.sign_txin(0, their_remote_htlc_privkey)) sig = bfh(htlc_tx.sign_txin(0, their_remote_htlc_privkey))
htlc_sig = ecc.sig_string_from_der_sig(sig[:-1]) htlc_sig = ecc.sig_string_from_der_sig(sig[:-1])
@ -343,12 +342,11 @@ class HTLCStateMachine(PrintError):
continue continue
settle_fails2.append(x) settle_fails2.append(x)
sent_this_batch, sent_fees = 0, 0 sent_this_batch = 0
for x in settle_fails2: for x in settle_fails2:
htlc = self.lookup_htlc(self.local_update_log, x.htlc_id) htlc = self.lookup_htlc(self.local_update_log, x.htlc_id)
sent_this_batch += htlc.amount_msat sent_this_batch += htlc.amount_msat
sent_fees += htlc.total_fee
self.total_msat_sent += sent_this_batch self.total_msat_sent += sent_this_batch
@ -374,8 +372,6 @@ class HTLCStateMachine(PrintError):
self.total_msat_received += received_this_batch self.total_msat_received += received_this_batch
received_fees = sum(x.total_fee for x in to_remove)
self.remote_state.revocation_store.add_next_entry(revocation.per_commitment_secret) self.remote_state.revocation_store.add_next_entry(revocation.per_commitment_secret)
next_point = self.remote_state.next_per_commitment_point next_point = self.remote_state.next_per_commitment_point
@ -386,10 +382,10 @@ class HTLCStateMachine(PrintError):
ctn=self.remote_state.ctn + 1, ctn=self.remote_state.ctn + 1,
current_per_commitment_point=next_point, current_per_commitment_point=next_point,
next_per_commitment_point=revocation.next_per_commitment_point, next_per_commitment_point=revocation.next_per_commitment_point,
amount_msat=self.remote_state.amount_msat + (sent_this_batch - received_this_batch) + sent_fees - received_fees amount_msat=self.remote_state.amount_msat + (sent_this_batch - received_this_batch)
) )
self.local_state=self.local_state._replace( self.local_state=self.local_state._replace(
amount_msat = self.local_state.amount_msat + (received_this_batch - sent_this_batch) - sent_fees + received_fees amount_msat = self.local_state.amount_msat + (received_this_batch - sent_this_batch)
) )
if self.pending_fee: if self.pending_fee:
@ -402,28 +398,24 @@ class HTLCStateMachine(PrintError):
@staticmethod @staticmethod
def htlcsum(htlcs): def htlcsum(htlcs):
amount_unsettled = 0 amount_unsettled = 0
fee = 0
for x in htlcs: for x in htlcs:
amount_unsettled += x.amount_msat amount_unsettled += x.amount_msat
fee += x.total_fee return amount_unsettled
return amount_unsettled, fee
def amounts(self): def amounts(self):
remote_settled_value, remote_settled_fee = self.htlcsum(self.gen_htlc_indices("remote", False)) remote_settled_value = self.htlcsum(self.gen_htlc_indices("remote", False))
local_settled_value, local_settled_fee = self.htlcsum(self.gen_htlc_indices("local", False)) local_settled_value = self.htlcsum(self.gen_htlc_indices("local", False))
htlc_value_local, total_fee_local = self.htlcsum(self.htlcs_in_local) htlc_value_local = self.htlcsum(self.htlcs_in_local)
htlc_value_remote, total_fee_remote = self.htlcsum(self.htlcs_in_remote) htlc_value_remote = self.htlcsum(self.htlcs_in_remote)
total_fee_local += local_settled_fee
total_fee_remote += remote_settled_fee
local_msat = self.local_state.amount_msat -\ local_msat = self.local_state.amount_msat -\
htlc_value_local + remote_settled_value - local_settled_value htlc_value_local + remote_settled_value - local_settled_value
remote_msat = self.remote_state.amount_msat -\ remote_msat = self.remote_state.amount_msat -\
htlc_value_remote + local_settled_value - remote_settled_value htlc_value_remote + local_settled_value - remote_settled_value
return remote_msat, total_fee_remote, local_msat, total_fee_local return remote_msat, local_msat
@property @property
def pending_remote_commitment(self): def pending_remote_commitment(self):
remote_msat, total_fee_remote, local_msat, total_fee_local = self.amounts() remote_msat, local_msat = self.amounts()
assert local_msat >= 0 assert local_msat >= 0
assert remote_msat >= 0 assert remote_msat >= 0
@ -440,23 +432,23 @@ class HTLCStateMachine(PrintError):
if htlc.amount_msat // 1000 - HTLC_SUCCESS_WEIGHT * (feerate // 1000) < self.remote_config.dust_limit_sat: if htlc.amount_msat // 1000 - HTLC_SUCCESS_WEIGHT * (feerate // 1000) < self.remote_config.dust_limit_sat:
continue continue
htlcs_in_local.append( htlcs_in_local.append(
( make_received_htlc(local_revocation_pubkey, local_htlc_pubkey, remote_htlc_pubkey, htlc.payment_hash, htlc.cltv_expiry), htlc.amount_msat + htlc.total_fee)) ( make_received_htlc(local_revocation_pubkey, local_htlc_pubkey, remote_htlc_pubkey, htlc.payment_hash, htlc.cltv_expiry), htlc.amount_msat))
htlcs_in_remote = [] htlcs_in_remote = []
for htlc in self.htlcs_in_remote: for htlc in self.htlcs_in_remote:
if htlc.amount_msat // 1000 - HTLC_TIMEOUT_WEIGHT * (feerate // 1000) < self.remote_config.dust_limit_sat: if htlc.amount_msat // 1000 - HTLC_TIMEOUT_WEIGHT * (feerate // 1000) < self.remote_config.dust_limit_sat:
continue continue
htlcs_in_remote.append( htlcs_in_remote.append(
( make_offered_htlc(local_revocation_pubkey, local_htlc_pubkey, remote_htlc_pubkey, htlc.payment_hash), htlc.amount_msat + htlc.total_fee)) ( make_offered_htlc(local_revocation_pubkey, local_htlc_pubkey, remote_htlc_pubkey, htlc.payment_hash), htlc.amount_msat))
commit = self.make_commitment(self.remote_state.ctn + 1, commit = self.make_commitment(self.remote_state.ctn + 1,
False, this_point, False, this_point,
remote_msat - total_fee_remote, local_msat - total_fee_local, htlcs_in_local + htlcs_in_remote) remote_msat, local_msat, htlcs_in_local + htlcs_in_remote)
return commit return commit
@property @property
def pending_local_commitment(self): def pending_local_commitment(self):
remote_msat, total_fee_remote, local_msat, total_fee_local = self.amounts() remote_msat, local_msat = self.amounts()
assert local_msat >= 0 assert local_msat >= 0
assert remote_msat >= 0 assert remote_msat >= 0
@ -473,18 +465,18 @@ class HTLCStateMachine(PrintError):
if htlc.amount_msat // 1000 - HTLC_TIMEOUT_WEIGHT * (feerate // 1000) < self.local_config.dust_limit_sat: if htlc.amount_msat // 1000 - HTLC_TIMEOUT_WEIGHT * (feerate // 1000) < self.local_config.dust_limit_sat:
continue continue
htlcs_in_local.append( htlcs_in_local.append(
( make_offered_htlc(remote_revocation_pubkey, remote_htlc_pubkey, local_htlc_pubkey, htlc.payment_hash), htlc.amount_msat + htlc.total_fee)) ( make_offered_htlc(remote_revocation_pubkey, remote_htlc_pubkey, local_htlc_pubkey, htlc.payment_hash), htlc.amount_msat))
htlcs_in_remote = [] htlcs_in_remote = []
for htlc in self.htlcs_in_remote: for htlc in self.htlcs_in_remote:
if htlc.amount_msat // 1000 - HTLC_SUCCESS_WEIGHT * (feerate // 1000) < self.local_config.dust_limit_sat: if htlc.amount_msat // 1000 - HTLC_SUCCESS_WEIGHT * (feerate // 1000) < self.local_config.dust_limit_sat:
continue continue
htlcs_in_remote.append( htlcs_in_remote.append(
( make_received_htlc(remote_revocation_pubkey, remote_htlc_pubkey, local_htlc_pubkey, htlc.payment_hash, htlc.cltv_expiry), htlc.amount_msat + htlc.total_fee)) ( make_received_htlc(remote_revocation_pubkey, remote_htlc_pubkey, local_htlc_pubkey, htlc.payment_hash, htlc.cltv_expiry), htlc.amount_msat))
commit = self.make_commitment(self.local_state.ctn + 1, commit = self.make_commitment(self.local_state.ctn + 1,
True, this_point, True, this_point,
local_msat - total_fee_local, remote_msat - total_fee_remote, htlcs_in_local + htlcs_in_remote) local_msat, remote_msat, htlcs_in_local + htlcs_in_remote)
return commit return commit
def gen_htlc_indices(self, subject, just_unsettled=True): def gen_htlc_indices(self, subject, just_unsettled=True):

Loading…
Cancel
Save