X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=de6488d144e65f437e6e57c6d47c23182393e462;hb=1508253bf081db5e57d9ee3256553dd623f889da;hp=e00e036db53478279dcc8abf4e79af660f519d62;hpb=e1c1ac7576bb74678d65b34b19cd091fc0bb371e;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index e00e036d..de6488d1 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -3839,6 +3839,13 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { create_announced_chan_between_nodes(&nodes, 2, 0, InitFeatures::supported(), InitFeatures::supported()); let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3, InitFeatures::supported(), InitFeatures::supported()); + let mut node_0_stale_monitors_serialized = Vec::new(); + for monitor in nodes[0].chan_monitor.simple_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); + } + let (our_payment_preimage, _) = route_payment(&nodes[2], &[&nodes[0], &nodes[1]], 1000000); // Serialize the ChannelManager here, but the monitor we keep up-to-date @@ -3861,6 +3868,15 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new()), &fee_estimator); nodes[0].chan_monitor = &new_chan_monitor; + + let mut node_0_stale_monitors = Vec::new(); + for serialized in node_0_stale_monitors_serialized.iter() { + let mut read = &serialized[..]; + let (_, monitor) = <(Sha256dHash, ChannelMonitor)>::read(&mut read, Arc::new(test_utils::TestLogger::new())).unwrap(); + assert!(read.is_empty()); + node_0_stale_monitors.push(monitor); + } + let mut node_0_monitors = Vec::new(); for serialized in node_0_monitors_serialized.iter() { let mut read = &serialized[..]; @@ -3869,9 +3885,25 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { node_0_monitors.push(monitor); } - let mut nodes_0_read = &nodes_0_serialized[..]; keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())); - let (_, nodes_0_deserialized_tmp) = <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + + let mut nodes_0_read = &nodes_0_serialized[..]; + if let Err(msgs::DecodeError::InvalidValue) = + <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { + default_config: UserConfig::default(), + keys_manager: &keys_manager, + fee_estimator: &fee_estimator, + monitor: nodes[0].chan_monitor, + tx_broadcaster: nodes[0].tx_broadcaster.clone(), + logger: Arc::new(test_utils::TestLogger::new()), + channel_monitors: &mut node_0_stale_monitors.iter_mut().map(|monitor| { (monitor.get_funding_txo().unwrap(), monitor) }).collect(), + }) { } else { + panic!("If the monitor(s) are stale, this indicates a bug and we should get an Err return"); + }; + + let mut nodes_0_read = &nodes_0_serialized[..]; + let (_, nodes_0_deserialized_tmp) = + <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs { default_config: UserConfig::default(), keys_manager: &keys_manager, fee_estimator: &fee_estimator, @@ -3977,7 +4009,7 @@ macro_rules! check_spendable_outputs { let local_delaysig = secp_ctx.sign(&sighash, key); spend_tx.input[0].witness.push(local_delaysig.serialize_der().to_vec()); spend_tx.input[0].witness[0].push(SigHashType::All as u8); - spend_tx.input[0].witness.push(vec!(0)); + spend_tx.input[0].witness.push(vec!()); spend_tx.input[0].witness.push(witness_script.clone().into_bytes()); txn.push(spend_tx); }, @@ -4049,6 +4081,8 @@ fn test_claim_sizeable_push_msat() { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], node_txn[0]); @@ -4077,6 +4111,8 @@ fn test_claim_on_remote_sizeable_push_msat() { nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); check_added_monitors!(nodes[1], 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 2); assert_eq!(spend_txn[0], spend_txn[1]); @@ -4100,17 +4136,21 @@ fn test_claim_on_remote_revoked_sizeable_push_msat() { assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid()); claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 3_000_000); - let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); + let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 3); - assert_eq!(spend_txn[0], spend_txn[2]); // to_remote output on revoked remote commitment_tx + 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[1], node_txn[0]); + check_spends!(spend_txn[2], node_txn[0]); } #[test] @@ -4150,15 +4190,72 @@ fn test_static_spendable_outputs_preimage_tx() { assert_eq!(node_txn.len(), 3); check_spends!(node_txn[0], commitment_tx[0]); assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); -eprintln!("{:?}", node_txn[1]); check_spends!(node_txn[1], chan_1.3); check_spends!(node_txn[2], node_txn[1]); - let spend_txn = check_spendable_outputs!(nodes[1], 1); // , 0, 0, 1, 1); + let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + + let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], node_txn[0]); } +#[test] +fn test_static_spendable_outputs_timeout_tx() { + 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(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); + + // Rebalance the network a bit by relaying one payment through all the channels ... + send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000); + + let (_, our_payment_hash) = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3_000_000); + + let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); + assert_eq!(commitment_tx[0].input.len(), 1); + assert_eq!(commitment_tx[0].input[0].previous_output.txid, chan_1.3.txid()); + + // Settle A's commitment tx on B' chain + let header = BlockHeader { version: 0x2000_0000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()] }, 0); + check_added_monitors!(nodes[1], 1); + let events = nodes[1].node.get_and_clear_pending_msg_events(); + match events[0] { + MessageSendEvent::BroadcastChannelUpdate { .. } => {}, + _ => panic!("Unexpected event"), + } + + // Check B's monitor was able to send back output descriptor event for timeout tx on A's commitment tx + let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(node_txn.len(), 3); // ChannelManager : 2 (local commitent tx + HTLC-timeout), ChannelMonitor: timeout tx + check_spends!(node_txn[0], commitment_tx[0].clone()); + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[1], chan_1.3.clone()); + check_spends!(node_txn[2], node_txn[1]); + + let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + let events = nodes[1].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PaymentFailed { payment_hash, .. } => { + assert_eq!(payment_hash, our_payment_hash); + }, + _ => panic!("Unexpected event"), + } + + let spend_txn = check_spendable_outputs!(nodes[1], 1); + 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()); +} + #[test] fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() { let chanmon_cfgs = create_chanmon_cfgs(2); @@ -4177,7 +4274,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() { claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage, 3_000_000); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); check_added_monitors!(nodes[1], 1); @@ -4186,6 +4283,10 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() { assert_eq!(node_txn[0].input.len(), 2); check_spends!(node_txn[0], revoked_local_txn[0]); + let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone()] }, 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], node_txn[0]); @@ -4223,7 +4324,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { check_spends!(revoked_htlc_txn[1], chan_1.3); // B will generate justice tx from A's revoked commitment/HTLC tx - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1); + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 0); check_closed_broadcast!(nodes[1], false); check_added_monitors!(nodes[1], 1); @@ -4237,6 +4338,10 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { assert_eq!(node_txn[3].input.len(), 1); check_spends!(node_txn[3], revoked_local_txn[0]); + let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone(), node_txn[2].clone()] }, 1); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + // Check B's ChannelMonitor was able to generate the right spendable output descriptor let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 2); @@ -4284,13 +4389,18 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { assert_eq!(node_txn[2].input.len(), 1); check_spends!(node_txn[2], revoked_htlc_txn[0]); + let header_1 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[0].block_notifier.block_connected(&Block { header: header_1, txdata: vec![node_txn[0].clone(), node_txn[2].clone()] }, 1); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash()); + // Check A's ChannelMonitor was able to generate the right spendable output descriptor let spend_txn = check_spendable_outputs!(nodes[0], 1); assert_eq!(spend_txn.len(), 5); // Duplicated SpendableOutput due to block rescan after revoked htlc output tracking + assert_eq!(spend_txn[0], spend_txn[1]); assert_eq!(spend_txn[0], spend_txn[2]); check_spends!(spend_txn[0], revoked_local_txn[0]); // spending to_remote output from revoked local tx - check_spends!(spend_txn[1], node_txn[0]); // spending justice tx output from revoked local tx htlc received output - check_spends!(spend_txn[3], node_txn[2]); // spending justice tx output on htlc success tx + check_spends!(spend_txn[3], node_txn[0]); // spending justice tx output from revoked local tx htlc received output + check_spends!(spend_txn[4], node_txn[2]); // spending justice tx output on htlc success tx } #[test] @@ -4548,16 +4658,23 @@ fn test_dynamic_spendable_outputs_local_htlc_success_tx() { MessageSendEvent::BroadcastChannelUpdate { .. } => {}, _ => panic!("Unexepected event"), } - let node_txn = nodes[1].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(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0]); + let node_txn = { + let node_txn = nodes[1].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(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[0], local_txn[0]); + vec![node_txn[0].clone(), node_txn[2].clone()] + }; + + let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[1].block_notifier.block_connected(&Block { header: header_201, txdata: node_txn.clone() }, 201); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash()); // Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 2); check_spends!(spend_txn[0], node_txn[0]); - check_spends!(spend_txn[1], node_txn[2]); + check_spends!(spend_txn[1], node_txn[1]); } fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, announce_latest: bool) { @@ -4823,7 +4940,7 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { // Create some initial channels let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::supported(), InitFeatures::supported()); - route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0; + let (_, our_payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000); let local_txn = get_local_commitment_txn!(nodes[0], chan_1.2); assert_eq!(local_txn[0].input.len(), 1); check_spends!(local_txn[0], chan_1.3); @@ -4834,22 +4951,32 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { check_closed_broadcast!(nodes[0], false); check_added_monitors!(nodes[0], 1); - 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]); + 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.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[0].block_notifier.block_connected(&Block { header: header_201, txdata: vec![htlc_timeout.clone()] }, 201); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 201, true, header_201.bitcoin_hash()); + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PaymentFailed { payment_hash, .. } => { + assert_eq!(payment_hash, our_payment_hash); + }, + _ => panic!("Unexpected event"), + } // 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); - assert_eq!(spend_txn.len(), 8); - assert_eq!(spend_txn[0], spend_txn[2]); - assert_eq!(spend_txn[0], spend_txn[4]); - assert_eq!(spend_txn[0], spend_txn[6]); - assert_eq!(spend_txn[1], spend_txn[3]); - assert_eq!(spend_txn[1], spend_txn[5]); - assert_eq!(spend_txn[1], spend_txn[7]); + assert_eq!(spend_txn.len(), 3); + assert_eq!(spend_txn[0], spend_txn[1]); check_spends!(spend_txn[0], local_txn[0]); - check_spends!(spend_txn[1], node_txn[0]); + check_spends!(spend_txn[2], htlc_timeout); } #[test] @@ -4865,12 +4992,16 @@ fn test_static_output_closing_tx() { let closing_tx = close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true).2; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1); + nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[0], 2); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], closing_tx); - nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1); + nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 0); + connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash()); + let spend_txn = check_spendable_outputs!(nodes[1], 2); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], closing_tx); @@ -6722,7 +6853,8 @@ fn test_data_loss_protect() { check_spends!(node_txn[0], chan.3); assert_eq!(node_txn[0].output.len(), 2); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; - nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 1); + nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 0); + connect_blocks(&nodes[0].block_notifier, ANTI_REORG_DELAY - 1, 0, true, header.bitcoin_hash()); let spend_txn = check_spendable_outputs!(nodes[0], 1); assert_eq!(spend_txn.len(), 1); check_spends!(spend_txn[0], node_txn[0]);