X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=3e79eecacbefd7aa3ea94d970c5e74062a691dc4;hb=9c3f3e76e58586dd0d985ea9f58193e4a757512b;hp=36c750fe7690cc7628f26d395f3e8ddffda88b98;hpb=87398be29354ea0e844a13c6e6988c8152d31a18;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 36c750fe..3e79eeca 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -11,13 +11,13 @@ //! payments/messages between them, and often checking the resulting ChannelMonitors are able to //! claim outputs on-chain. +use chain::Watch; +use chain::channelmonitor; +use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY}; use chain::transaction::OutPoint; use chain::keysinterface::{ChannelKeys, KeysInterface, SpendableOutputDescriptor}; -use chain::chaininterface::{ChainListener, ChainWatchInterfaceUtil, BlockNotifier}; use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC}; use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure, BREAKDOWN_TIMEOUT}; -use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ManyChannelMonitor, ANTI_REORG_DELAY}; -use ln::channelmonitor; use ln::channel::{Channel, ChannelError}; use ln::{chan_utils, onion_utils}; use routing::router::{Route, RouteHop, get_route}; @@ -475,7 +475,7 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) { if steps & 0x0f == 4 { return; } nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created); { - let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap(); + let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); assert_eq!(added_monitors[0].0, funding_output); added_monitors.clear(); @@ -485,7 +485,7 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) { if steps & 0x0f == 5 { return; } nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed); { - let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap(); + let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); assert_eq!(added_monitors[0].0, funding_output); added_monitors.clear(); @@ -659,7 +659,7 @@ fn test_update_fee_with_fundee_update_add_htlc() { // nothing happens since node[1] is in AwaitingRemoteRevoke nodes[1].node.send_payment(&route, our_payment_hash, &None).unwrap(); { - let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap(); + let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 0); added_monitors.clear(); } @@ -2846,14 +2846,14 @@ fn test_htlc_on_chain_success() { // Verify that B's ChannelManager is able to extract preimage from HTLC Success tx and pass it backward connect_block(&nodes[1], &Block { header, txdata: node_txn}, 1); { - let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap(); + let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); assert_eq!(added_monitors[0].0.txid, chan_2.3.txid()); added_monitors.clear(); } let events = nodes[1].node.get_and_clear_pending_msg_events(); { - let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap(); + let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 2); assert_eq!(added_monitors[0].0.txid, chan_1.3.txid()); assert_eq!(added_monitors[1].0.txid, chan_1.3.txid()); @@ -3521,7 +3521,7 @@ fn test_force_close_fail_back() { // Now check that if we add the preimage to ChannelMonitor it broadcasts our HTLC-Success.. { - let mut monitors = nodes[2].chan_monitor.simple_monitor.monitors.lock().unwrap(); + let mut monitors = nodes[2].chain_monitor.chain_monitor.monitors.lock().unwrap(); monitors.get_mut(&OutPoint{ txid: Txid::from_slice(&payment_event.commitment_msg.channel_id[..]).unwrap(), index: 0 }).unwrap() .provide_payment_preimage(&our_payment_hash, &our_payment_preimage); } @@ -3557,10 +3557,8 @@ fn test_unconf_chan() { header = BlockHeader { version: 0x20000000, prev_blockhash: header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; headers.push(header.clone()); } - let mut height = 99; while !headers.is_empty() { - nodes[0].node.block_disconnected(&headers.pop().unwrap(), height); - height -= 1; + nodes[0].node.block_disconnected(&headers.pop().unwrap()); } check_closed_broadcast!(nodes[0], false); check_added_monitors!(nodes[0], 1); @@ -4309,9 +4307,10 @@ fn test_no_txn_manager_serialize_deserialize() { let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let logger: test_utils::TestLogger; let fee_estimator: test_utils::TestFeeEstimator; - let new_chan_monitor: test_utils::TestChannelMonitor; + let persister: test_utils::TestPersister; + let new_chain_monitor: test_utils::TestChainMonitor; let keys_manager: test_utils::TestKeysInterface; - let nodes_0_deserialized: ChannelManager; + let nodes_0_deserialized: ChannelManager; let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, InitFeatures::known(), InitFeatures::known()); @@ -4320,12 +4319,13 @@ fn test_no_txn_manager_serialize_deserialize() { let nodes_0_serialized = nodes[0].node.encode(); let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new()); - nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap(); + nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap(); logger = test_utils::TestLogger::new(); fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; - new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator); - nodes[0].chan_monitor = &new_chan_monitor; + persister = test_utils::TestPersister{}; + new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister); + nodes[0].chain_monitor = &new_chain_monitor; let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..]; let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor)>::read(&mut chan_0_monitor_read).unwrap(); assert!(chan_0_monitor_read.is_empty()); @@ -4336,11 +4336,11 @@ fn test_no_txn_manager_serialize_deserialize() { let (_, nodes_0_deserialized_tmp) = { let mut channel_monitors = HashMap::new(); channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor); - <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { default_config: config, keys_manager: &keys_manager, fee_estimator: &fee_estimator, - monitor: nodes[0].chan_monitor, + chain_monitor: nodes[0].chain_monitor, tx_broadcaster: nodes[0].tx_broadcaster.clone(), logger: &logger, channel_monitors, @@ -4349,9 +4349,8 @@ fn test_no_txn_manager_serialize_deserialize() { nodes_0_deserialized = nodes_0_deserialized_tmp; assert!(nodes_0_read.is_empty()); - assert!(nodes[0].chan_monitor.add_monitor(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok()); + assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok()); nodes[0].node = &nodes_0_deserialized; - nodes[0].block_notifier.register_listener(nodes[0].node); assert_eq!(nodes[0].node.list_channels().len(), 1); check_added_monitors!(nodes[0], 1); @@ -4383,10 +4382,11 @@ fn test_manager_serialize_deserialize_events() { let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let fee_estimator: test_utils::TestFeeEstimator; + let persister: test_utils::TestPersister; let logger: test_utils::TestLogger; - let new_chan_monitor: test_utils::TestChannelMonitor; + let new_chain_monitor: test_utils::TestChainMonitor; let keys_manager: test_utils::TestKeysInterface; - let nodes_0_deserialized: ChannelManager; + let nodes_0_deserialized: ChannelManager; let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); // Start creating a channel, but stop right before broadcasting the event message FundingBroadcastSafe @@ -4407,7 +4407,7 @@ fn test_manager_serialize_deserialize_events() { node_b.node.handle_funding_created(&node_a.node.get_our_node_id(), &get_event_msg!(node_a, MessageSendEvent::SendFundingCreated, node_b.node.get_our_node_id())); { - let mut added_monitors = node_b.chan_monitor.added_monitors.lock().unwrap(); + let mut added_monitors = node_b.chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); assert_eq!(added_monitors[0].0, funding_output); added_monitors.clear(); @@ -4415,7 +4415,7 @@ fn test_manager_serialize_deserialize_events() { node_a.node.handle_funding_signed(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendFundingSigned, node_a.node.get_our_node_id())); { - let mut added_monitors = node_a.chan_monitor.added_monitors.lock().unwrap(); + let mut added_monitors = node_a.chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); assert_eq!(added_monitors[0].0, funding_output); added_monitors.clear(); @@ -4428,12 +4428,13 @@ fn test_manager_serialize_deserialize_events() { // Start the de/seriailization process mid-channel creation to check that the channel manager will hold onto events that are serialized let nodes_0_serialized = nodes[0].node.encode(); let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new()); - nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap(); + nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap(); fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; logger = test_utils::TestLogger::new(); - new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator); - nodes[0].chan_monitor = &new_chan_monitor; + persister = test_utils::TestPersister{}; + new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister); + nodes[0].chain_monitor = &new_chain_monitor; let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..]; let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor)>::read(&mut chan_0_monitor_read).unwrap(); assert!(chan_0_monitor_read.is_empty()); @@ -4444,11 +4445,11 @@ fn test_manager_serialize_deserialize_events() { let (_, nodes_0_deserialized_tmp) = { let mut channel_monitors = HashMap::new(); channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor); - <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { default_config: config, keys_manager: &keys_manager, fee_estimator: &fee_estimator, - monitor: nodes[0].chan_monitor, + chain_monitor: nodes[0].chain_monitor, tx_broadcaster: nodes[0].tx_broadcaster.clone(), logger: &logger, channel_monitors, @@ -4459,7 +4460,7 @@ fn test_manager_serialize_deserialize_events() { nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - assert!(nodes[0].chan_monitor.add_monitor(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok()); + assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok()); nodes[0].node = &nodes_0_deserialized; // After deserializing, make sure the FundingBroadcastSafe event is still held by the channel manager @@ -4474,7 +4475,6 @@ fn test_manager_serialize_deserialize_events() { }; // Make sure the channel is functioning as though the de/serialization never happened - nodes[0].block_notifier.register_listener(nodes[0].node); assert_eq!(nodes[0].node.list_channels().len(), 1); check_added_monitors!(nodes[0], 1); @@ -4506,9 +4506,10 @@ fn test_simple_manager_serialize_deserialize() { let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let logger: test_utils::TestLogger; let fee_estimator: test_utils::TestFeeEstimator; - let new_chan_monitor: test_utils::TestChannelMonitor; + let persister: test_utils::TestPersister; + let new_chain_monitor: test_utils::TestChainMonitor; let keys_manager: test_utils::TestKeysInterface; - let nodes_0_deserialized: ChannelManager; + let nodes_0_deserialized: ChannelManager; let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); @@ -4519,12 +4520,13 @@ fn test_simple_manager_serialize_deserialize() { let nodes_0_serialized = nodes[0].node.encode(); let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new()); - nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap(); + nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap(); logger = test_utils::TestLogger::new(); fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; - new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator); - nodes[0].chan_monitor = &new_chan_monitor; + persister = test_utils::TestPersister{}; + new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister); + nodes[0].chain_monitor = &new_chain_monitor; let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..]; let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor)>::read(&mut chan_0_monitor_read).unwrap(); assert!(chan_0_monitor_read.is_empty()); @@ -4534,11 +4536,11 @@ fn test_simple_manager_serialize_deserialize() { let (_, nodes_0_deserialized_tmp) = { let mut channel_monitors = HashMap::new(); channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor); - <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { default_config: UserConfig::default(), keys_manager: &keys_manager, fee_estimator: &fee_estimator, - monitor: nodes[0].chan_monitor, + chain_monitor: nodes[0].chain_monitor, tx_broadcaster: nodes[0].tx_broadcaster.clone(), logger: &logger, channel_monitors, @@ -4547,7 +4549,7 @@ fn test_simple_manager_serialize_deserialize() { nodes_0_deserialized = nodes_0_deserialized_tmp; assert!(nodes_0_read.is_empty()); - assert!(nodes[0].chan_monitor.add_monitor(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok()); + assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok()); nodes[0].node = &nodes_0_deserialized; check_added_monitors!(nodes[0], 1); @@ -4565,16 +4567,17 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); let logger: test_utils::TestLogger; let fee_estimator: test_utils::TestFeeEstimator; - let new_chan_monitor: test_utils::TestChannelMonitor; + let persister: test_utils::TestPersister; + let new_chain_monitor: test_utils::TestChainMonitor; let keys_manager: test_utils::TestKeysInterface; - let nodes_0_deserialized: ChannelManager; + let nodes_0_deserialized: ChannelManager; let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs); create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); create_announced_chan_between_nodes(&nodes, 2, 0, InitFeatures::known(), InitFeatures::known()); let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3, InitFeatures::known(), InitFeatures::known()); let mut node_0_stale_monitors_serialized = Vec::new(); - for monitor in nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter() { + for monitor in nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter() { let mut writer = test_utils::TestVecWriter(Vec::new()); monitor.1.write_for_disk(&mut writer).unwrap(); node_0_stale_monitors_serialized.push(writer.0); @@ -4593,7 +4596,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { // Now the ChannelMonitor (which is now out-of-sync with ChannelManager for channel w/ // nodes[3]) let mut node_0_monitors_serialized = Vec::new(); - for monitor in nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter() { + for monitor in nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter() { let mut writer = test_utils::TestVecWriter(Vec::new()); monitor.1.write_for_disk(&mut writer).unwrap(); node_0_monitors_serialized.push(writer.0); @@ -4601,8 +4604,9 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { logger = test_utils::TestLogger::new(); fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; - new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator); - nodes[0].chan_monitor = &new_chan_monitor; + persister = test_utils::TestPersister{}; + new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister); + nodes[0].chain_monitor = &new_chain_monitor; let mut node_0_stale_monitors = Vec::new(); for serialized in node_0_stale_monitors_serialized.iter() { @@ -4624,11 +4628,11 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { let mut nodes_0_read = &nodes_0_serialized[..]; if let Err(msgs::DecodeError::InvalidValue) = - <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { default_config: UserConfig::default(), keys_manager: &keys_manager, fee_estimator: &fee_estimator, - monitor: nodes[0].chan_monitor, + chain_monitor: nodes[0].chain_monitor, tx_broadcaster: nodes[0].tx_broadcaster.clone(), logger: &logger, channel_monitors: node_0_stale_monitors.iter_mut().map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect(), @@ -4638,11 +4642,11 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { let mut nodes_0_read = &nodes_0_serialized[..]; let (_, nodes_0_deserialized_tmp) = - <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + <(BlockHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { default_config: UserConfig::default(), keys_manager: &keys_manager, fee_estimator: &fee_estimator, - monitor: nodes[0].chan_monitor, + chain_monitor: nodes[0].chain_monitor, tx_broadcaster: nodes[0].tx_broadcaster.clone(), logger: &logger, channel_monitors: node_0_monitors.iter_mut().map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect(), @@ -4658,7 +4662,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { } for monitor in node_0_monitors.drain(..) { - assert!(nodes[0].chan_monitor.add_monitor(monitor.get_funding_txo().0, monitor).is_ok()); + assert!(nodes[0].chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor).is_ok()); check_added_monitors!(nodes[0], 1); } nodes[0].node = &nodes_0_deserialized; @@ -4688,7 +4692,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { macro_rules! check_spendable_outputs { ($node: expr, $der_idx: expr, $keysinterface: expr, $chan_value: expr) => { { - let events = $node.chan_monitor.simple_monitor.get_and_clear_pending_events(); + let events = $node.chain_monitor.chain_monitor.get_and_clear_pending_events(); let mut txn = Vec::new(); for event in events { match event { @@ -4712,6 +4716,7 @@ macro_rules! check_spendable_outputs { input: vec![input], output: vec![outp], }; + spend_tx.output[0].value -= (spend_tx.get_weight() + 2 + 1 + 73 + 35 + 3) as u64 / 4; // (Max weight + 3 (to round up)) / 4 let secp_ctx = Secp256k1::new(); let keys = $keysinterface.derive_channel_keys($chan_value, key_derivation_params.0, key_derivation_params.1); let remotepubkey = keys.pubkeys().payment_point; @@ -4746,6 +4751,7 @@ macro_rules! check_spendable_outputs { let delayed_payment_pubkey = PublicKey::from_secret_key(&secp_ctx, &delayed_payment_key); let witness_script = chan_utils::get_revokeable_redeemscript(revocation_pubkey, *to_self_delay, &delayed_payment_pubkey); + spend_tx.output[0].value -= (spend_tx.get_weight() + 2 + 1 + 73 + 1 + witness_script.len() + 1 + 3) as u64 / 4; // (Max weight + 3 (to round up)) / 4 let sighash = Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(0, &witness_script, output.value, SigHashType::All)[..]).unwrap(); let local_delayedsig = secp_ctx.sign(&sighash, &delayed_payment_key); spend_tx.input[0].witness.push(local_delayedsig.serialize_der().to_vec()); @@ -4773,6 +4779,7 @@ macro_rules! check_spendable_outputs { input: vec![input], output: vec![outp.clone()], }; + spend_tx.output[0].value -= (spend_tx.get_weight() + 2 + 1 + 73 + 35 + 3) as u64 / 4; // (Max weight + 3 (to round up)) / 4 let secret = { match ExtendedPrivKey::new_master(Network::Testnet, &$node.node_seed) { Ok(master_key) => { @@ -4856,8 +4863,7 @@ fn test_claim_on_remote_sizeable_push_msat() { connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1, 1, true, header.block_hash()); let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000); - assert_eq!(spend_txn.len(), 2); - assert_eq!(spend_txn[0], spend_txn[1]); + assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], node_txn[0]); } @@ -4889,10 +4895,9 @@ fn test_claim_on_remote_revoked_sizeable_push_msat() { connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1, 1, true, header.block_hash()); let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000); - assert_eq!(spend_txn.len(), 3); - assert_eq!(spend_txn[0], spend_txn[1]); // to_remote output on revoked remote commitment_tx - check_spends!(spend_txn[0], revoked_local_txn[0]); - check_spends!(spend_txn[2], node_txn[0]); + assert_eq!(spend_txn.len(), 2); + check_spends!(spend_txn[0], revoked_local_txn[0]); // to_remote output on revoked remote commitment_tx + check_spends!(spend_txn[1], node_txn[0]); } #[test] @@ -4987,8 +4992,8 @@ fn test_static_spendable_outputs_timeout_tx() { expect_payment_failed!(nodes[1], our_payment_hash, true); let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000); - assert_eq!(spend_txn.len(), 3); // SpendableOutput: remote_commitment_tx.to_remote (*2), timeout_tx.output (*1) - check_spends!(spend_txn[2], node_txn[0].clone()); + assert_eq!(spend_txn.len(), 2); // SpendableOutput: remote_commitment_tx.to_remote, timeout_tx.output + check_spends!(spend_txn[1], node_txn[0]); } #[test] @@ -5163,12 +5168,11 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { // Check A's ChannelMonitor was able to generate the right spendable output descriptor let spend_txn = check_spendable_outputs!(nodes[0], 1, node_cfgs[0].keys_manager, 100000); - assert_eq!(spend_txn.len(), 3); // Duplicated SpendableOutput due to block rescan after revoked htlc output tracking - assert_eq!(spend_txn[0], spend_txn[1]); + assert_eq!(spend_txn.len(), 2); assert_eq!(spend_txn[0].input.len(), 1); check_spends!(spend_txn[0], revoked_local_txn[0]); // spending to_remote output from revoked local tx assert_ne!(spend_txn[0].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output); - check_spends!(spend_txn[2], node_txn[1]); // spending justice tx output on the htlc success tx + check_spends!(spend_txn[1], node_txn[1]); // spending justice tx output on the htlc success tx } #[test] @@ -5232,7 +5236,7 @@ fn test_onchain_to_onchain_claim() { assert_eq!(b_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); assert!(b_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output assert_ne!(b_txn[2].lock_time, 0); // Timeout tx - check_spends!(b_txn[0], c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor, * 2 due to block rescan + check_spends!(b_txn[0], c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert!(b_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment assert_ne!(b_txn[2].lock_time, 0); // Timeout tx @@ -5730,10 +5734,9 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor let spend_txn = check_spendable_outputs!(nodes[0], 1, node_cfgs[0].keys_manager, 100000); - assert_eq!(spend_txn.len(), 3); - assert_eq!(spend_txn[0], spend_txn[1]); + assert_eq!(spend_txn.len(), 2); check_spends!(spend_txn[0], local_txn[0]); - check_spends!(spend_txn[2], htlc_timeout); + check_spends!(spend_txn[1], htlc_timeout); } #[test] @@ -5747,8 +5750,8 @@ fn test_key_derivation_params() { // We manually create the node configuration to backup the seed. let seed = [42; 32]; let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet); - let chan_monitor = test_utils::TestChannelMonitor::new(&chanmon_cfgs[0].tx_broadcaster, &chanmon_cfgs[0].logger, &chanmon_cfgs[0].fee_estimator); - let node = NodeCfg { chain_monitor: &chanmon_cfgs[0].chain_monitor, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, chan_monitor, keys_manager, node_seed: seed }; + let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[0].chain_source), &chanmon_cfgs[0].tx_broadcaster, &chanmon_cfgs[0].logger, &chanmon_cfgs[0].fee_estimator, &chanmon_cfgs[0].persister); + let node = NodeCfg { chain_source: &chanmon_cfgs[0].chain_source, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, chain_monitor, keys_manager, node_seed: seed }; let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs); node_cfgs.remove(0); node_cfgs.insert(0, node); @@ -5801,10 +5804,9 @@ fn test_key_derivation_params() { // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor let new_keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet); let spend_txn = check_spendable_outputs!(nodes[0], 1, new_keys_manager, 100000); - assert_eq!(spend_txn.len(), 3); - assert_eq!(spend_txn[0], spend_txn[1]); + assert_eq!(spend_txn.len(), 2); check_spends!(spend_txn[0], local_txn_1[0]); - check_spends!(spend_txn[2], htlc_timeout); + check_spends!(spend_txn[1], htlc_timeout); } #[test] @@ -7163,60 +7165,6 @@ fn test_failure_delay_dust_htlc_local_commitment() { do_test_failure_delay_dust_htlc_local_commitment(false); } -#[test] -fn test_no_failure_dust_htlc_local_commitment() { - // Transaction filters for failing back dust htlc based on local commitment txn infos has been - // prone to error, we test here that a dummy transaction don't fail them. - - let chanmon_cfgs = create_chanmon_cfgs(2); - let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); - let nodes = create_network(2, &node_cfgs, &node_chanmgrs); - let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - - // Rebalance a bit - send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000); - - let as_dust_limit = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().holder_dust_limit_satoshis; - let bs_dust_limit = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().holder_dust_limit_satoshis; - - // We route 2 dust-HTLCs between A and B - let (preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000); - let (preimage_2, _) = route_payment(&nodes[1], &[&nodes[0]], as_dust_limit*1000); - - // Build a dummy invalid transaction trying to spend a commitment tx - let input = TxIn { - previous_output: BitcoinOutPoint { txid: chan.3.txid(), vout: 0 }, - script_sig: Script::new(), - sequence: 0, - witness: Vec::new(), - }; - - let outp = TxOut { - script_pubkey: Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), - value: 10000, - }; - - let dummy_tx = Transaction { - version: 2, - lock_time: 0, - input: vec![input], - output: vec![outp] - }; - - let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[0].chan_monitor.simple_monitor.block_connected(&header, &[(0, &dummy_tx)], 1); - assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); - assert_eq!(nodes[0].node.get_and_clear_pending_msg_events().len(), 0); - // We broadcast a few more block to check everything is all right - connect_blocks(&nodes[0], 20, 1, true, header.block_hash()); - assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); - assert_eq!(nodes[0].node.get_and_clear_pending_msg_events().len(), 0); - - claim_payment(&nodes[0], &vec!(&nodes[1])[..], preimage_1, bs_dust_limit*1000); - claim_payment(&nodes[1], &vec!(&nodes[0])[..], preimage_2, as_dust_limit*1000); -} - fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { // Outbound HTLC-failure updates must be cancelled if we get a reorg before we reach ANTI_REORG_DELAY. // Broadcast of revoked remote commitment tx, trigger failure-update of dust/non-dust HTLCs @@ -7467,10 +7415,11 @@ fn test_data_loss_protect() { // * we close channel in case of detecting other being fallen behind // * we are able to claim our own outputs thanks to to_remote being static let keys_manager; + let persister; let logger; let fee_estimator; let tx_broadcaster; - let chain_monitor; + let chain_source; let monitor; let node_state_0; let chanmon_cfgs = create_chanmon_cfgs(2); @@ -7482,8 +7431,8 @@ fn test_data_loss_protect() { // Cache node A state before any channel update let previous_node_state = nodes[0].node.encode(); - let mut previous_chan_monitor_state = test_utils::TestVecWriter(Vec::new()); - nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut previous_chan_monitor_state).unwrap(); + let mut previous_chain_monitor_state = test_utils::TestVecWriter(Vec::new()); + nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut previous_chain_monitor_state).unwrap(); send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000); send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000); @@ -7493,19 +7442,20 @@ fn test_data_loss_protect() { // Restore node A from previous state logger = test_utils::TestLogger::with_id(format!("node {}", 0)); - let mut chan_monitor = <(BlockHash, ChannelMonitor)>::read(&mut ::std::io::Cursor::new(previous_chan_monitor_state.0)).unwrap().1; - chain_monitor = ChainWatchInterfaceUtil::new(Network::Testnet); + let mut chain_monitor = <(BlockHash, ChannelMonitor)>::read(&mut ::std::io::Cursor::new(previous_chain_monitor_state.0)).unwrap().1; + chain_source = test_utils::TestChainSource::new(Network::Testnet); tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}; fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet); - monitor = test_utils::TestChannelMonitor::new(&tx_broadcaster, &logger, &fee_estimator); + persister = test_utils::TestPersister{}; + monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &fee_estimator, &persister); node_state_0 = { let mut channel_monitors = HashMap::new(); - channel_monitors.insert(OutPoint { txid: chan.3.txid(), index: 0 }, &mut chan_monitor); - <(BlockHash, ChannelManager)>::read(&mut ::std::io::Cursor::new(previous_node_state), ChannelManagerReadArgs { + channel_monitors.insert(OutPoint { txid: chan.3.txid(), index: 0 }, &mut chain_monitor); + <(BlockHash, ChannelManager)>::read(&mut ::std::io::Cursor::new(previous_node_state), ChannelManagerReadArgs { keys_manager: &keys_manager, fee_estimator: &fee_estimator, - monitor: &monitor, + chain_monitor: &monitor, logger: &logger, tx_broadcaster: &tx_broadcaster, default_config: UserConfig::default(), @@ -7513,13 +7463,9 @@ fn test_data_loss_protect() { }).unwrap().1 }; nodes[0].node = &node_state_0; - assert!(monitor.add_monitor(OutPoint { txid: chan.3.txid(), index: 0 }, chan_monitor).is_ok()); - nodes[0].chan_monitor = &monitor; - nodes[0].chain_monitor = &chain_monitor; - - nodes[0].block_notifier = BlockNotifier::new(); - nodes[0].block_notifier.register_listener(&nodes[0].chan_monitor.simple_monitor); - nodes[0].block_notifier.register_listener(nodes[0].node); + assert!(monitor.watch_channel(OutPoint { txid: chan.3.txid(), index: 0 }, chain_monitor).is_ok()); + nodes[0].chain_monitor = &monitor; + nodes[0].chain_source = &chain_source; check_added_monitors!(nodes[0], 1); @@ -8231,7 +8177,7 @@ fn test_bump_txn_sanitize_tracking_maps() { connect_block(&nodes[0], &Block { header: header_130, txdata: penalty_txn }, 130); connect_blocks(&nodes[0], 5, 130, false, header_130.block_hash()); { - let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap(); + let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap(); if let Some(monitor) = monitors.get(&OutPoint { txid: chan.3.txid(), index: 0 }) { assert!(monitor.onchain_tx_handler.pending_claim_requests.is_empty()); assert!(monitor.onchain_tx_handler.claimable_outpoints.is_empty()); @@ -8360,22 +8306,24 @@ fn test_update_err_monitor_lockdown() { // Route a HTLC from node 0 to node 1 (but don't settle) let preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9_000_000).0; - // Copy SimpleManyChannelMonitor to simulate a watchtower and update block height of node 0 until its ChannelMonitor timeout HTLC onchain + // Copy ChainMonitor to simulate a watchtower and update block height of node 0 until its ChannelMonitor timeout HTLC onchain + let chain_source = test_utils::TestChainSource::new(Network::Testnet); let logger = test_utils::TestLogger::with_id(format!("node {}", 0)); + let persister = test_utils::TestPersister::new(); let watchtower = { - let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap(); + let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap(); let monitor = monitors.get(&outpoint).unwrap(); let mut w = test_utils::TestVecWriter(Vec::new()); monitor.write_for_disk(&mut w).unwrap(); let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor)>::read( &mut ::std::io::Cursor::new(&w.0)).unwrap().1; assert!(new_monitor == *monitor); - let watchtower = test_utils::TestChannelMonitor::new(&chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator); - assert!(watchtower.add_monitor(outpoint, new_monitor).is_ok()); + let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister); + assert!(watchtower.watch_channel(outpoint, new_monitor).is_ok()); watchtower }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - watchtower.simple_monitor.block_connected(&header, &[], 200); + watchtower.chain_monitor.block_connected(&header, &[], 200); // Try to update ChannelMonitor assert!(nodes[1].node.claim_funds(preimage, &None, 9_000_000)); @@ -8385,8 +8333,8 @@ fn test_update_err_monitor_lockdown() { nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]); if let Some(ref mut channel) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2) { if let Ok((_, _, _, update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].fee_estimator, &node_cfgs[0].logger) { - if let Err(_) = watchtower.simple_monitor.update_monitor(outpoint, update.clone()) {} else { assert!(false); } - if let Ok(_) = nodes[0].chan_monitor.update_monitor(outpoint, update) {} else { assert!(false); } + if let Err(_) = watchtower.chain_monitor.update_channel(outpoint, update.clone()) {} else { assert!(false); } + if let Ok(_) = nodes[0].chain_monitor.update_channel(outpoint, update) {} else { assert!(false); } } else { assert!(false); } } else { assert!(false); }; // Our local monitor is in-sync and hasn't processed yet timeout @@ -8417,22 +8365,24 @@ fn test_concurrent_monitor_claim() { // Route a HTLC from node 0 to node 1 (but don't settle) route_payment(&nodes[0], &vec!(&nodes[1])[..], 9_000_000).0; - // Copy SimpleManyChannelMonitor to simulate watchtower Alice and update block height her ChannelMonitor timeout HTLC onchain + // Copy ChainMonitor to simulate watchtower Alice and update block height her ChannelMonitor timeout HTLC onchain + let chain_source = test_utils::TestChainSource::new(Network::Testnet); let logger = test_utils::TestLogger::with_id(format!("node {}", "Alice")); + let persister = test_utils::TestPersister::new(); let watchtower_alice = { - let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap(); + let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap(); let monitor = monitors.get(&outpoint).unwrap(); let mut w = test_utils::TestVecWriter(Vec::new()); monitor.write_for_disk(&mut w).unwrap(); let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor)>::read( &mut ::std::io::Cursor::new(&w.0)).unwrap().1; assert!(new_monitor == *monitor); - let watchtower = test_utils::TestChannelMonitor::new(&chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator); - assert!(watchtower.add_monitor(outpoint, new_monitor).is_ok()); + let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister); + assert!(watchtower.watch_channel(outpoint, new_monitor).is_ok()); watchtower }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - watchtower_alice.simple_monitor.block_connected(&header, &vec![], 135); + watchtower_alice.chain_monitor.block_connected(&header, &vec![], 135); // Watchtower Alice should have broadcast a commitment/HTLC-timeout { @@ -8441,22 +8391,24 @@ fn test_concurrent_monitor_claim() { txn.clear(); } - // Copy SimpleManyChannelMonitor to simulate watchtower Bob and make it receive a commitment update first. + // Copy ChainMonitor to simulate watchtower Bob and make it receive a commitment update first. + let chain_source = test_utils::TestChainSource::new(Network::Testnet); let logger = test_utils::TestLogger::with_id(format!("node {}", "Bob")); + let persister = test_utils::TestPersister::new(); let watchtower_bob = { - let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap(); + let monitors = nodes[0].chain_monitor.chain_monitor.monitors.lock().unwrap(); let monitor = monitors.get(&outpoint).unwrap(); let mut w = test_utils::TestVecWriter(Vec::new()); monitor.write_for_disk(&mut w).unwrap(); let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor)>::read( &mut ::std::io::Cursor::new(&w.0)).unwrap().1; assert!(new_monitor == *monitor); - let watchtower = test_utils::TestChannelMonitor::new(&chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator); - assert!(watchtower.add_monitor(outpoint, new_monitor).is_ok()); + let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister); + assert!(watchtower.watch_channel(outpoint, new_monitor).is_ok()); watchtower }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - watchtower_bob.simple_monitor.block_connected(&header, &vec![], 134); + watchtower_bob.chain_monitor.block_connected(&header, &vec![], 134); // Route another payment to generate another update with still previous HTLC pending let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]); @@ -8473,16 +8425,16 @@ fn test_concurrent_monitor_claim() { if let Some(ref mut channel) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2) { if let Ok((_, _, _, update)) = channel.commitment_signed(&updates.commitment_signed, &node_cfgs[0].fee_estimator, &node_cfgs[0].logger) { // Watchtower Alice should already have seen the block and reject the update - if let Err(_) = watchtower_alice.simple_monitor.update_monitor(outpoint, update.clone()) {} else { assert!(false); } - if let Ok(_) = watchtower_bob.simple_monitor.update_monitor(outpoint, update.clone()) {} else { assert!(false); } - if let Ok(_) = nodes[0].chan_monitor.update_monitor(outpoint, update) {} else { assert!(false); } + if let Err(_) = watchtower_alice.chain_monitor.update_channel(outpoint, update.clone()) {} else { assert!(false); } + if let Ok(_) = watchtower_bob.chain_monitor.update_channel(outpoint, update.clone()) {} else { assert!(false); } + if let Ok(_) = nodes[0].chain_monitor.update_channel(outpoint, update) {} else { assert!(false); } } else { assert!(false); } } else { assert!(false); }; // Our local monitor is in-sync and hasn't processed yet timeout check_added_monitors!(nodes[0], 1); //// Provide one more block to watchtower Bob, expect broadcast of commitment and HTLC-Timeout - watchtower_bob.simple_monitor.block_connected(&header, &vec![], 135); + watchtower_bob.chain_monitor.block_connected(&header, &vec![], 135); // Watchtower Bob should have broadcast a commitment/HTLC-timeout let bob_state_y; @@ -8494,7 +8446,7 @@ fn test_concurrent_monitor_claim() { }; // We confirm Bob's state Y on Alice, she should broadcast a HTLC-timeout - watchtower_alice.simple_monitor.block_connected(&header, &vec![(0, &bob_state_y)], 136); + watchtower_alice.chain_monitor.block_connected(&header, &vec![(0, &bob_state_y)], 136); { let htlc_txn = chanmon_cfgs[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); // We broadcast twice the transaction, once due to the HTLC-timeout, once due @@ -8504,3 +8456,50 @@ fn test_concurrent_monitor_claim() { check_spends!(htlc_txn[1], bob_state_y); } } + +#[test] +fn test_htlc_no_detection() { + // This test is a mutation to underscore the detection logic bug we had + // before #653. HTLC value routed is above the remaining balance, thus + // inverting HTLC and `to_remote` output. HTLC will come second and + // it wouldn't be seen by pre-#653 detection as we were enumerate()'ing + // on a watched outputs vector (Vec) thus implicitly relying on + // outputs order detection for correct spending children filtring. + + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + // Create some initial channels + let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known()); + + send_payment(&nodes[0], &vec!(&nodes[1])[..], 1_000_000, 1_000_000); + let (_, our_payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 2_000_000); + let local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); + assert_eq!(local_txn[0].input.len(), 1); + assert_eq!(local_txn[0].output.len(), 3); + check_spends!(local_txn[0], chan_1.3); + + // Timeout HTLC on A's chain and so it can generate a HTLC-Timeout tx + let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + connect_block(&nodes[0], &Block { header, txdata: vec![local_txn[0].clone()] }, 200); + // We deliberately connect the local tx twice as this should provoke a failure calling + // this test before #653 fix. + connect_block(&nodes[0], &Block { header, txdata: vec![local_txn[0].clone()] }, 200); + check_closed_broadcast!(nodes[0], false); + check_added_monitors!(nodes[0], 1); + + let htlc_timeout = { + let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(node_txn[0].input.len(), 1); + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[0], local_txn[0]); + node_txn[0].clone() + }; + + let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + connect_block(&nodes[0], &Block { header: header_201, txdata: vec![htlc_timeout.clone()] }, 201); + connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1, 201, true, header_201.block_hash()); + expect_payment_failed!(nodes[0], our_payment_hash, true); +}