Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit eeb9f36

Browse files
committedAug 4, 2021
Expose the amount of funds available for claim in ChannelMonitor
In general, we should always allow users to query for how much is currently in-flight being claimed on-chain at any time. This does so by examining the confirmed claims on-chain and breaking down what is left to be claimed into a new `ClaimableBalance` enum. Fixes #995.
1 parent 1a2826d commit eeb9f36

File tree

2 files changed

+448
-2
lines changed

2 files changed

+448
-2
lines changed
 

‎lightning/src/chain/channelmonitor.rs

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,56 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
504504
},
505505
);
506506

507+
/// Details about the balance available for claim once the channel appears on chain.
508+
#[derive(Clone, Debug, PartialEq, Eq)]
509+
#[cfg_attr(test, derive(PartialOrd, Ord))]
510+
pub enum ClaimableBalance {
511+
/// The channel is not yet closed (or the initial commitment or closing transaction has not yet
512+
/// been confirmed). The given balance is claimable (less on-chain fees) if the channel is
513+
/// force-closed now.
514+
ClaimableOnChannelClose {
515+
/// The amount available to claim, in satoshis, ignoring the on-chain fees which will be
516+
/// required to do so.
517+
claimable_amount_satoshis: u64,
518+
},
519+
/// The channel has been closed, and the given balance is ours but awaiting confirmations until
520+
/// we consider it spendable.
521+
ClaimableAwaitingConfirmations {
522+
/// The amount available to claim, in satoshis, possibly ignoring the on-chain fees which
523+
/// were spent in broadcasting the transaction.
524+
claimable_amount_satoshis: u64,
525+
/// The height at which an [`Event::SpendableOutputs`] event will be generated for this
526+
/// amount.
527+
confirmation_height: u32,
528+
},
529+
/// The channel has been closed, and the given balance should be ours but awaiting spending
530+
/// transaction confirmation. If the spending transaction does not confirm in time, it is
531+
/// possible our counterparty can take the funds by broadcasting an HTLC timeout on-chain.
532+
///
533+
/// Once the spending transaction confirms, before it has reached enough confirmations to be
534+
/// considered safe from chain reorganizations, the balance will instead be provided via
535+
/// [`ClaimableBalance::ClaimableAwaitingConfirmations`].
536+
ContentiousClaimable {
537+
/// The amount available to claim, in satoshis, ignoring the on-chain fees which will be
538+
/// required to do so.
539+
claimable_amount_satoshis: u64,
540+
/// The height at which the counterparty may be able to claim the balance if we have not
541+
/// done so.
542+
timeout_height: u32,
543+
},
544+
/// HTLCs which we sent to our counterparty which are claimable after a timeout (less on-chain
545+
/// fees) if the counterparty does not know the preimage for the HTLCs. These are somewhat
546+
/// likely to be claimed by our counterparty before we do.
547+
PossiblyClaimableHTLCAwaitingTimeout {
548+
/// The amount available to claim, in satoshis, ignoring the on-chain fees which will be
549+
/// required to do so.
550+
claimable_amount_satoshis: u64,
551+
/// The height at which we will be able to claim the balance if our counterparty has not
552+
/// done so.
553+
claimable_height: u32,
554+
},
555+
}
556+
507557
/// An HTLC which has been irrevocably resolved on-chain, and has reached ANTI_REORG_DELAY.
508558
#[derive(PartialEq)]
509559
struct HTLCIrrevocablyResolved {
@@ -1266,6 +1316,107 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
12661316
pub fn current_best_block(&self) -> BestBlock {
12671317
self.inner.lock().unwrap().best_block.clone()
12681318
}
1319+
1320+
/// Gets the balances in this channel which are either claimable by us if we were to
1321+
/// force-close the channel now or which are claimable on-chain or claims which are awaiting
1322+
/// confirmation.
1323+
///
1324+
/// Any balances in the channel which are available on-chain (ignoring on-chain fees) are
1325+
/// included here until an [`Event::SpendableOutputs`] event has been generated for the
1326+
/// balance, or until our counterparty has claimed the balance and accrued several
1327+
/// confirmations on the claim transaction.
1328+
///
1329+
/// See [`ClaimableBalance`] for additional details on the types of claimable balances which
1330+
/// may be returned here and their meanings.
1331+
pub fn get_claimable_balances(&self) -> Vec<ClaimableBalance> {
1332+
let mut res = Vec::new();
1333+
let us = self.inner.lock().unwrap();
1334+
1335+
let mut confirmed_txid = us.funding_spend_confirmed;
1336+
if let Some((txid, conf_thresh)) = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
1337+
if let OnchainEvent::FundingSpendConfirmation { txid, .. } = event.event {
1338+
Some((txid, event.confirmation_threshold()))
1339+
} else { None }
1340+
}) {
1341+
debug_assert!(us.funding_spend_confirmed.is_none(), "We have a pending funding spend awaiting confirmation, we can't have confirmed it already!");
1342+
confirmed_txid = Some(txid);
1343+
res.push(ClaimableBalance::ClaimableAwaitingConfirmations {
1344+
claimable_amount_satoshis: us.current_holder_commitment_tx.to_self_value_sat,
1345+
confirmation_height: conf_thresh,
1346+
});
1347+
}
1348+
1349+
macro_rules! walk_htlcs {
1350+
($holder_commitment: expr, $htlc_iter: expr) => {
1351+
for htlc in $htlc_iter {
1352+
if let Some(htlc_input_idx) = htlc.transaction_output_index {
1353+
if us.htlcs_resolved_on_chain.iter().any(|v| v.input_idx == htlc_input_idx) {
1354+
assert!(us.funding_spend_confirmed.is_some());
1355+
} else if htlc.offered == $holder_commitment {
1356+
res.push(ClaimableBalance::PossiblyClaimableHTLCAwaitingTimeout {
1357+
claimable_amount_satoshis: htlc.amount_msat / 1000,
1358+
claimable_height: htlc.cltv_expiry,
1359+
});
1360+
} else {
1361+
if us.payment_preimages.get(&htlc.payment_hash).is_some() {
1362+
if let Some(conf_thresh) = us.onchain_events_awaiting_threshold_conf.iter().find_map(|event| {
1363+
if let OnchainEvent::HTLCSpendConfirmation { input_idx, .. } = event.event {
1364+
if input_idx == htlc_input_idx { Some(event.confirmation_threshold()) } else { None }
1365+
} else { None }
1366+
}) {
1367+
res.push(ClaimableBalance::ClaimableAwaitingConfirmations {
1368+
claimable_amount_satoshis: htlc.amount_msat / 1000,
1369+
confirmation_height: conf_thresh,
1370+
});
1371+
} else {
1372+
res.push(ClaimableBalance::ContentiousClaimable {
1373+
claimable_amount_satoshis: htlc.amount_msat / 1000,
1374+
timeout_height: htlc.cltv_expiry,
1375+
});
1376+
}
1377+
}
1378+
}
1379+
}
1380+
}
1381+
}
1382+
}
1383+
1384+
if let Some(txid) = confirmed_txid {
1385+
if Some(txid) == us.current_counterparty_commitment_txid || Some(txid) == us.prev_counterparty_commitment_txid {
1386+
walk_htlcs!(false, us.counterparty_claimable_outpoints.get(&txid).unwrap().iter().map(|(a, _)| a));
1387+
} else if txid == us.current_holder_commitment_tx.txid {
1388+
walk_htlcs!(true, us.current_holder_commitment_tx.htlc_outputs.iter().map(|(a, _, _)| a));
1389+
} else if let Some(prev_commitment) = &us.prev_holder_signed_commitment_tx {
1390+
if txid == prev_commitment.txid {
1391+
walk_htlcs!(true, prev_commitment.htlc_outputs.iter().map(|(a, _, _)| a));
1392+
}
1393+
}
1394+
// TODO: Add logic to provide claimable balances for counterparty broadcasting revoked
1395+
// outputs.
1396+
// Otherwise assume we closed with a cooperative close which only needs the
1397+
// `ClaimableAwaitingConfirmations` balance pushed first.
1398+
} else {
1399+
let mut claimable_inbound_htlc_value_sat = 0;
1400+
for (htlc, _, _) in us.current_holder_commitment_tx.htlc_outputs.iter() {
1401+
if htlc.transaction_output_index.is_none() { continue; }
1402+
if htlc.offered {
1403+
res.push(ClaimableBalance::PossiblyClaimableHTLCAwaitingTimeout {
1404+
claimable_amount_satoshis: htlc.amount_msat / 1000,
1405+
claimable_height: htlc.cltv_expiry,
1406+
});
1407+
} else {
1408+
if us.payment_preimages.get(&htlc.payment_hash).is_some() {
1409+
claimable_inbound_htlc_value_sat += htlc.amount_msat / 1000;
1410+
}
1411+
}
1412+
}
1413+
res.push(ClaimableBalance::ClaimableOnChannelClose {
1414+
claimable_amount_satoshis: us.current_holder_commitment_tx.to_self_value_sat + claimable_inbound_htlc_value_sat,
1415+
});
1416+
}
1417+
1418+
res
1419+
}
12691420
}
12701421

