Skip to content

Commit 1e0d36d

Browse files
committed
Test register_output is called on dependent txn
chain::Filter::register_output may return an in-block dependent transaction that spends the output. Test the scenario where the txdata given to ChainMonitor::block_connected includes a commitment transaction whose HTLC output is spent in the same block but not included in txdata. Instead, it is returned by chain::Filter::register_output when given the commitment transaction's HTLC output. This is a common scenario for Electrum clients, which provided filtered txdata.
1 parent 8afda0d commit 1e0d36d

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

lightning/src/chain/chainmonitor.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,55 @@ impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> even
267267
pending_events
268268
}
269269
}
270+
271+
#[cfg(test)]
272+
mod tests {
273+
use ::{check_added_monitors, get_local_commitment_txn};
274+
use ln::features::InitFeatures;
275+
use ln::functional_test_utils::*;
276+
use util::events::EventsProvider;
277+
use util::events::MessageSendEventsProvider;
278+
use util::test_utils::{OnRegisterOutput, TxOutReference};
279+
280+
/// Tests that in-block dependent transactions are processed by `block_connected` when not
281+
/// included in `txdata` but returned by [`chain::Filter::register_output`]. For instance,
282+
/// a commitment transaction's HTLC output may be spent in the same block as the commitment
283+
/// transaction itself. An Electrum client may filter the commitment transaction but needs to
284+
/// return the HTLC transaction so it can be processed.
285+
#[test]
286+
fn connect_block_checks_dependent_transactions() {
287+
let chanmon_cfgs = create_chanmon_cfgs(2);
288+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
289+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
290+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
291+
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
292+
293+
// Send a payment, saving nodes[0]'s revoked commitment and HTLC-Timeout transactions.
294+
let (commitment_tx, htlc_tx) = {
295+
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 5_000_000).0;
296+
let mut txn = get_local_commitment_txn!(nodes[0], channel.2);
297+
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 5_000_000);
298+
299+
assert_eq!(txn.len(), 2);
300+
(txn.remove(0), txn.remove(0))
301+
};
302+
303+
// Set expectations on nodes[1]'s chain source to return dependent transactions.
304+
let htlc_output = TxOutReference(commitment_tx.clone(), 0);
305+
let to_local_output = TxOutReference(commitment_tx.clone(), 1);
306+
let htlc_timeout_output = TxOutReference(htlc_tx.clone(), 0);
307+
nodes[1].chain_source
308+
.expect(OnRegisterOutput { with: htlc_output, returns: Some((1, htlc_tx)) })
309+
.expect(OnRegisterOutput { with: to_local_output, returns: None })
310+
.expect(OnRegisterOutput { with: htlc_timeout_output, returns: None });
311+
312+
// Notify nodes[1] that nodes[0]'s revoked commitment transaction was mined. The chain
313+
// source should return the dependent HTLC transaction when the HTLC output is registered.
314+
mine_transaction(&nodes[1], &commitment_tx);
315+
316+
// Clean up so uninteresting assertions don't fail.
317+
check_added_monitors!(nodes[1], 1);
318+
nodes[1].node.get_and_clear_pending_msg_events();
319+
nodes[1].node.get_and_clear_pending_events();
320+
}
321+
}

lightning/src/ln/functional_test_utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ macro_rules! get_feerate {
341341
}
342342
}
343343

344-
#[cfg(test)]
344+
/// Returns any local commitment transactions for the channel.
345+
#[macro_export]
345346
macro_rules! get_local_commitment_txn {
346347
($node: expr, $channel_id: expr) => {
347348
{

0 commit comments

Comments
 (0)