Skip to content

Commit 83b341d

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 ad0b173 commit 83b341d

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

lightning/src/chain/chainmonitor.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,57 @@ 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+
use bitcoin::blockdata::block::{Block, BlockHeader};
281+
282+
/// Tests that in-block dependent transactions are processed by `block_connected` when not
283+
/// included in `txdata` but returned by [`chain::Filter::register_output`]. For instance,
284+
/// a commitment transaction's HTLC output may be spent in the same block as the commitment
285+
/// transaction itself. An Electrum client may filter the commitment transaction but needs to
286+
/// return the HTLC transaction so it can be processed.
287+
#[test]
288+
fn connect_block_checks_dependent_transactions() {
289+
let chanmon_cfgs = create_chanmon_cfgs(2);
290+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
291+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
292+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
293+
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
294+
295+
// Send a payment, saving nodes[0]'s revoked commitment and HTLC-Timeout transactions.
296+
let (commitment_tx, htlc_tx) = {
297+
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 5_000_000).0;
298+
let mut txn = get_local_commitment_txn!(nodes[0], channel.2);
299+
claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 5_000_000);
300+
301+
assert_eq!(txn.len(), 2);
302+
(txn.remove(0), txn.remove(0))
303+
};
304+
305+
// Set expectations on nodes[1]'s chain source to return dependent transactions.
306+
let htlc_output = TxOutReference(commitment_tx.clone(), 0);
307+
let to_local_output = TxOutReference(commitment_tx.clone(), 1);
308+
let htlc_timeout_output = TxOutReference(htlc_tx.clone(), 0);
309+
nodes[1].chain_source
310+
.expect(OnRegisterOutput { with: htlc_output, returns: Some((1, htlc_tx)) })
311+
.expect(OnRegisterOutput { with: to_local_output, returns: None })
312+
.expect(OnRegisterOutput { with: htlc_timeout_output, returns: None });
313+
314+
// Notify nodes[1] that nodes[0]'s revoked commitment transaction was mined. The chain
315+
// source should return the dependent HTLC transaction when the HTLC output is registered.
316+
mine_transaction(&nodes[1], &commitment_tx);
317+
318+
// Clean up so uninteresting assertions don't fail.
319+
check_added_monitors!(nodes[1], 1);
320+
nodes[1].node.get_and_clear_pending_msg_events();
321+
nodes[1].node.get_and_clear_pending_events();
322+
}
323+
}

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)