Skip to content

Commit cc517d6

Browse files
committed
(XXX: more commit message) Include routed msat balances in Balance::ClaimableOnChannelClose
If we're gonna push users towards using `Balance` to determine their current balances, we really need to provide more information, including msat balances. Here we add rounded-out msat balances to the pre-close balance information
1 parent f6a7fe0 commit cc517d6

File tree

2 files changed

+109
-16
lines changed

2 files changed

+109
-16
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,32 @@ pub enum Balance {
585585
/// transaction fee) this value will be zero. For [`ChannelMonitor`]s created prior to LDK
586586
/// 0.0.117, the channel is always treated as outbound (and thus this value is never zero).
587587
transaction_fee_satoshis: u64,
588+
/// The amount of millisatoshis which has been burned to fees from HTLCs which are outbound
589+
/// from us and are related to a payment which was sent by us. This is the sum of the
590+
/// millisatoshis part of all HTLCs which are otherwise represented by
591+
/// [`Balance::MaybeTimeoutClaimableHTLC`] with their
592+
/// [`Balance::MaybeTimeoutClaimableHTLC::outbound_payment`] flag set, as well as any dust
593+
/// HTLCs which would otherwise be represented the same.
594+
outbound_payment_htlc_rounded_msat: u64,
595+
/// The amount of millisatoshis which has been burned to fees from HTLCs which are outbound
596+
/// from us and are related to a forwarded HTLC. This is the sum of the millisatoshis part
597+
/// of all HTLCs which are otherwise represented by [`Balance::MaybeTimeoutClaimableHTLC`]
598+
/// with their [`Balance::MaybeTimeoutClaimableHTLC::outbound_payment`] flag *not* set, as
599+
/// well as any dust HTLCs which would otherwise be represented the same.
600+
outbound_forwarded_htlc_rounded_msat: u64,
601+
/// The amount of millisatoshis which has been burned to fees from HTLCs which are inbound
602+
/// to us and for which we know the preimage. This is the sum of the millisatoshis part of
603+
/// all HTLCs which would be represented by [`Balance::ContentiousClaimable`] on channel
604+
/// close, but who's current value is included in
605+
/// [`Balance::ClaimableOnChannelClose::amount_satoshis`], as well as any dust HTLCs which
606+
/// would otherwise be represented the same.
607+
inbound_claiming_htlc_rounded_msat: u64,
608+
/// The amount of millisatoshis which has been burned to fees from HTLCs which are inbound
609+
/// to us and for which we do not know the preimage. This is the sum of the millisatoshis
610+
/// part of all HTLCs which would be represented by [`Balance::MaybePreimageClaimableHTLC`]
611+
/// on channel close, as well as any dust HTLCs which would otherwise be represented the
612+
/// same.
613+
inbound_htlc_rounded_msat: u64,
588614
},
589615
/// The channel has been closed, and the given balance is ours but awaiting confirmations until
590616
/// we consider it spendable.
@@ -2017,10 +2043,17 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
20172043
} else {
20182044
let mut claimable_inbound_htlc_value_sat = 0;
20192045
let mut nondust_htlc_count = 0;
2046+
let mut outbound_payment_htlc_rounded_msat = 0;
2047+
let mut outbound_forwarded_htlc_rounded_msat = 0;
2048+
let mut inbound_claiming_htlc_rounded_msat = 0;
2049+
let mut inbound_htlc_rounded_msat = 0;
20202050
for (htlc, _, source) in us.current_holder_commitment_tx.htlc_outputs.iter() {
20212051
if htlc.transaction_output_index.is_some() {
20222052
nondust_htlc_count += 1;
2023-
} else { continue; }
2053+
}
2054+
let rounded_value_msat = if htlc.transaction_output_index.is_none() {
2055+
htlc.amount_msat
2056+
} else { htlc.amount_msat % 1000 };
20242057
if htlc.offered {
20252058
let outbound_payment = match source {
20262059
None => {
@@ -2030,22 +2063,36 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
20302063
Some(HTLCSource::PreviousHopData(_)) => false,
20312064
Some(HTLCSource::OutboundRoute { .. }) => true,
20322065
};
2033-
res.push(Balance::MaybeTimeoutClaimableHTLC {
2034-
amount_satoshis: htlc.amount_msat / 1000,
2035-
claimable_height: htlc.cltv_expiry,
2036-
payment_hash: htlc.payment_hash,
2037-
outbound_payment,
2038-
});
2066+
if outbound_payment {
2067+
outbound_payment_htlc_rounded_msat += rounded_value_msat;
2068+
} else {
2069+
outbound_forwarded_htlc_rounded_msat += rounded_value_msat;
2070+
}
2071+
if htlc.transaction_output_index.is_some() {
2072+
res.push(Balance::MaybeTimeoutClaimableHTLC {
2073+
amount_satoshis: htlc.amount_msat / 1000,
2074+
claimable_height: htlc.cltv_expiry,
2075+
payment_hash: htlc.payment_hash,
2076+
outbound_payment,
2077+
});
2078+
}
20392079
} else if us.payment_preimages.get(&htlc.payment_hash).is_some() {
2040-
claimable_inbound_htlc_value_sat += htlc.amount_msat / 1000;
2080+
inbound_claiming_htlc_rounded_msat += rounded_value_msat;
2081+
if htlc.transaction_output_index.is_some() {
2082+
claimable_inbound_htlc_value_sat += htlc.amount_msat / 1000;
2083+
claimable_inbound_htlc_value_msat += htlc.amount_msat;
2084+
}
20412085
} else {
2042-
// As long as the HTLC is still in our latest commitment state, treat
2043-
// it as potentially claimable, even if it has long-since expired.
2044-
res.push(Balance::MaybePreimageClaimableHTLC {
2045-
amount_satoshis: htlc.amount_msat / 1000,
2046-
expiry_height: htlc.cltv_expiry,
2047-
payment_hash: htlc.payment_hash,
2048-
});
2086+
inbound_htlc_rounded_msat += rounded_value_msat;
2087+
if htlc.transaction_output_index.is_some() {
2088+
// As long as the HTLC is still in our latest commitment state, treat
2089+
// it as potentially claimable, even if it has long-since expired.
2090+
res.push(Balance::MaybePreimageClaimableHTLC {
2091+
amount_satoshis: htlc.amount_msat / 1000,
2092+
expiry_height: htlc.cltv_expiry,
2093+
payment_hash: htlc.payment_hash,
2094+
});
2095+
}
20492096
}
20502097
}
20512098
res.push(Balance::ClaimableOnChannelClose {
@@ -2055,6 +2102,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
20552102
us.current_holder_commitment_tx.feerate_per_kw, nondust_htlc_count,
20562103
us.onchain_tx_handler.channel_type_features())
20572104
} else { 0 },
2105+
outbound_payment_htlc_rounded_msat,
2106+
outbound_forwarded_htlc_rounded_msat,
2107+
inbound_claiming_htlc_rounded_msat,
2108+
inbound_htlc_rounded_msat,
20582109
});
20592110
}
20602111

