X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fln%2Ffunctional_tests.rs;h=c98ef2e2e1471580cbb80f88b1540fceb2961636;hb=4cc7d5d5274edc2e28ffc5e83228dbcaa4a935bb;hp=3a8e3b8619d94bc2eba717fc0f754b2ac4bebf9d;hpb=93fd3e8bb95b23fa6929dc201cff928892f34d55;p=rust-lightning diff --git a/src/ln/functional_tests.rs b/src/ln/functional_tests.rs index 3a8e3b86..c98ef2e2 100644 --- a/src/ln/functional_tests.rs +++ b/src/ln/functional_tests.rs @@ -21,6 +21,7 @@ use util::errors::APIError; use util::logger::Logger; use util::ser::{Writeable, Writer, ReadableArgs}; use util::config::UserConfig; +use util::rng; use bitcoin::util::hash::{BitcoinHash, Sha256dHash}; use bitcoin::util::bip143; @@ -50,11 +51,12 @@ use std::sync::atomic::Ordering; use std::time::Instant; use std::mem; +const CHAN_CONFIRM_DEPTH: u32 = 100; fn confirm_transaction(chain: &chaininterface::ChainWatchInterfaceUtil, tx: &Transaction, chan_id: u32) { assert!(chain.does_match_tx(tx)); let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; chain.block_connected_checked(&header, 1, &[tx; 1], &[chan_id; 1]); - for i in 2..100 { + for i in 2..CHAN_CONFIRM_DEPTH { header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; chain.block_connected_checked(&header, i, &[tx; 0], &[0; 0]); } @@ -1967,19 +1969,33 @@ fn get_announce_close_broadcast_events(nodes: &Vec, a: usize, b: usize) { } } +macro_rules! expect_payment_received { + ($node: expr, $expected_payment_hash: expr, $expected_recv_value: expr) => { + let events = $node.node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PaymentReceived { ref payment_hash, amt } => { + assert_eq!($expected_payment_hash, *payment_hash); + assert_eq!($expected_recv_value, amt); + }, + _ => panic!("Unexpected event"), + } + } +} + +macro_rules! get_channel_value_stat { + ($node: expr, $channel_id: expr) => {{ + let chan_lock = $node.node.channel_state.lock().unwrap(); + let chan = chan_lock.by_id.get(&$channel_id).unwrap(); + chan.get_value_stat() + }} +} + fn do_channel_reserve_test(test_recv: bool) { use util::rng; use std::sync::atomic::Ordering; use ln::msgs::HandleError; - macro_rules! get_channel_value_stat { - ($node: expr, $channel_id: expr) => {{ - let chan_lock = $node.node.channel_state.lock().unwrap(); - let chan = chan_lock.by_id.get(&$channel_id).unwrap(); - chan.get_value_stat() - }} - } - let mut nodes = create_network(3); let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1900, 1001); let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1900, 1001); @@ -2008,20 +2024,6 @@ fn do_channel_reserve_test(test_recv: bool) { }} } - macro_rules! expect_payment_received { - ($node: expr, $expected_payment_hash: expr, $expected_recv_value: expr) => { - let events = $node.node.get_and_clear_pending_events(); - assert_eq!(events.len(), 1); - match events[0] { - Event::PaymentReceived { ref payment_hash, amt } => { - assert_eq!($expected_payment_hash, *payment_hash); - assert_eq!($expected_recv_value, amt); - }, - _ => panic!("Unexpected event"), - } - } - }; - let feemsat = 239; // somehow we know? let total_fee_msat = (nodes.len() - 2) as u64 * 239; @@ -2105,7 +2107,7 @@ fn do_channel_reserve_test(test_recv: bool) { // Need to manually create update_add_htlc message to go around the channel reserve check in send_htlc() let secp_ctx = Secp256k1::new(); - let session_priv = SecretKey::from_slice(&secp_ctx, &{ + let session_priv = SecretKey::from_slice(&{ let mut session_key = [0; 32]; rng::fill_bytes(&mut session_key); session_key @@ -2648,14 +2650,15 @@ fn test_htlc_on_chain_success() { // Test that in case of an unilateral close onchain, we detect the state of output thanks to // ChainWatchInterface and pass the preimage backward accordingly. So here we test that ChannelManager is // broadcasting the right event to other nodes in payment path. + // We test with two HTLCs simultaneously as that was not handled correctly in the past. // A --------------------> B ----------------------> C (preimage) - // First, C should claim the HTLC output via HTLC-Success when its own latest local + // First, C should claim the HTLC outputs via HTLC-Success when its own latest local // commitment transaction was broadcast. // Then, B should learn the preimage from said transactions, attempting to claim backwards // towards B. // B should be able to claim via preimage if A then broadcasts its local tx. // Finally, when A sees B's latest local commitment transaction it should be able to claim - // the HTLC output via the preimage it learned (which, once confirmed should generate a + // the HTLC outputs via the preimage it learned (which, once confirmed should generate a // PaymentSent event). let nodes = create_network(3); @@ -2669,6 +2672,7 @@ fn test_htlc_on_chain_success() { send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); let (our_payment_preimage, _payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), 3000000); + let (our_payment_preimage_2, _payment_hash_2) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), 3000000); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; // Broadcast legit commitment tx from C on B's chain @@ -2677,7 +2681,8 @@ fn test_htlc_on_chain_success() { assert_eq!(commitment_tx.len(), 1); check_spends!(commitment_tx[0], chan_2.3.clone()); nodes[2].node.claim_funds(our_payment_preimage); - check_added_monitors!(nodes[2], 1); + nodes[2].node.claim_funds(our_payment_preimage_2); + check_added_monitors!(nodes[2], 2); let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id()); assert!(updates.update_add_htlcs.is_empty()); assert!(updates.update_fail_htlcs.is_empty()); @@ -2686,22 +2691,28 @@ fn test_htlc_on_chain_success() { nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1); check_closed_broadcast!(nodes[2]); - let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 (commitment tx), ChannelMonitor : 2 (2 * HTLC-Success tx) - assert_eq!(node_txn.len(), 3); - assert_eq!(node_txn[1], commitment_tx[0]); - assert_eq!(node_txn[0], node_txn[2]); + let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 (commitment tx), ChannelMonitor : 4 (2*2 * HTLC-Success tx) + assert_eq!(node_txn.len(), 5); + assert_eq!(node_txn[0], node_txn[3]); + assert_eq!(node_txn[1], node_txn[4]); + assert_eq!(node_txn[2], commitment_tx[0]); check_spends!(node_txn[0], commitment_tx[0].clone()); + check_spends!(node_txn[1], commitment_tx[0].clone()); assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output assert_eq!(node_txn[0].lock_time, 0); + assert_eq!(node_txn[1].lock_time, 0); // Verify that B's ChannelManager is able to extract preimage from HTLC Success tx and pass it backward nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: node_txn}, 1); let events = nodes[1].node.get_and_clear_pending_msg_events(); { let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); + 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()); added_monitors.clear(); } assert_eq!(events.len(), 2); @@ -2719,25 +2730,45 @@ fn test_htlc_on_chain_success() { }, _ => panic!("Unexpected event"), }; - { - // nodes[1] now broadcasts its own local state as a fallback, suggesting an alternate - // commitment transaction with a corresponding HTLC-Timeout transaction, as well as a - // timeout-claim of the output that nodes[2] just claimed via success. - let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 (timeout tx) * 2 (block-rescan) - assert_eq!(node_txn.len(), 4); - assert_eq!(node_txn[0], node_txn[3]); - check_spends!(node_txn[0], commitment_tx[0].clone()); - assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert_ne!(node_txn[0].lock_time, 0); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment - check_spends!(node_txn[1], chan_2.3.clone()); - check_spends!(node_txn[2], node_txn[1].clone()); - assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71); - assert_eq!(node_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert_ne!(node_txn[2].lock_time, 0); - node_txn.clear(); - } + macro_rules! check_tx_local_broadcast { + ($node: expr, $htlc_offered: expr, $commitment_tx: expr, $chan_tx: expr) => { { + // ChannelManager : 3 (commitment tx, 2*HTLC-Timeout tx), ChannelMonitor : 2 (timeout tx) * 2 (block-rescan) + let mut node_txn = $node.tx_broadcaster.txn_broadcasted.lock().unwrap(); + assert_eq!(node_txn.len(), 7); + assert_eq!(node_txn[0], node_txn[5]); + assert_eq!(node_txn[1], node_txn[6]); + check_spends!(node_txn[0], $commitment_tx.clone()); + check_spends!(node_txn[1], $commitment_tx.clone()); + assert_ne!(node_txn[0].lock_time, 0); + assert_ne!(node_txn[1].lock_time, 0); + if $htlc_offered { + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + } else { + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + } + check_spends!(node_txn[2], $chan_tx.clone()); + check_spends!(node_txn[3], node_txn[2].clone()); + check_spends!(node_txn[4], node_txn[2].clone()); + assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), 71); + assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[4].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert!(node_txn[3].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert!(node_txn[4].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert_ne!(node_txn[3].lock_time, 0); + assert_ne!(node_txn[4].lock_time, 0); + node_txn.clear(); + } } + } + // nodes[1] now broadcasts its own local state as a fallback, suggesting an alternate + // commitment transaction with a corresponding HTLC-Timeout transactions, as well as a + // timeout-claim of the output that nodes[2] just claimed via success. + check_tx_local_broadcast!(nodes[1], false, commitment_tx[0], chan_2.3); // Broadcast legit commitment tx from A on B's chain // Broadcast preimage tx by B on offered output from A commitment tx on A's chain @@ -2749,7 +2780,9 @@ fn test_htlc_on_chain_success() { assert_eq!(node_txn.len(), 3); assert_eq!(node_txn[0], node_txn[2]); check_spends!(node_txn[0], commitment_tx[0].clone()); - assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[0].input.len(), 2); + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[0].input[1].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[0].lock_time, 0); assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment check_spends!(node_txn[1], chan_1.3.clone()); @@ -2761,26 +2794,22 @@ fn test_htlc_on_chain_success() { nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone(), node_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[0]); let events = nodes[0].node.get_and_clear_pending_events(); - assert_eq!(events.len(), 1); - match events[0] { - Event::PaymentSent { payment_preimage } => { - assert_eq!(payment_preimage, our_payment_preimage); - }, - _ => panic!("Unexpected event"), + assert_eq!(events.len(), 2); + let mut first_claimed = false; + for event in events { + match event { + Event::PaymentSent { payment_preimage } => { + if payment_preimage == our_payment_preimage { + assert!(!first_claimed); + first_claimed = true; + } else { + assert_eq!(payment_preimage, our_payment_preimage_2); + } + }, + _ => panic!("Unexpected event"), + } } - let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 (HTLC-Timeout tx) * 2 (block-rescan) - assert_eq!(node_txn.len(), 4); - assert_eq!(node_txn[0], node_txn[3]); - check_spends!(node_txn[0], commitment_tx[0].clone()); - assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_ne!(node_txn[0].lock_time, 0); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - check_spends!(node_txn[1], chan_1.3.clone()); - check_spends!(node_txn[2], node_txn[1].clone()); - assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71); - assert_eq!(node_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert_ne!(node_txn[2].lock_time, 0); + check_tx_local_broadcast!(nodes[0], true, commitment_tx[0], chan_1.3); } #[test] @@ -2951,7 +2980,7 @@ fn test_simple_commitment_revoked_fail_backward() { } } -fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) { +fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use_dust: bool, no_to_remote: bool) { // Test that if our counterparty broadcasts a revoked commitment transaction we fail all // pending HTLCs on that channel backwards even if the HTLCs aren't present in our latest // commitment transaction anymore. @@ -2973,15 +3002,22 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) { create_announced_chan_between_nodes(&nodes, 0, 1); let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2); - let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000); + let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], if no_to_remote { 10_000 } else { 3_000_000 }); // Get the will-be-revoked local txn from nodes[2] let revoked_local_txn = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone(); + assert_eq!(revoked_local_txn[0].output.len(), if no_to_remote { 1 } else { 2 }); // Revoke the old state claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage); - let (_, first_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000); - let (_, second_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000); - let (_, third_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000); + let value = if use_dust { + // The dust limit applied to HTLC outputs considers the fee of the HTLC transaction as + // well, so HTLCs at exactly the dust limit will not be included in commitment txn. + nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().our_dust_limit_satoshis * 1000 + } else { 3000000 }; + + let (_, first_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value); + let (_, second_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value); + let (_, third_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value); assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash, 0)); expect_pending_htlcs_forwardable!(nodes[2]); @@ -3043,8 +3079,8 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) { if deliver_bs_raa { nodes[1].node.handle_revoke_and_ack(&nodes[2].node.get_our_node_id(), &bs_raa).unwrap(); - // One monitor for the new revocation preimage, one as we generate a commitment for - // nodes[0] to fail first_payment_hash backwards. + // One monitor for the new revocation preimage, no second on as we won't generate a new + // commitment transaction for nodes[0] until process_pending_htlc_forwards(). check_added_monitors!(nodes[1], 1); let events = nodes[1].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); @@ -3152,9 +3188,19 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) { } #[test] -fn test_commitment_revoked_fail_backward_exhaustive() { - do_test_commitment_revoked_fail_backward_exhaustive(false); - do_test_commitment_revoked_fail_backward_exhaustive(true); +fn test_commitment_revoked_fail_backward_exhaustive_a() { + do_test_commitment_revoked_fail_backward_exhaustive(false, true, false); + do_test_commitment_revoked_fail_backward_exhaustive(true, true, false); + do_test_commitment_revoked_fail_backward_exhaustive(false, false, false); + do_test_commitment_revoked_fail_backward_exhaustive(true, false, false); +} + +#[test] +fn test_commitment_revoked_fail_backward_exhaustive_b() { + do_test_commitment_revoked_fail_backward_exhaustive(false, true, true); + do_test_commitment_revoked_fail_backward_exhaustive(true, true, true); + do_test_commitment_revoked_fail_backward_exhaustive(false, false, true); + do_test_commitment_revoked_fail_backward_exhaustive(true, false, true); } #[test] @@ -5124,7 +5170,7 @@ macro_rules! check_spendable_outputs { witness: Vec::new(), }; let outp = TxOut { - script_pubkey: Builder::new().push_opcode(opcodes::All::OP_RETURN).into_script(), + script_pubkey: Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), value: output.value, }; let mut spend_tx = Transaction { @@ -5138,7 +5184,7 @@ macro_rules! check_spendable_outputs { let witness_script = Address::p2pkh(&remotepubkey, Network::Testnet).script_pubkey(); let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap(); let remotesig = secp_ctx.sign(&sighash, key); - spend_tx.input[0].witness.push(remotesig.serialize_der(&secp_ctx).to_vec()); + spend_tx.input[0].witness.push(remotesig.serialize_der().to_vec()); spend_tx.input[0].witness[0].push(SigHashType::All as u8); spend_tx.input[0].witness.push(remotepubkey.serialize().to_vec()); txn.push(spend_tx); @@ -5151,7 +5197,7 @@ macro_rules! check_spendable_outputs { witness: Vec::new(), }; let outp = TxOut { - script_pubkey: Builder::new().push_opcode(opcodes::All::OP_RETURN).into_script(), + script_pubkey: Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), value: output.value, }; let mut spend_tx = Transaction { @@ -5163,7 +5209,7 @@ macro_rules! check_spendable_outputs { let secp_ctx = Secp256k1::new(); let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], witness_script, output.value)[..]).unwrap(); let local_delaysig = secp_ctx.sign(&sighash, key); - spend_tx.input[0].witness.push(local_delaysig.serialize_der(&secp_ctx).to_vec()); + 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(witness_script.clone().into_bytes()); @@ -5178,7 +5224,7 @@ macro_rules! check_spendable_outputs { witness: Vec::new(), }; let outp = TxOut { - script_pubkey: Builder::new().push_opcode(opcodes::All::OP_RETURN).into_script(), + script_pubkey: Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script(), value: output.value, }; let mut spend_tx = Transaction { @@ -5188,7 +5234,7 @@ macro_rules! check_spendable_outputs { output: vec![outp.clone()], }; let secret = { - match ExtendedPrivKey::new_master(&secp_ctx, Network::Testnet, &$node.node_seed) { + match ExtendedPrivKey::new_master(Network::Testnet, &$node.node_seed) { Ok(master_key) => { match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx($der_idx)) { Ok(key) => key, @@ -5202,7 +5248,7 @@ macro_rules! check_spendable_outputs { let witness_script = Address::p2pkh(&pubkey, Network::Testnet).script_pubkey(); let sighash = Message::from_slice(&bip143::SighashComponents::new(&spend_tx).sighash_all(&spend_tx.input[0], &witness_script, output.value)[..]).unwrap(); let sig = secp_ctx.sign(&sighash, &secret.secret_key); - spend_tx.input[0].witness.push(sig.serialize_der(&secp_ctx).to_vec()); + spend_tx.input[0].witness.push(sig.serialize_der().to_vec()); spend_tx.input[0].witness[0].push(SigHashType::All as u8); spend_tx.input[0].witness.push(pubkey.serialize().to_vec()); txn.push(spend_tx); @@ -6002,6 +6048,146 @@ fn test_static_output_closing_tx() { check_spends!(spend_txn[0], closing_tx); } +fn do_htlc_claim_local_commitment_only(use_dust: bool) { + let nodes = create_network(2); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + + let (our_payment_preimage, _) = route_payment(&nodes[0], &[&nodes[1]], if use_dust { 50000 } else { 3000000 }); + + // Claim the payment, but don't deliver A's commitment_signed, resulting in the HTLC only being + // present in B's local commitment transaction, but none of A's commitment transactions. + assert!(nodes[1].node.claim_funds(our_payment_preimage)); + check_added_monitors!(nodes[1], 1); + + let bs_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); + nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &bs_updates.update_fulfill_htlcs[0]).unwrap(); + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PaymentSent { payment_preimage } => { + assert_eq!(payment_preimage, our_payment_preimage); + }, + _ => panic!("Unexpected event"), + } + + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_updates.commitment_signed).unwrap(); + check_added_monitors!(nodes[0], 1); + let as_updates = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_updates.0).unwrap(); + check_added_monitors!(nodes[1], 1); + + let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + for i in 1..TEST_FINAL_CLTV - CLTV_CLAIM_BUFFER + CHAN_CONFIRM_DEPTH + 1 { + nodes[1].chain_monitor.block_connected_checked(&header, i, &Vec::new(), &Vec::new()); + header.prev_blockhash = header.bitcoin_hash(); + } + test_txn_broadcast(&nodes[1], &chan, None, if use_dust { HTLCType::NONE } else { HTLCType::SUCCESS }); + check_closed_broadcast!(nodes[1]); +} + +fn do_htlc_claim_current_remote_commitment_only(use_dust: bool) { + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), if use_dust { 50000 } else { 3000000 }, TEST_FINAL_CLTV).unwrap(); + let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[0].node.send_payment(route, payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + + let _as_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + + // As far as A is concerened, the HTLC is now present only in the latest remote commitment + // transaction, however it is not in A's latest local commitment, so we can just broadcast that + // to "time out" the HTLC. + + let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + for i in 1..TEST_FINAL_CLTV + HTLC_FAIL_TIMEOUT_BLOCKS + CHAN_CONFIRM_DEPTH + 1 { + nodes[0].chain_monitor.block_connected_checked(&header, i, &Vec::new(), &Vec::new()); + header.prev_blockhash = header.bitcoin_hash(); + } + test_txn_broadcast(&nodes[0], &chan, None, HTLCType::NONE); + check_closed_broadcast!(nodes[0]); +} + +fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no_close: bool) { + let nodes = create_network(3); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + + // Fail the payment, but don't deliver A's final RAA, resulting in the HTLC only being present + // in B's previous (unrevoked) commitment transaction, but none of A's commitment transactions. + // Also optionally test that we *don't* fail the channel in case the commitment transaction was + // actually revoked. + let htlc_value = if use_dust { 50000 } else { 3000000 }; + let (_, our_payment_hash) = route_payment(&nodes[0], &[&nodes[1]], htlc_value); + assert!(nodes[1].node.fail_htlc_backwards(&our_payment_hash, htlc_value)); + expect_pending_htlcs_forwardable!(nodes[1]); + check_added_monitors!(nodes[1], 1); + + let bs_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); + nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_updates.update_fail_htlcs[0]).unwrap(); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_updates.commitment_signed).unwrap(); + check_added_monitors!(nodes[0], 1); + let as_updates = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_updates.0).unwrap(); + check_added_monitors!(nodes[1], 1); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_updates.1).unwrap(); + check_added_monitors!(nodes[1], 1); + let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + + if check_revoke_no_close { + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + check_added_monitors!(nodes[0], 1); + } + + let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + for i in 1..TEST_FINAL_CLTV + HTLC_FAIL_TIMEOUT_BLOCKS + CHAN_CONFIRM_DEPTH + 1 { + nodes[0].chain_monitor.block_connected_checked(&header, i, &Vec::new(), &Vec::new()); + header.prev_blockhash = header.bitcoin_hash(); + } + if !check_revoke_no_close { + test_txn_broadcast(&nodes[0], &chan, None, HTLCType::NONE); + check_closed_broadcast!(nodes[0]); + } else { + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PaymentFailed { payment_hash, rejected_by_dest, .. } => { + assert_eq!(payment_hash, our_payment_hash); + assert!(rejected_by_dest); + }, + _ => panic!("Unexpected event"), + } + } +} + +// Test that we close channels on-chain when broadcastable HTLCs reach their timeout window. +// There are only a few cases to test here: +// * its not really normative behavior, but we test that below-dust HTLCs "included" in +// broadcastable commitment transactions result in channel closure, +// * its included in an unrevoked-but-previous remote commitment transaction, +// * its included in the latest remote or local commitment transactions. +// We test each of the three possible commitment transactions individually and use both dust and +// non-dust HTLCs. +// Note that we don't bother testing both outbound and inbound HTLC failures for each case, and we +// assume they are handled the same across all six cases, as both outbound and inbound failures are +// tested for at least one of the cases in other tests. +#[test] +fn htlc_claim_single_commitment_only_a() { + do_htlc_claim_local_commitment_only(true); + do_htlc_claim_local_commitment_only(false); + + do_htlc_claim_current_remote_commitment_only(true); + do_htlc_claim_current_remote_commitment_only(false); +} + +#[test] +fn htlc_claim_single_commitment_only_b() { + do_htlc_claim_previous_remote_commitment_only(true, false); + do_htlc_claim_previous_remote_commitment_only(false, false); + do_htlc_claim_previous_remote_commitment_only(true, true); + do_htlc_claim_previous_remote_commitment_only(false, true); +} + fn run_onion_failure_test(_name: &str, test_case: u8, nodes: &Vec, route: &Route, payment_hash: &PaymentHash, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option, expected_channel_update: Option) where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC), F2: FnMut(), @@ -6211,7 +6397,7 @@ fn test_onion_failure() { let mut nodes = create_network(3); for node in nodes.iter() { - *node.keys_manager.override_session_priv.lock().unwrap() = Some(SecretKey::from_slice(&Secp256k1::without_caps(), &[3; 32]).unwrap()); + *node.keys_manager.override_session_priv.lock().unwrap() = Some(SecretKey::from_slice(&[3; 32]).unwrap()); } let channels = [create_announced_chan_between_nodes(&nodes, 0, 1), create_announced_chan_between_nodes(&nodes, 1, 2)]; let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]); @@ -6221,7 +6407,7 @@ fn test_onion_failure() { // intermediate node failure run_onion_failure_test("invalid_realm", 0, &nodes, &route, &payment_hash, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1; let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height).unwrap(); @@ -6231,7 +6417,7 @@ fn test_onion_failure() { // final node failure run_onion_failure_test("invalid_realm", 3, &nodes, &route, &payment_hash, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1; let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); let (mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height).unwrap(); @@ -6247,7 +6433,7 @@ fn test_onion_failure() { msg.amount_msat -= 1; }, |msg| { // and tamper returing error message - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], NODE|2, &[0;0]); }, ||{}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[0].pubkey, is_permanent: false})); @@ -6255,7 +6441,7 @@ fn test_onion_failure() { // final node failure run_onion_failure_test_with_fail_intercept("temporary_node_failure", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| { // and tamper returing error message - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]); }, ||{ @@ -6266,14 +6452,14 @@ fn test_onion_failure() { run_onion_failure_test_with_fail_intercept("permanent_node_failure", 100, &nodes, &route, &payment_hash, |msg| { msg.amount_msat -= 1; }, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|2, &[0;0]); }, ||{}, true, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[0].pubkey, is_permanent: true})); // final node failure run_onion_failure_test_with_fail_intercept("permanent_node_failure", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]); }, ||{ @@ -6284,7 +6470,7 @@ fn test_onion_failure() { run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 100, &nodes, &route, &payment_hash, |msg| { msg.amount_msat -= 1; }, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]); }, ||{ @@ -6293,7 +6479,7 @@ fn test_onion_failure() { // final node failure run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 200, &nodes, &route, &payment_hash, |_msg| {}, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]); }, ||{ @@ -6312,7 +6498,7 @@ fn test_onion_failure() { run_onion_failure_test_with_fail_intercept("temporary_channel_failure", 100, &nodes, &route, &payment_hash, |msg| { msg.amount_msat -= 1; }, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy().encode_with_len()[..]); }, ||{}, true, Some(UPDATE|7), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()})); @@ -6320,7 +6506,7 @@ fn test_onion_failure() { run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, |msg| { msg.amount_msat -= 1; }, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|8, &[0;0]); // short_channel_id from the processing node @@ -6329,7 +6515,7 @@ fn test_onion_failure() { run_onion_failure_test_with_fail_intercept("required_channel_feature_missing", 100, &nodes, &route, &payment_hash, |msg| { msg.amount_msat -= 1; }, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|9, &[0;0]); // short_channel_id from the processing node @@ -6406,7 +6592,7 @@ fn test_onion_failure() { reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, |msg| { - let session_priv = SecretKey::from_slice(&::secp256k1::Secp256k1::without_caps(), &[3; 32]).unwrap(); + let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let mut route = route.clone(); let height = 1; route.hops[1].cltv_expiry_delta += CLTV_FAR_FAR_AWAY + route.hops[0].cltv_expiry_delta + 1; @@ -6417,3 +6603,304 @@ fn test_onion_failure() { msg.onion_routing_packet = onion_packet; }, ||{}, true, Some(21), None); } + +// BOLT 2 Requirements for the Sender when constructing and sending an update_add_htlc message. +// BOLT 2 Requirement: MUST NOT offer amount_msat it cannot pay for in the remote commitment transaction at the current feerate_per_kw (see "Updating Fees") while maintaining its channel reserve. +//TODO: I don't believe this is explicitly enforced when sending an HTLC but as the Fee aspect of the BOLT specs is in flux leaving this as a TODO. + +#[test] +fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { + //BOLT2 Requirement: MUST offer amount_msat greater than 0. + //BOLT2 Requirement: MUST NOT offer amount_msat below the receiving node's htlc_minimum_msat (same validation check catches both of these) + let mut nodes = create_network(2); + let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000); + let mut route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + + route.hops[0].fee_msat = 0; + + let err = nodes[0].node.send_payment(route, our_payment_hash); + + if let Err(APIError::ChannelUnavailable{err}) = err { + assert_eq!(err, "Cannot send less than their minimum HTLC value"); + } else { + assert!(false); + } +} + +#[test] +fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { + //BOLT 2 Requirement: MUST set cltv_expiry less than 500000000. + //It is enforced when constructing a route. + let mut nodes = create_network(2); + let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 0); + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000000, 500000001).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + + let err = nodes[0].node.send_payment(route, our_payment_hash); + + if let Err(APIError::RouteError{err}) = err { + assert_eq!(err, "Channel CLTV overflowed?!"); + } else { + assert!(false); + } +} + +#[test] +fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() { + //BOLT 2 Requirement: if result would be offering more than the remote's max_accepted_htlcs HTLCs, in the remote commitment transaction: MUST NOT add an HTLC. + //BOLT 2 Requirement: for the first HTLC it offers MUST set id to 0. + //BOLT 2 Requirement: MUST increase the value of id by 1 for each successive offer. + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0); + let max_accepted_htlcs = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().their_max_accepted_htlcs as u64; + + for i in 0..max_accepted_htlcs { + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + let mut payment_event = { + nodes[0].node.send_payment(route, our_payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + if let MessageSendEvent::UpdateHTLCs { node_id: _, updates: msgs::CommitmentUpdate{ update_add_htlcs: ref htlcs, .. }, } = events[0] { + assert_eq!(htlcs[0].htlc_id, i); + } else { + assert!(false); + } + SendEvent::from_event(events.remove(0)) + }; + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]).unwrap(); + check_added_monitors!(nodes[1], 0); + commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false); + + expect_pending_htlcs_forwardable!(nodes[1]); + expect_payment_received!(nodes[1], our_payment_hash, 100000); + } + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + let err = nodes[0].node.send_payment(route, our_payment_hash); + + if let Err(APIError::ChannelUnavailable{err}) = err { + assert_eq!(err, "Cannot push more than their max accepted HTLCs"); + } else { + assert!(false); + } +} + +#[test] +fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() { + //BOLT 2 Requirement: if the sum of total offered HTLCs would exceed the remote's max_htlc_value_in_flight_msat: MUST NOT add an HTLC. + let mut nodes = create_network(2); + let channel_value = 100000; + let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 0); + let max_in_flight = get_channel_value_stat!(nodes[0], chan.2).their_max_htlc_value_in_flight_msat; + + send_payment(&nodes[0], &vec!(&nodes[1])[..], max_in_flight); + + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], max_in_flight+1, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + let err = nodes[0].node.send_payment(route, our_payment_hash); + + if let Err(APIError::ChannelUnavailable{err}) = err { + assert_eq!(err, "Cannot send value that would put us over our max HTLC value in flight"); + } else { + assert!(false); + } + + send_payment(&nodes[0], &[&nodes[1]], max_in_flight); +} + +// BOLT 2 Requirements for the Receiver when handling an update_add_htlc message. +#[test] +fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() { + //BOLT2 Requirement: receiving an amount_msat equal to 0, OR less than its own htlc_minimum_msat -> SHOULD fail the channel. + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000); + let htlc_minimum_msat: u64; + { + let chan_lock = nodes[0].node.channel_state.lock().unwrap(); + let channel = chan_lock.by_id.get(&chan.2).unwrap(); + htlc_minimum_msat = channel.get_our_htlc_minimum_msat(); + } + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], htlc_minimum_msat, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[0].node.send_payment(route, our_payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + updates.update_add_htlcs[0].amount_msat = htlc_minimum_msat-1; + let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); + if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err { + assert_eq!(err, "Remote side tried to send less than our minimum HTLC value"); + } else { + assert!(false); + } + assert!(nodes[1].node.list_channels().is_empty()); + check_closed_broadcast!(nodes[1]); +} + +#[test] +fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() { + //BOLT2 Requirement: receiving an amount_msat that the sending node cannot afford at the current feerate_per_kw (while maintaining its channel reserve): SHOULD fail the channel + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000); + + let their_channel_reserve = get_channel_value_stat!(nodes[0], chan.2).channel_reserve_msat; + + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 5000000-their_channel_reserve, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[0].node.send_payment(route, our_payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + + updates.update_add_htlcs[0].amount_msat = 5000000-their_channel_reserve+1; + let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); + + if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err { + assert_eq!(err, "Remote HTLC add would put them over their reserve value"); + } else { + assert!(false); + } + + assert!(nodes[1].node.list_channels().is_empty()); + check_closed_broadcast!(nodes[1]); +} + +#[test] +fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() { + //BOLT 2 Requirement: if a sending node adds more than its max_accepted_htlcs HTLCs to its local commitment transaction: SHOULD fail the channel + //BOLT 2 Requirement: MUST allow multiple HTLCs with the same payment_hash. + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000); + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 3999999, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + + let session_priv = SecretKey::from_slice(&{ + let mut session_key = [0; 32]; + rng::fill_bytes(&mut session_key); + session_key + }).expect("RNG is bad!"); + + let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1; + let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route, &session_priv).unwrap(); + let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route, cur_height).unwrap(); + let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, &our_payment_hash); + + let mut msg = msgs::UpdateAddHTLC { + channel_id: chan.2, + htlc_id: 0, + amount_msat: 1000, + payment_hash: our_payment_hash, + cltv_expiry: htlc_cltv, + onion_routing_packet: onion_packet.clone(), + }; + + for i in 0..super::channel::OUR_MAX_HTLCS { + msg.htlc_id = i as u64; + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &msg).unwrap(); + } + msg.htlc_id = (super::channel::OUR_MAX_HTLCS) as u64; + let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &msg); + + if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err { + assert_eq!(err, "Remote tried to push more than our max accepted HTLCs"); + } else { + assert!(false); + } + + assert!(nodes[1].node.list_channels().is_empty()); + check_closed_broadcast!(nodes[1]); +} + +#[test] +fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() { + //OR adds more than its max_htlc_value_in_flight_msat worth of offered HTLCs to its local commitment transaction: SHOULD fail the channel + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000); + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[0].node.send_payment(route, our_payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + updates.update_add_htlcs[0].amount_msat = get_channel_value_stat!(nodes[1], chan.2).their_max_htlc_value_in_flight_msat + 1; + let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); + + if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err { + assert_eq!(err,"Remote HTLC add would put them over their max HTLC value in flight"); + } else { + assert!(false); + } + + assert!(nodes[1].node.list_channels().is_empty()); + check_closed_broadcast!(nodes[1]); +} + +#[test] +fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() { + //BOLT2 Requirement: if sending node sets cltv_expiry to greater or equal to 500000000: SHOULD fail the channel. + let mut nodes = create_network(2); + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000); + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 3999999, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[0].node.send_payment(route, our_payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + updates.update_add_htlcs[0].cltv_expiry = 500000000; + let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); + + if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err { + assert_eq!(err,"Remote provided CLTV expiry in seconds instead of block height"); + } else { + assert!(false); + } + + assert!(nodes[1].node.list_channels().is_empty()); + check_closed_broadcast!(nodes[1]); +} + +#[test] +fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { + //BOLT 2 requirement: if the sender did not previously acknowledge the commitment of that HTLC: MUST ignore a repeated id value after a reconnection. + // We test this by first testing that that repeated HTLCs pass commitment signature checks + // after disconnect and that non-sequential htlc_ids result in a channel failure. + let mut nodes = create_network(2); + create_announced_chan_between_nodes(&nodes, 0, 1); + let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap(); + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[0].node.send_payment(route, our_payment_hash).unwrap(); + check_added_monitors!(nodes[0], 1); + let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]).unwrap(); + + //Disconnect and Reconnect + nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); + nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); + let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); + assert_eq!(reestablish_1.len(), 1); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); + let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); + assert_eq!(reestablish_2.len(), 1); + nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); + handle_chan_reestablish_msgs!(nodes[0], nodes[1]); + nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap(); + handle_chan_reestablish_msgs!(nodes[1], nodes[0]); + + //Resend HTLC + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]).unwrap(); + assert_eq!(updates.commitment_signed.htlc_signatures.len(), 1); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &updates.commitment_signed).unwrap(); + check_added_monitors!(nodes[1], 1); + let _bs_responses = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); + + let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]); + if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err { + assert_eq!(err, "Remote skipped HTLC ID"); + } else { + assert!(false); + } + + assert!(nodes[1].node.list_channels().is_empty()); + check_closed_broadcast!(nodes[1]); +}