Skip to content

Commit 68be3c0

Browse files
committed
Test that we do not fail-backwards HTLCs that the remote on-chained
1 parent f48fe4b commit 68be3c0

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

src/ln/channelmanager.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,6 +2198,7 @@ mod tests {
21982198
use bitcoin::util::hash::Sha256dHash;
21992199
use bitcoin::blockdata::block::{Block, BlockHeader};
22002200
use bitcoin::blockdata::transaction::{Transaction, TxOut};
2201+
use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
22012202
use bitcoin::blockdata::constants::genesis_block;
22022203
use bitcoin::network::constants::Network;
22032204
use bitcoin::network::serialize::serialize;
@@ -3401,6 +3402,125 @@ mod tests {
34013402
nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0], &node_txn[1]], &[1; 2]);
34023403
}
34033404

3405+
#[test]
3406+
fn test_force_close_fail_back() {
3407+
// Check which HTLCs are failed-backwards on channel force-closure
3408+
let mut nodes = create_network(3);
3409+
create_announced_chan_between_nodes(&nodes, 0, 1);
3410+
create_announced_chan_between_nodes(&nodes, 1, 2);
3411+
3412+
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, 42).unwrap();
3413+
3414+
let our_payment_preimage = [*nodes[0].network_payment_count.borrow(); 32];
3415+
*nodes[0].network_payment_count.borrow_mut() += 1;
3416+
let our_payment_hash = {
3417+
let mut sha = Sha256::new();
3418+
sha.input(&our_payment_preimage[..]);
3419+
let mut ret = [0; 32];
3420+
sha.result(&mut ret);
3421+
ret
3422+
};
3423+
3424+
let mut payment_event = {
3425+
nodes[0].node.send_payment(route, our_payment_hash).unwrap();
3426+
{
3427+
let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap();
3428+
assert_eq!(added_monitors.len(), 1);
3429+
added_monitors.clear();
3430+
}
3431+
3432+
let mut events = nodes[0].node.get_and_clear_pending_events();
3433+
assert_eq!(events.len(), 1);
3434+
SendEvent::from_event(events.remove(0))
3435+
};
3436+
3437+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]).unwrap();
3438+
commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
3439+
3440+
let events_1 = nodes[1].node.get_and_clear_pending_events();
3441+
assert_eq!(events_1.len(), 1);
3442+
match events_1[0] {
3443+
Event::PendingHTLCsForwardable { .. } => { },
3444+
_ => panic!("Unexpected event"),
3445+
};
3446+
3447+
nodes[1].node.channel_state.lock().unwrap().next_forward = Instant::now();
3448+
nodes[1].node.process_pending_htlc_forwards();
3449+
3450+
let mut events_2 = nodes[1].node.get_and_clear_pending_events();
3451+
assert_eq!(events_2.len(), 1);
3452+
payment_event = SendEvent::from_event(events_2.remove(0));
3453+
assert_eq!(payment_event.msgs.len(), 1);
3454+
3455+
{
3456+
let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap();
3457+
assert_eq!(added_monitors.len(), 1);
3458+
added_monitors.clear();
3459+
}
3460+
3461+
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]).unwrap();
3462+
nodes[2].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg).unwrap();
3463+
3464+
{
3465+
let mut added_monitors = nodes[2].chan_monitor.added_monitors.lock().unwrap();
3466+
assert_eq!(added_monitors.len(), 1);
3467+
added_monitors.clear();
3468+
}
3469+
3470+
// nodes[2] now has the latest commitment transaction, but hasn't revoked its previous
3471+
// state or updated nodes[1]' state. Now force-close and broadcast that commitment/HTLC
3472+
// transaction and ensure nodes[1] doesn't fail-backwards (this was originally a bug!).
3473+
3474+
nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id);
3475+
let events_3 = nodes[2].node.get_and_clear_pending_events();
3476+
assert_eq!(events_3.len(), 1);
3477+
match events_3[0] {
3478+
Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => {
3479+
assert_eq!(flags & 0b10, 0b10);
3480+
},
3481+
_ => panic!("Unexpected event"),
3482+
}
3483+
3484+
let tx = {
3485+
let mut node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap();
3486+
// Note that we don't bother broadcasting the HTLC-Success transaction here as we don't
3487+
// have a use for it unless nodes[2] learns the preimage somehow, the funds will go
3488+
// back to nodes[1] upon timeout otherwise.
3489+
assert_eq!(node_txn.len(), 1);
3490+
node_txn.remove(0)
3491+
};
3492+
3493+
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
3494+
nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&tx], &[1]);
3495+
3496+
let events_4 = nodes[1].node.get_and_clear_pending_events();
3497+
// Note no UpdateHTLCs event here from nodes[1] to nodes[0]!
3498+
assert_eq!(events_4.len(), 1);
3499+
match events_4[0] {
3500+
Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => {
3501+
assert_eq!(flags & 0b10, 0b10);
3502+
},
3503+
_ => panic!("Unexpected event"),
3504+
}
3505+
3506+
// Now check that if we add the preimage to ChannelMonitor it broadcasts our HTLC-Success..
3507+
{
3508+
let mut monitors = nodes[2].chan_monitor.simple_monitor.monitors.lock().unwrap();
3509+
monitors.get_mut(&OutPoint::new(Sha256dHash::from(&payment_event.commitment_msg.channel_id[..]), 0)).unwrap()
3510+
.provide_payment_preimage(&our_payment_hash, &our_payment_preimage);
3511+
}
3512+
nodes[2].chain_monitor.block_connected_checked(&header, 1, &[&tx], &[1]);
3513+
let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap();
3514+
assert_eq!(node_txn.len(), 1);
3515+
assert_eq!(node_txn[0].input.len(), 1);
3516+
assert_eq!(node_txn[0].input[0].previous_output.txid, tx.txid());
3517+
assert_eq!(node_txn[0].lock_time, 0); // Must be an HTLC-Success
3518+
assert_eq!(node_txn[0].input[0].witness.len(), 5); // Must be an HTLC-Success
3519+
let mut funding_tx_map = HashMap::new();
3520+
funding_tx_map.insert(tx.txid(), tx);
3521+
node_txn[0].verify(&funding_tx_map).unwrap();
3522+
}
3523+
34043524
#[test]
34053525
fn test_unconf_chan() {
34063526
// After creating a chan between nodes, we disconnect all blocks previously seen to force a channel close on nodes[0] side

src/ln/channelmonitor.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ pub trait ManyChannelMonitor: Send + Sync {
6363
/// If you're using this for local monitoring of your own channels, you probably want to use
6464
/// `OutPoint` as the key, which will give you a ManyChannelMonitor implementation.
6565
pub struct SimpleManyChannelMonitor<Key> {
66+
#[cfg(test)] // Used in ChannelManager tests to manipulate channels directly
67+
pub monitors: Mutex<HashMap<Key, ChannelMonitor>>,
68+
#[cfg(not(test))]
6669
monitors: Mutex<HashMap<Key, ChannelMonitor>>,
6770
chain_monitor: Arc<ChainWatchInterface>,
6871
broadcaster: Arc<BroadcasterInterface>

0 commit comments

Comments
 (0)