lightning/src/ln/monitor_tests.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,19 @@ fn chanmon_claim_value_coop_close() {
175175
assert_eq!(vec![Balance::ClaimableOnChannelClose {
176176
amount_satoshis: 1_000_000 - 1_000 - commitment_fee,
177177
transaction_fee_satoshis: commitment_fee,
178+
outbound_payment_htlc_rounded_msat: 0,
179+
outbound_forwarded_htlc_rounded_msat: 0,
180+
inbound_claiming_htlc_rounded_msat: 0,
181+
inbound_htlc_rounded_msat: 0,
178182
}],
179183
nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances());
180-
assert_eq!(vec![Balance::ClaimableOnChannelClose { amount_satoshis: 1_000, transaction_fee_satoshis: 0 }],
184+
assert_eq!(vec![Balance::ClaimableOnChannelClose {
185+
amount_satoshis: 1_000, transaction_fee_satoshis: 0,
186+
outbound_payment_htlc_rounded_msat: 0,
187+
outbound_forwarded_htlc_rounded_msat: 0,
188+
inbound_claiming_htlc_rounded_msat: 0,
189+
inbound_htlc_rounded_msat: 0,
190+
}],
181191
nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances());
182192

183193
nodes[0].node.close_channel(&chan_id, &nodes[1].node.get_our_node_id()).unwrap();
@@ -327,11 +337,19 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) {
327337
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
328338
amount_satoshis: 1_000_000 - 3_000 - 4_000 - 1_000 - 3 - commitment_tx_fee,
329339
transaction_fee_satoshis: commitment_tx_fee,
340+
outbound_payment_htlc_rounded_msat: 3000,
341+
outbound_forwarded_htlc_rounded_msat: 0,
342+
inbound_claiming_htlc_rounded_msat: 0,
343+
inbound_htlc_rounded_msat: 0,
330344
}, sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]),
331345
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
332346
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
333347
amount_satoshis: 1_000,
334348
transaction_fee_satoshis: 0,
349+
outbound_payment_htlc_rounded_msat: 0,
350+
outbound_forwarded_htlc_rounded_msat: 0,
351+
inbound_claiming_htlc_rounded_msat: 0,
352+
inbound_htlc_rounded_msat: 3000,
335353
}, received_htlc_balance.clone(), received_htlc_timeout_balance.clone()]),
336354
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
337355