12711422
/// Compares a broadcasted commitment transaction's HTLCs with those in the latest state,

‎lightning/src/ln/monitor_tests.rs

Lines changed: 297 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99

1010
//! Further functional tests which test blockchain reorganizations.
1111
12-
use chain::channelmonitor::ANTI_REORG_DELAY;
13-
use ln::{PaymentPreimage, PaymentHash};
12+
use chain::channelmonitor::{ANTI_REORG_DELAY, ClaimableBalance};
13+
use chain::transaction::OutPoint;
14+
use ln::{channel, PaymentPreimage, PaymentHash};
15+
use ln::channelmanager::BREAKDOWN_TIMEOUT;
1416
use ln::features::InitFeatures;
1517
use ln::msgs::{ChannelMessageHandler, HTLCFailChannelUpdate, ErrorAction};
1618
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
@@ -19,6 +21,10 @@ use routing::router::get_route;
1921
use bitcoin::hashes::sha256::Hash as Sha256;
2022
use bitcoin::hashes::Hash;
2123

24+
use bitcoin::blockdata::script::Builder;
25+
use bitcoin::blockdata::opcodes;
26+
use bitcoin::secp256k1::Secp256k1;
27+
2228
use prelude::*;
2329

2430
use ln::functional_test_utils::*;
@@ -79,3 +85,292 @@ fn chanmon_fail_from_stale_commitment() {
7985
expect_payment_failed!(nodes[0], payment_hash, false);
8086
expect_payment_failure_chan_update!(nodes[0], update_a.contents.short_channel_id, true);
8187
}
88+
89+
#[test]
90+
fn chanmon_claim_value_coop_close() {
91+
// Tests `get_claimable_balances` returns the correct values across a simple cooperative claim.
92+
// Specifically, this tests that the channel non-HTLC balances show up in
93+
// `get_claimable_balances` until the cooperative claims have confirmed and generated a
94+
// `SpendableOutputs` event, and no longer.
95+
let chanmon_cfgs = create_chanmon_cfgs(2);
96+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
97+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
98+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
99+
100+
let (_, _, chan_id, funding_tx) =
101+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 1_000_000, InitFeatures::known(), InitFeatures::known());
102+
let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
103+
assert_eq!(funding_outpoint.to_channel_id(), chan_id);
104+
105+
let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
106+
107+
assert_eq!(vec![ClaimableBalance::ClaimableOnChannelClose {
108+
claimable_amount_satoshis: 1_000_000 - 1_000 - chan_feerate * channel::COMMITMENT_TX_BASE_WEIGHT / 1000
109+
}],
110+
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
111+
assert_eq!(vec![ClaimableBalance::ClaimableOnChannelClose { claimable_amount_satoshis: 1_000, }],
112+
nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
113+
114+
nodes[0].node.close_channel(&chan_id).unwrap();
115+
let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
116+
nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown);
117+
let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
118+
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &InitFeatures::known(), &node_1_shutdown);
119+
120+
let node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
121+
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
122+
let (_, node_1_closing_signed) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
123+
nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &node_1_closing_signed.unwrap());
124+
let (_, node_0_none) = get_closing_signed_broadcast!(nodes[0].node, nodes[1].node.get_our_node_id());
125+
assert!(node_0_none.is_none());
126+
127+
let shutdown_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
128+
assert_eq!(shutdown_tx, nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0));
129+
assert_eq!(shutdown_tx.len(), 1);
130+
131+
mine_transaction(&nodes[0], &shutdown_tx[0]);
132+
mine_transaction(&nodes[1], &shutdown_tx[0]);
133+
134+
assert!(nodes[0].node.list_channels().is_empty());
135+
assert!(nodes[1].node.list_channels().is_empty());
136+
137+
assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
138+
assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
139+
140+
assert_eq!(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
141+
claimable_amount_satoshis: 1_000_000 - 1_000 - chan_feerate * channel::COMMITMENT_TX_BASE_WEIGHT / 1000,
142+
confirmation_height: nodes[0].best_block_info().1 + ANTI_REORG_DELAY - 1,
143+
}],
144+
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
145+
assert_eq!(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
146+
claimable_amount_satoshis: 1000,
147+
confirmation_height: nodes[1].best_block_info().1 + ANTI_REORG_DELAY - 1,
148+
}],
149+
nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
150+
151+
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
152+
connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
153+
154+
assert_eq!(Vec::<ClaimableBalance>::new(),
155+
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
156+
assert_eq!(Vec::<ClaimableBalance>::new(),
157+
nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
158+
159+
let mut node_a_spendable = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
160+
assert_eq!(node_a_spendable.len(), 1);
161+
if let Event::SpendableOutputs { outputs } = node_a_spendable.pop().unwrap() {
162+
assert_eq!(outputs.len(), 1);
163+
let spend_tx = nodes[0].keys_manager.backing.spend_spendable_outputs(&[&outputs[0]], Vec::new(),
164+
Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), 253, &Secp256k1::new()).unwrap();
165+
check_spends!(spend_tx, shutdown_tx[0]);
166+
}
167+
168+
let mut node_b_spendable = nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events();
169+
assert_eq!(node_b_spendable.len(), 1);
170+
if let Event::SpendableOutputs { outputs } = node_b_spendable.pop().unwrap() {
171+
assert_eq!(outputs.len(), 1);
172+
let spend_tx = nodes[1].keys_manager.backing.spend_spendable_outputs(&[&outputs[0]], Vec::new(),
173+
Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), 253, &Secp256k1::new()).unwrap();
174+
check_spends!(spend_tx, shutdown_tx[0]);
175+
}
176+
}
177+
178+
fn sorted_vec<T: Ord>(mut v: Vec<T>) -> Vec<T> {
179+
v.sort_unstable();
180+
v
181+
}
182+
183+
#[test]
184+
fn test_claim_value_force_close() {
185+
// Tests `get_claimable_balances` with an HTLC across a force-close.
186+
// We build a channel with an HTLC pending, then force close the channel and check that the
187+
// `get_claimable_balances` return value is correct as transactions confirm on-chain.
188+
let chanmon_cfgs = create_chanmon_cfgs(2);
189+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
190+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
191+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
192+
193+
let (_, _, chan_id, funding_tx) =
194+
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 1_000_000, InitFeatures::known(), InitFeatures::known());
195+
let funding_outpoint = OutPoint { txid: funding_tx.txid(), index: 0 };
196+
assert_eq!(funding_outpoint.to_channel_id(), chan_id);
197+
198+
let payment_preimage = route_payment(&nodes[0], &[&nodes[1]], 3_000_000).0;
199+
// This HTLC will be dust, and not be claimable at all:
200+
let (dust_payment_preimage, dust_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 3_000);
201+
202+
let htlc_cltv_timeout = nodes[0].best_block_info().1 + TEST_FINAL_CLTV + 1; // Note ChannelManager adds one to CLTV timeouts for safety
203+
204+
let chan_feerate = get_feerate!(nodes[0], chan_id) as u64;
205+
206+
let remote_txn = get_local_commitment_txn!(nodes[1], chan_id);
207+
// Before B receives the payment preimage, it only suggests the push_msat value of 1_000 sats
208+
// as claimable. A lists both its to-self balance and the (possibly-claimable) HTLC.
209+
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableOnChannelClose {
210+
claimable_amount_satoshis: 1_000_000 - 3_000 - 1_000 - 3 - chan_feerate *
211+
(channel::COMMITMENT_TX_BASE_WEIGHT + channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
212+
}, ClaimableBalance::PossiblyClaimableHTLCAwaitingTimeout {
213+
claimable_amount_satoshis: 3_000,
214+
claimable_height: htlc_cltv_timeout,
215+
}]),
216+
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
217+
assert_eq!(vec![ClaimableBalance::ClaimableOnChannelClose {
218+
claimable_amount_satoshis: 1_000,
219+
}],
220+
nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
221+
222+
nodes[1].node.claim_funds(payment_preimage);
223+
check_added_monitors!(nodes[1], 1);
224+
get_htlc_update_msgs!(&nodes[1], nodes[0].node.get_our_node_id());
225+
// We claim the dust payment here as well, but it won't impact our claimable balances as its
226+
// dust and thus doesn't appear on chain at all.
227+
nodes[1].node.claim_funds(dust_payment_preimage);
228+
check_added_monitors!(nodes[1], 1);
229+
230+
// Once B has received the payment preimage, it includes the value of the HTLC in its
231+
// "claimable if you were to close the channel" balance.
232+
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableOnChannelClose {
233+
claimable_amount_satoshis: 1_000_000 - // Channel funding value in satoshis
234+
3_000 - // The larger HTLC value in satoshis
235+
1_000 - // The push_msat value in satoshis
236+
3 - // The dust HTLC value in satoshis
237+
// The commitment transaction fee with one HTLC output:
238+
chan_feerate * (channel::COMMITMENT_TX_BASE_WEIGHT + channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
239+
}, ClaimableBalance::PossiblyClaimableHTLCAwaitingTimeout {
240+
claimable_amount_satoshis: 3_000,
241+
claimable_height: htlc_cltv_timeout,
242+
}]),
243+
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
244+
assert_eq!(vec![ClaimableBalance::ClaimableOnChannelClose {
245+
claimable_amount_satoshis: 1_000 + 3_000,
246+
}],
247+
nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
248+
249+
// Broadcast the closing transaction (which has the pending HTLC in it) and get B's broadcasted
250+
// HTLC claim transaction with preimage.
251+
let node_b_commitment_claimable = nodes[1].best_block_info().1 + BREAKDOWN_TIMEOUT as u32;
252+
mine_transaction(&nodes[0], &remote_txn[0]);
253+
mine_transaction(&nodes[1], &remote_txn[0]);
254+
255+
let b_broadcast_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
256+
assert_eq!(b_broadcast_txn.len(), 3);
257+
assert_eq!(b_broadcast_txn[0], b_broadcast_txn[2]);
258+
// b_broadcast_txn[0] should spend the HTLC output of the commitment tx for 3_000 sats
259+
check_spends!(b_broadcast_txn[0], remote_txn[0]);
260+
assert_eq!(b_broadcast_txn[0].input.len(), 1);
261+
assert_eq!(remote_txn[0].output[b_broadcast_txn[0].input[0].previous_output.vout as usize].value, 3_000);
262+
check_spends!(b_broadcast_txn[1], funding_tx);
263+
264+
assert!(nodes[0].node.list_channels().is_empty());
265+
check_closed_broadcast!(nodes[0], true);
266+
check_added_monitors!(nodes[0], 1);
267+
assert!(nodes[1].node.list_channels().is_empty());
268+
check_closed_broadcast!(nodes[1], true);
269+
check_added_monitors!(nodes[1], 1);
270+
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
271+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
272+
273+
// Once the commitment transaction confirms, we will wait until ANTI_REORG_DELAY until we
274+
// generate any `SpendableOutputs` events. Thus, the same balances will still be listed
275+
// available in `get_claimable_balances`. However, both will swap from `ClaimableOnClose` to
276+
// other ClaimableBalance variants, as close has already happened.
277+
assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
278+
assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
279+
280+
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
281+
claimable_amount_satoshis: 1_000_000 - 3_000 - 1_000 - 3 - chan_feerate *
282+
(channel::COMMITMENT_TX_BASE_WEIGHT + channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
283+
confirmation_height: nodes[0].best_block_info().1 + ANTI_REORG_DELAY - 1,
284+
}, ClaimableBalance::PossiblyClaimableHTLCAwaitingTimeout {
285+
claimable_amount_satoshis: 3_000,
286+
claimable_height: htlc_cltv_timeout,
287+
}]),
288+
sorted_vec(nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
289+
// The main non-HTLC balance is just awaiting confirmations, but the claimable height is the
290+
// CSV delay, not ANTI_REORG_DELAY.
291+
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
292+
claimable_amount_satoshis: 1_000,
293+
confirmation_height: node_b_commitment_claimable,
294+
},
295+
// The HTLC balance is "contentious" as our counterparty could claim it if we wait too
296+
// long.
297+
ClaimableBalance::ContentiousClaimable {
298+
claimable_amount_satoshis: 3_000,
299+
timeout_height: htlc_cltv_timeout,
300+
}]),
301+
sorted_vec(nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
302+
303+
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
304+
expect_payment_failed!(nodes[0], dust_payment_hash, true);
305+
connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
306+
307+
// After ANTI_REORG_DELAY, A will consider its balance fully spendable and generate a
308+
// `SpendableOutputs` event. However, B still has to wait for the CSV delay.
309+
assert_eq!(vec![ClaimableBalance::PossiblyClaimableHTLCAwaitingTimeout {
310+
claimable_amount_satoshis: 3_000,
311+
claimable_height: htlc_cltv_timeout,
312+
}],
313+
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
314+
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
315+
claimable_amount_satoshis: 1_000,
316+
confirmation_height: node_b_commitment_claimable,
317+
}, ClaimableBalance::ContentiousClaimable {
318+
claimable_amount_satoshis: 3_000,
319+
timeout_height: htlc_cltv_timeout,
320+
}]),
321+
sorted_vec(nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
322+
323+
let mut node_a_spendable = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
324+
assert_eq!(node_a_spendable.len(), 1);
325+
if let Event::SpendableOutputs { outputs } = node_a_spendable.pop().unwrap() {
326+
assert_eq!(outputs.len(), 1);
327+
let spend_tx = nodes[0].keys_manager.backing.spend_spendable_outputs(&[&outputs[0]], Vec::new(),
328+
Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), 253, &Secp256k1::new()).unwrap();
329+
check_spends!(spend_tx, remote_txn[0]);
330+
}
331+
332+
assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
333+
334+
// After broadcasting the HTLC claim transaction, node A will still consider the HTLC
335+
// possibly-claimable up to ANTI_REORG_DELAY, at which point it will drop it.
336+
mine_transaction(&nodes[0], &b_broadcast_txn[0]);
337+
expect_payment_sent!(nodes[0], payment_preimage);
338+
assert_eq!(vec![ClaimableBalance::PossiblyClaimableHTLCAwaitingTimeout {
339+
claimable_amount_satoshis: 3_000,
340+
claimable_height: htlc_cltv_timeout,
341+
}],
342+
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
343+
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
344+
assert_eq!(Vec::<ClaimableBalance>::new(),
345+
nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
346+
347+
// Node B will no longer consider the HTLC "contentious" after the HTLC claim transaction
348+
// confirms, and consider it simply "awaiting confirmations".
349+
mine_transaction(&nodes[1], &b_broadcast_txn[0]);
350+
assert_eq!(sorted_vec(vec![ClaimableBalance::ClaimableAwaitingConfirmations {
351+
claimable_amount_satoshis: 1_000,
352+
confirmation_height: node_b_commitment_claimable,
353+
}, ClaimableBalance::ClaimableAwaitingConfirmations {
354+
claimable_amount_satoshis: 3_000,
355+
confirmation_height: nodes[1].best_block_info().1 + ANTI_REORG_DELAY - 1,
356+
}]),
357+
sorted_vec(nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances()));
358+
359+
// Finally, after ANTI_REORG_DELAY confirmations on the HTLC transaction, plus reaching the
360+
// commitment output CSV, we'll get a SpendableOutputs event for both and have no further
361+
// claimable balance for node B.
362+
connect_blocks(&nodes[1], BREAKDOWN_TIMEOUT as u32 - ANTI_REORG_DELAY - 1);
363+
assert_eq!(nodes[1].best_block_info().1, node_b_commitment_claimable);
364+
365+
let mut node_b_spendable = nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events();
366+
assert_eq!(node_b_spendable.len(), 1);
367+
if let Event::SpendableOutputs { outputs } = node_b_spendable.pop().unwrap() {
368+
assert_eq!(outputs.len(), 1);
369+
let spend_tx = nodes[1].keys_manager.backing.spend_spendable_outputs(&[&outputs[0]], Vec::new(),
370+
Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), 253, &Secp256k1::new()).unwrap();
371+
check_spends!(spend_tx, remote_txn[0]);
372+
}
373+
374+
assert_eq!(Vec::<ClaimableBalance>::new(),
375+
nodes[1].chain_monitor.chain_monitor.monitors.read().unwrap().get(&funding_outpoint).unwrap().get_claimable_balances());
376+
}

0 commit comments

Comments
 (0)
Please sign in to comment.