Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion electrum/lnchannel.py
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,7 @@ def extract_preimage_from_htlc_txin(self, txin: TxInput, *, is_deeply_mined: boo
error_bytes=None,
failure_message=failure)

def balance(self, whose: HTLCOwner, *, ctx_owner=HTLCOwner.LOCAL, ctn: int = None) -> int:
def balance(self, whose: HTLCOwner, *, ctx_owner: HTLCOwner = None, ctn: int = None) -> int:
assert type(whose) is HTLCOwner
initial = self.config[whose].initial_msat
return self.hm.get_balance_msat(whose=whose,
Expand Down
30 changes: 23 additions & 7 deletions electrum/lnhtlc.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,35 +507,51 @@ def all_htlcs_ever(self) -> Sequence[Tuple[Direction, UpdateAddHtlc]]:
return sent + received

@with_lock
def get_balance_msat(self, whose: HTLCOwner, *, ctx_owner=HTLCOwner.LOCAL, ctn: int = None,
def get_balance_msat(self, whose: HTLCOwner, *, ctx_owner: HTLCOwner = None, ctn: int = None,
initial_balance_msat: int) -> int:
"""Returns the balance of 'whose' in 'ctx' at 'ctn'.
Only HTLCs that have been settled by that ctn are counted.
"""
if ctn is None:
ctn = self.ctn_oldest_unrevoked(ctx_owner)
if ctx_owner is None:
# if ctx_owner is None, we want result to be consistent with get_lightning_history
# thus, we consider that htlcs are settled as soon as their preimage is released,
# because get_lightning_history calls self.was_htlc_preimage_released
ctx_owner = whose
ctx_owner_sent = whose
ctx_owner_recv = -whose
else:
ctx_owner_sent = ctx_owner
ctx_owner_recv = ctx_owner
if ctn is None:
ctn = self.ctn_oldest_unrevoked(ctx_owner)

balance = initial_balance_msat
if ctn >= self.ctn_oldest_unrevoked(ctx_owner):
if ctn is None or ctn >= self.ctn_oldest_unrevoked(ctx_owner):
balance += self._balance_delta * whose
considered_sent_htlc_ids = self._maybe_active_htlc_ids[whose]
considered_recv_htlc_ids = self._maybe_active_htlc_ids[-whose]
else: # ctn is too old; need to consider full log (slow...)
elif ctn == 0:
considered_sent_htlc_ids = []
considered_recv_htlc_ids = []
else:
# ctn is too old; need to consider full log (slow...)
# used in sync_with_remote_watchtower
considered_sent_htlc_ids = self.log[whose]['settles']
considered_recv_htlc_ids = self.log[-whose]['settles']
# sent htlcs
for htlc_id in considered_sent_htlc_ids:
ctns = self.log[whose]['settles'].get(htlc_id, None)
if ctns is None:
continue
if ctns[ctx_owner] is not None and ctns[ctx_owner] <= ctn:
if ctns[ctx_owner_sent] is not None and (ctn is None or ctns[ctx_owner_sent] <= ctn):
htlc = self.log[whose]['adds'][htlc_id]
balance -= htlc.amount_msat
# recv htlcs
for htlc_id in considered_recv_htlc_ids:
ctns = self.log[-whose]['settles'].get(htlc_id, None)
if ctns is None:
continue
if ctns[ctx_owner] is not None and ctns[ctx_owner] <= ctn:
if ctns[ctx_owner_recv] is not None and (ctn is None or ctns[ctx_owner_recv] <= ctn):
htlc = self.log[-whose]['adds'][htlc_id]
balance += htlc.amount_msat
return balance
Expand Down
1 change: 0 additions & 1 deletion electrum/lnworker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,6 @@ def get_lightning_history(self) -> Dict[str, LightningHistoryItem]:
lb = sum(chan.balance(LOCAL) if not chan.is_closed_or_closing() else 0
for chan in self.channels.values())
if balance_msat != lb:
# this typically happens when a channel is recently force closed
self.logger.info(f'get_lightning_history: balance mismatch {balance_msat - lb}')
return out

Expand Down
2 changes: 1 addition & 1 deletion tests/test_lnchannel.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ async def test_SimpleAddSettleWorkflow(self):
tx4 = str(alice_channel.force_close_tx())
self.assertNotEqual(tx3, tx4)

self.assertEqual(alice_channel.balance(LOCAL), 500000000000)
self.assertEqual(alice_channel.balance(LOCAL, ctx_owner=LOCAL), 500000000000)
self.assertEqual(1, alice_channel.get_oldest_unrevoked_ctn(LOCAL))
self.assertEqual(len(alice_channel.included_htlcs(LOCAL, RECEIVED, ctn=2)), 0)
aliceRevocation2 = alice_channel.revoke_current_commitment()
Expand Down