@@ -378,6 +396,10 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) {
378396
3 - // The dust HTLC value in satoshis
379397
commitment_tx_fee,
380398
transaction_fee_satoshis: commitment_tx_fee,
399+
outbound_payment_htlc_rounded_msat: 3000,
400+
outbound_forwarded_htlc_rounded_msat: 0,
401+
inbound_claiming_htlc_rounded_msat: 0,
402+
inbound_htlc_rounded_msat: 0,
381403
}, sent_htlc_timeout_balance.clone()];
382404
if !prev_commitment_tx {
383405
a_expected_balances.push(sent_htlc_balance.clone());
@@ -387,6 +409,10 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) {
387409
assert_eq!(vec![Balance::ClaimableOnChannelClose {
388410
amount_satoshis: 1_000 + 3_000 + 4_000,
389411
transaction_fee_satoshis: 0,
412+
outbound_payment_htlc_rounded_msat: 0,
413+
outbound_forwarded_htlc_rounded_msat: 0,
414+
inbound_claiming_htlc_rounded_msat: 3000,
415+
inbound_htlc_rounded_msat: 0,
390416
}],
391417
nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances());
392418

@@ -796,12 +822,20 @@ fn test_no_preimage_inbound_htlc_balances() {
796822
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
797823
amount_satoshis: 1_000_000 - 500_000 - 10_000 - commitment_tx_fee,
798824
transaction_fee_satoshis: commitment_tx_fee,
825+
outbound_payment_htlc_rounded_msat: 0,
826+
outbound_forwarded_htlc_rounded_msat: 0,
827+
inbound_claiming_htlc_rounded_msat: 0,
828+
inbound_htlc_rounded_msat: 0,
799829
}, a_received_htlc_balance.clone(), a_sent_htlc_balance.clone()]),
800830
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
801831

802832
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
803833
amount_satoshis: 500_000 - 20_000,
804834
transaction_fee_satoshis: 0,
835+
outbound_payment_htlc_rounded_msat: 0,
836+
outbound_forwarded_htlc_rounded_msat: 0,
837+
inbound_claiming_htlc_rounded_msat: 0,
838+
inbound_htlc_rounded_msat: 0,
805839
}, b_received_htlc_balance.clone(), b_sent_htlc_balance.clone()]),
806840
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
807841

@@ -1076,6 +1110,10 @@ fn do_test_revoked_counterparty_commitment_balances(confirm_htlc_spend_first: bo
10761110
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
10771111
amount_satoshis: 100_000 - 5_000 - 4_000 - 3 - 2_000 + 3_000,
10781112
transaction_fee_satoshis: 0,
1113+
outbound_payment_htlc_rounded_msat: 3000,
1114+
outbound_forwarded_htlc_rounded_msat: 0,
1115+
inbound_claiming_htlc_rounded_msat: 0,
1116+
inbound_htlc_rounded_msat: 0,
10791117
}, Balance::MaybeTimeoutClaimableHTLC {
10801118
amount_satoshis: 2_000,
10811119
claimable_height: missing_htlc_cltv_timeout,
@@ -1517,6 +1555,10 @@ fn test_revoked_counterparty_aggregated_claims() {
15171555
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
15181556
amount_satoshis: 100_000 - 4_000 - 3_000,
15191557
transaction_fee_satoshis: 0,
1558+
outbound_payment_htlc_rounded_msat: 0,
1559+
outbound_forwarded_htlc_rounded_msat: 0,
1560+
inbound_claiming_htlc_rounded_msat: 0,
1561+
inbound_htlc_rounded_msat: 0,
15201562
}, Balance::MaybeTimeoutClaimableHTLC {
15211563
amount_satoshis: 4_000,
15221564
claimable_height: htlc_cltv_timeout,

0 commit comments

Comments
 (0)