//! claim outputs on-chain.
use chain::transaction::OutPoint;
-use chain::chaininterface::{ChainListener, ChainWatchInterface};
-use chain::keysinterface::{KeysInterface, SpendableOutputDescriptor};
+use chain::chaininterface::{ChainListener, ChainWatchInterface, ChainWatchInterfaceUtil};
+use chain::keysinterface::{KeysInterface, SpendableOutputDescriptor, KeysManager};
use chain::keysinterface;
-use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC, BREAKDOWN_TIMEOUT};
-use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash};
-use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS, ManyChannelMonitor, HTLC_FAIL_ANTI_REORG_DELAY};
-use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT};
+use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
+use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT};
+use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ManyChannelMonitor, ANTI_REORG_DELAY};
+use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT, Channel, ChannelError};
use ln::onion_utils;
use ln::router::{Route, RouteHop};
use ln::msgs;
-use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler,HTLCFailChannelUpdate};
+use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler,HTLCFailChannelUpdate, LocalFeatures, ErrorAction};
use util::test_utils;
use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
use util::errors::APIError;
use util::ser::{Writeable, ReadableArgs};
use util::config::UserConfig;
-use util::rng;
+use util::logger::Logger;
use bitcoin::util::hash::BitcoinHash;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use bitcoin::util::address::Address;
use bitcoin::util::bip32::{ChildNumber, ExtendedPubKey, ExtendedPrivKey};
use bitcoin::blockdata::block::{Block, BlockHeader};
-use bitcoin::blockdata::transaction::{Transaction, TxOut, TxIn, SigHashType};
+use bitcoin::blockdata::transaction::{Transaction, TxOut, TxIn, SigHashType, OutPoint as BitcoinOutPoint};
use bitcoin::blockdata::script::{Builder, Script};
use bitcoin::blockdata::opcodes;
use bitcoin::blockdata::constants::genesis_block;
use std::collections::{BTreeSet, HashMap, HashSet};
use std::default::Default;
-use std::sync::Arc;
+use std::sync::{Arc, Mutex};
use std::sync::atomic::Ordering;
-use std::time::Instant;
use std::mem;
+use rand::{thread_rng, Rng};
+
use ln::functional_test_utils::*;
+#[test]
+fn test_insane_channel_opens() {
+ // Stand up a network of 2 nodes
+ let nodes = create_network(2, &[None, None]);
+
+ // Instantiate channel parameters where we push the maximum msats given our
+ // funding satoshis
+ let channel_value_sat = 31337; // same as funding satoshis
+ let channel_reserve_satoshis = Channel::get_our_channel_reserve_satoshis(channel_value_sat);
+ let push_msat = (channel_value_sat - channel_reserve_satoshis) * 1000;
+
+ // Have node0 initiate a channel to node1 with aforementioned parameters
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_sat, push_msat, 42).unwrap();
+
+ // Extract the channel open message from node0 to node1
+ let open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+
+ // Test helper that asserts we get the correct error string given a mutator
+ // that supposedly makes the channel open message insane
+ let insane_open_helper = |expected_error_str, message_mutator: fn(msgs::OpenChannel) -> msgs::OpenChannel| {
+ match nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), LocalFeatures::new(), &message_mutator(open_channel_message.clone())) {
+ Err(msgs::LightningError{ err: error_str, action: msgs::ErrorAction::SendErrorMessage {..}}) => {
+ assert_eq!(error_str, expected_error_str, "unexpected LightningError string (expected `{}`, actual `{}`)", expected_error_str, error_str)
+ },
+ Err(msgs::LightningError{..}) => {panic!("unexpected LightningError action")},
+ _ => panic!("insane OpenChannel message was somehow Ok"),
+ }
+ };
+
+ use ln::channel::MAX_FUNDING_SATOSHIS;
+ use ln::channelmanager::MAX_LOCAL_BREAKDOWN_TIMEOUT;
+
+ // Test all mutations that would make the channel open message insane
+ insane_open_helper("funding value > 2^24", |mut msg| { msg.funding_satoshis = MAX_FUNDING_SATOSHIS; msg });
+
+ insane_open_helper("Bogus channel_reserve_satoshis", |mut msg| { msg.channel_reserve_satoshis = msg.funding_satoshis + 1; msg });
+
+ insane_open_helper("push_msat larger than funding value", |mut msg| { msg.push_msat = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 + 1; msg });
+
+ insane_open_helper("Peer never wants payout outputs?", |mut msg| { msg.dust_limit_satoshis = msg.funding_satoshis + 1 ; msg });
+
+ insane_open_helper("Bogus; channel reserve is less than dust limit", |mut msg| { msg.dust_limit_satoshis = msg.channel_reserve_satoshis + 1; msg });
+
+ insane_open_helper("Minimum htlc value is full channel value", |mut msg| { msg.htlc_minimum_msat = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000; msg });
+
+ insane_open_helper("They wanted our payments to be delayed by a needlessly long period", |mut msg| { msg.to_self_delay = MAX_LOCAL_BREAKDOWN_TIMEOUT + 1; msg });
+
+ insane_open_helper("0 max_accpted_htlcs makes for a useless channel", |mut msg| { msg.max_accepted_htlcs = 0; msg });
+
+ insane_open_helper("max_accpted_htlcs > 483", |mut msg| { msg.max_accepted_htlcs = 484; msg });
+}
+
#[test]
fn test_async_inbound_update_fee() {
- let mut nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let channel_id = chan.2;
// balancing
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
// A B
// update_fee ->
fn test_update_fee_unordered_raa() {
// Just the intro to the previous test followed by an out-of-order RAA (which caused a
// crash in an earlier version of the update_fee patch)
- let mut nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let channel_id = chan.2;
// balancing
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
// First nodes[0] generates an update_fee
nodes[0].node.update_fee(channel_id, get_feerate!(nodes[0], channel_id) + 20).unwrap();
#[test]
fn test_multi_flight_update_fee() {
- let nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let channel_id = chan.2;
// A B
#[test]
fn test_update_fee_vanilla() {
- let nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let channel_id = chan.2;
let feerate = get_feerate!(nodes[0], channel_id);
#[test]
fn test_update_fee_that_funder_cannot_afford() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
let channel_value = 1888;
- let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 700000);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 700000, LocalFeatures::new(), LocalFeatures::new());
let channel_id = chan.2;
let feerate = 260;
#[test]
fn test_update_fee_with_fundee_update_add_htlc() {
- let mut nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let channel_id = chan.2;
// balancing
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
let feerate = get_feerate!(nodes[0], channel_id);
nodes[0].node.update_fee(channel_id, feerate+20).unwrap();
_ => panic!("Unexpected event"),
};
- claim_payment(&nodes[1], &vec!(&nodes[0])[..], our_payment_preimage);
+ claim_payment(&nodes[1], &vec!(&nodes[0])[..], our_payment_preimage, 800_000);
- send_payment(&nodes[1], &vec!(&nodes[0])[..], 800000);
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 800000);
+ send_payment(&nodes[1], &vec!(&nodes[0])[..], 800000, 800_000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 800000, 800_000);
close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true);
}
#[test]
fn test_update_fee() {
- let nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let channel_id = chan.2;
// A B
#[test]
fn pre_funding_lock_shutdown_test() {
// Test sending a shutdown prior to funding_locked after funding generation
- let nodes = create_network(2);
- let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 8000000, 0);
+ let nodes = create_network(2, &[None, None]);
+ let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 8000000, 0, LocalFeatures::new(), LocalFeatures::new());
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&tx; 1], &[1; 1]);
nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&tx; 1], &[1; 1]);
#[test]
fn updates_shutdown_wait() {
// Test sending a shutdown with outstanding updates pending
- let mut nodes = create_network(3);
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let mut nodes = create_network(3, &[None, None, None]);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
let route_1 = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
let route_2 = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
if let Err(APIError::ChannelUnavailable {..}) = nodes[1].node.send_payment(route_2, payment_hash) {}
else { panic!("New sends should fail!") };
- assert!(nodes[2].node.claim_funds(our_payment_preimage));
+ assert!(nodes[2].node.claim_funds(our_payment_preimage, 100_000));
check_added_monitors!(nodes[2], 1);
let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
assert!(updates.update_add_htlcs.is_empty());
#[test]
fn htlc_fail_async_shutdown() {
// Test HTLCs fail if shutdown starts even if messages are delivered out-of-order
- let mut nodes = create_network(3);
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let mut nodes = create_network(3, &[None, None, None]);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &[], 100000, TEST_FINAL_CLTV).unwrap();
let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
fn do_test_shutdown_rebroadcast(recv_count: u8) {
// Test that shutdown/closing_signed is re-sent on reconnect with a variable number of
// messages delivered prior to disconnect
- let nodes = create_network(3);
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let nodes = create_network(3, &[None, None, None]);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
let (our_payment_preimage, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 100000);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
- assert!(nodes[2].node.claim_funds(our_payment_preimage));
+ assert!(nodes[2].node.claim_funds(our_payment_preimage, 100_000));
check_added_monitors!(nodes[2], 1);
let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
assert!(updates.update_add_htlcs.is_empty());
// transaction.
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
- if let Err(msgs::HandleError{action: Some(msgs::ErrorAction::SendErrorMessage{msg}), ..}) =
+ if let Err(msgs::LightningError{action: msgs::ErrorAction::SendErrorMessage{msg}, ..}) =
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &node_0_2nd_reestablish) {
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msg);
let msgs::ErrorMessage {ref channel_id, ..} = msg;
fn fake_network_test() {
// Simple test which builds a network of ChannelManagers, connects them to each other, and
// tests that payments get routed and transactions broadcast in semi-reasonable ways.
- let nodes = create_network(4);
+ let nodes = create_network(4, &[None, None, None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
- let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
+ let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3, LocalFeatures::new(), LocalFeatures::new());
// Rebalance the network a bit by relaying one payment through all the channels...
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 8000000, 8_000_000);
// Send some more payments
- send_payment(&nodes[1], &vec!(&nodes[2], &nodes[3])[..], 1000000);
- send_payment(&nodes[3], &vec!(&nodes[2], &nodes[1], &nodes[0])[..], 1000000);
- send_payment(&nodes[3], &vec!(&nodes[2], &nodes[1])[..], 1000000);
+ send_payment(&nodes[1], &vec!(&nodes[2], &nodes[3])[..], 1000000, 1_000_000);
+ send_payment(&nodes[3], &vec!(&nodes[2], &nodes[1], &nodes[0])[..], 1000000, 1_000_000);
+ send_payment(&nodes[3], &vec!(&nodes[2], &nodes[1])[..], 1000000, 1_000_000);
// Test failure packets
let payment_hash_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 1000000).1;
fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], payment_hash_1);
// Add a new channel that skips 3
- let chan_4 = create_announced_chan_between_nodes(&nodes, 1, 3);
+ let chan_4 = create_announced_chan_between_nodes(&nodes, 1, 3, LocalFeatures::new(), LocalFeatures::new());
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 1000000);
- send_payment(&nodes[2], &vec!(&nodes[3])[..], 1000000);
- send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
- send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
- send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
- send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
- send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 1000000, 1_000_000);
+ send_payment(&nodes[2], &vec!(&nodes[3])[..], 1000000, 1_000_000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000, 8_000_000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000, 8_000_000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000, 8_000_000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000, 8_000_000);
+ send_payment(&nodes[1], &vec!(&nodes[3])[..], 8000000, 8_000_000);
// Do some rebalance loop payments, simultaneously
let mut hops = Vec::with_capacity(3);
// Claim the rebalances...
fail_payment(&nodes[1], &vec!(&nodes[3], &nodes[2], &nodes[1])[..], payment_hash_2);
- claim_payment(&nodes[1], &vec!(&nodes[2], &nodes[3], &nodes[1])[..], payment_preimage_1);
+ claim_payment(&nodes[1], &vec!(&nodes[2], &nodes[3], &nodes[1])[..], payment_preimage_1, 1_000_000);
// Add a duplicate new channel from 2 to 4
- let chan_5 = create_announced_chan_between_nodes(&nodes, 1, 3);
+ let chan_5 = create_announced_chan_between_nodes(&nodes, 1, 3, LocalFeatures::new(), LocalFeatures::new());
// Send some payments across both channels
let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], 3000000).0;
//TODO: Test that routes work again here as we've been notified that the channel is full
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_3);
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_4);
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_5);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_3, 3_000_000);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_4, 3_000_000);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[3])[..], payment_preimage_5, 3_000_000);
// Close down the channels...
close_channel(&nodes[0], &nodes[1], &chan_1.2, chan_1.3, true);
// Tests that HTLCs in the holding cell count towards the pending HTLC limits on outbound HTLCs
// to ensure we don't end up with HTLCs sitting around in our holding cell for several
// commitment dance rounds.
- let mut nodes = create_network(3);
- create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let mut nodes = create_network(3, &[None, None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
let mut payments = Vec::new();
for _ in 0..::ln::channel::OUR_MAX_HTLCS {
}
for (preimage, _) in payments.drain(..) {
- claim_payment(&nodes[1], &[&nodes[2]], preimage);
+ claim_payment(&nodes[1], &[&nodes[2]], preimage, 100_000);
}
- send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
+ send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000, 1_000_000);
}
#[test]
fn duplicate_htlc_test() {
// Test that we accept duplicate payment_hash HTLCs across the network and that
// claiming/failing them are all separate and don't affect each other
- let mut nodes = create_network(6);
+ let mut nodes = create_network(6, &[None, None, None, None, None, None]);
// Create some initial channels to route via 3 to 4/5 from 0/1/2
- create_announced_chan_between_nodes(&nodes, 0, 3);
- create_announced_chan_between_nodes(&nodes, 1, 3);
- create_announced_chan_between_nodes(&nodes, 2, 3);
- create_announced_chan_between_nodes(&nodes, 3, 4);
- create_announced_chan_between_nodes(&nodes, 3, 5);
+ create_announced_chan_between_nodes(&nodes, 0, 3, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 1, 3, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 2, 3, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 3, 4, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 3, 5, LocalFeatures::new(), LocalFeatures::new());
let (payment_preimage, payment_hash) = route_payment(&nodes[0], &vec!(&nodes[3], &nodes[4])[..], 1000000);
*nodes[0].network_payment_count.borrow_mut() -= 1;
assert_eq!(route_payment(&nodes[2], &vec!(&nodes[3], &nodes[5])[..], 1000000).0, payment_preimage);
- claim_payment(&nodes[0], &vec!(&nodes[3], &nodes[4])[..], payment_preimage);
+ claim_payment(&nodes[0], &vec!(&nodes[3], &nodes[4])[..], payment_preimage, 1_000_000);
fail_payment(&nodes[2], &vec!(&nodes[3], &nodes[5])[..], payment_hash);
- claim_payment(&nodes[1], &vec!(&nodes[3])[..], payment_preimage);
+ claim_payment(&nodes[1], &vec!(&nodes[3])[..], payment_preimage, 1_000_000);
+}
+
+#[test]
+fn test_duplicate_htlc_different_direction_onchain() {
+ // Test that ChannelMonitor doesn't generate 2 preimage txn
+ // when we have 2 HTLCs with same preimage that go across a node
+ // in opposite directions.
+ let nodes = create_network(2, &[None, None]);
+
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+
+ // balancing
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
+
+ let (payment_preimage, payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 900_000);
+
+ let route = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 800_000, TEST_FINAL_CLTV).unwrap();
+ send_along_route_with_hash(&nodes[1], route, &vec!(&nodes[0])[..], 800_000, payment_hash);
+
+ // Provide preimage to node 0 by claiming payment
+ nodes[0].node.claim_funds(payment_preimage, 800_000);
+ check_added_monitors!(nodes[0], 1);
+
+ // Broadcast node 1 commitment txn
+ let remote_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
+
+ assert_eq!(remote_txn[0].output.len(), 4); // 1 local, 1 remote, 1 htlc inbound, 1 htlc outbound
+ let mut has_both_htlcs = 0; // check htlcs match ones committed
+ for outp in remote_txn[0].output.iter() {
+ if outp.value == 800_000 / 1000 {
+ has_both_htlcs += 1;
+ } else if outp.value == 900_000 / 1000 {
+ has_both_htlcs += 1;
+ }
+ }
+ assert_eq!(has_both_htlcs, 2);
+
+ let header = BlockHeader { version: 0x2000_0000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+
+ nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![remote_txn[0].clone()] }, 1);
+
+ // Check we only broadcast 1 timeout tx
+ let claim_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
+ let htlc_pair = if claim_txn[0].output[0].value == 800_000 / 1000 { (claim_txn[0].clone(), claim_txn[1].clone()) } else { (claim_txn[1].clone(), claim_txn[0].clone()) };
+ assert_eq!(claim_txn.len(), 6);
+ assert_eq!(htlc_pair.0.input.len(), 1);
+ assert_eq!(htlc_pair.0.input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC 1 <--> 0, preimage tx
+ check_spends!(htlc_pair.0, remote_txn[0].clone());
+ assert_eq!(htlc_pair.1.input.len(), 1);
+ assert_eq!(htlc_pair.1.input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx
+ check_spends!(htlc_pair.1, remote_txn[0].clone());
+
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 2);
+ for e in events {
+ match e {
+ MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+ MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, .. } } => {
+ assert!(update_add_htlcs.is_empty());
+ assert!(update_fail_htlcs.is_empty());
+ assert_eq!(update_fulfill_htlcs.len(), 1);
+ assert!(update_fail_malformed_htlcs.is_empty());
+ assert_eq!(nodes[1].node.get_our_node_id(), *node_id);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ }
}
fn do_channel_reserve_test(test_recv: bool) {
- use util::rng;
- use std::sync::atomic::Ordering;
- use ln::msgs::HandleError;
+ use ln::msgs::LightningError;
- 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);
+ let mut nodes = create_network(3, &[None, None, None]);
+ let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1900, 1001, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1900, 1001, LocalFeatures::new(), LocalFeatures::new());
let mut stat01 = get_channel_value_stat!(nodes[0], chan_1.2);
let mut stat11 = get_channel_value_stat!(nodes[1], chan_1.2);
assert!(route.hops.iter().rev().skip(1).all(|h| h.fee_msat == feemsat));
let err = nodes[0].node.send_payment(route, our_payment_hash).err().unwrap();
match err {
- APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight"),
+ APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept"),
_ => panic!("Unknown error variants"),
}
}
if stat01.value_to_self_msat - amt_msat < stat01.channel_reserve_msat {
break;
}
- send_payment(&nodes[0], &vec![&nodes[1], &nodes[2]][..], recv_value_0);
+ send_payment(&nodes[0], &vec![&nodes[1], &nodes[2]][..], recv_value_0, recv_value_0);
htlc_id += 1;
let (stat01_, stat11_, stat12_, stat22_) = (
let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value + 1);
let err = nodes[0].node.send_payment(route.clone(), our_payment_hash).err().unwrap();
match err {
- APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over the reserve value"),
+ APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over their reserve value"),
_ => panic!("Unknown error variants"),
}
}
{
let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_2 + 1);
match nodes[0].node.send_payment(route, our_payment_hash).err().unwrap() {
- APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over the reserve value"),
+ APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over their reserve value"),
_ => panic!("Unknown error variants"),
}
}
let secp_ctx = Secp256k1::new();
let session_priv = SecretKey::from_slice(&{
let mut session_key = [0; 32];
- rng::fill_bytes(&mut session_key);
+ let mut rng = thread_rng();
+ rng.fill_bytes(&mut session_key);
session_key
}).expect("RNG is bad!");
if test_recv {
let err = nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &msg).err().unwrap();
match err {
- HandleError{err, .. } => assert_eq!(err, "Remote HTLC add would put them over their reserve value"),
+ LightningError{err, .. } => assert_eq!(err, "Remote HTLC add would put them over their reserve value"),
}
// If we send a garbage message, the channel should get closed, making the rest of this test case fail.
assert_eq!(nodes[1].node.list_channels().len(), 1);
{
let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_22+1);
match nodes[0].node.send_payment(route, our_payment_hash).err().unwrap() {
- APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over the reserve value"),
+ APIError::ChannelUnavailable{err} => assert_eq!(err, "Cannot send value that would put us over their reserve value"),
_ => panic!("Unknown error variants"),
}
}
_ => panic!("Unexpected event"),
}
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_1);
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_21);
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_22);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_1, recv_value_1);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_21, recv_value_21);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), our_payment_preimage_22, recv_value_22);
let expected_value_to_self = stat01.value_to_self_msat - (recv_value_1 + total_fee_msat) - (recv_value_21 + total_fee_msat) - (recv_value_22 + total_fee_msat);
let stat0 = get_channel_value_stat!(nodes[0], chan_1.2);
// removed it fully. B now has the push_msat plus the first two HTLCs in value.
// * Now B happily sends another HTLC, potentially violating its reserve value from A's point
// of view (if A counts the AwaitingRemovedRemoteRevoke HTLC).
- let mut nodes = create_network(2);
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let b_chan_values = get_channel_value_stat!(nodes[1], chan_1.2);
// Route the first two HTLCs.
// Now claim both of the first two HTLCs on B's end, putting B in AwaitingRAA and generating an
// initial fulfill/CS.
- assert!(nodes[1].node.claim_funds(payment_preimage_1));
+ assert!(nodes[1].node.claim_funds(payment_preimage_1, b_chan_values.channel_reserve_msat - b_chan_values.value_to_self_msat - 10000));
check_added_monitors!(nodes[1], 1);
let bs_removes = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
// This claim goes in B's holding cell, allowing us to have a pending B->A RAA which does not
// remove the second HTLC when we send the HTLC back from B to A.
- assert!(nodes[1].node.claim_funds(payment_preimage_2));
+ assert!(nodes[1].node.claim_funds(payment_preimage_2, 20000));
check_added_monitors!(nodes[1], 1);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
expect_pending_htlcs_forwardable!(nodes[0]);
expect_payment_received!(nodes[0], payment_hash_4, 10000);
- claim_payment(&nodes[1], &[&nodes[0]], payment_preimage_4);
- claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_3);
+ claim_payment(&nodes[1], &[&nodes[0]], payment_preimage_4, 10_000);
+ claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_3, 100_000);
}
#[test]
fn channel_monitor_network_test() {
// Simple test which builds a network of ChannelManagers, connects them to each other, and
// tests that ChannelMonitor is able to recover from various states.
- let nodes = create_network(5);
+ let nodes = create_network(5, &[None, None, None, None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
- let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
- let chan_4 = create_announced_chan_between_nodes(&nodes, 3, 4);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
+ let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3, LocalFeatures::new(), LocalFeatures::new());
+ let chan_4 = create_announced_chan_between_nodes(&nodes, 3, 4, LocalFeatures::new(), LocalFeatures::new());
// Rebalance the network a bit by relaying one payment through all the channels...
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000, 8_000_000);
// Simple case with no pending HTLCs:
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true);
assert_eq!(nodes[2].node.list_channels().len(), 1);
macro_rules! claim_funds {
- ($node: expr, $prev_node: expr, $preimage: expr) => {
+ ($node: expr, $prev_node: expr, $preimage: expr, $amount: expr) => {
{
- assert!($node.node.claim_funds($preimage));
+ assert!($node.node.claim_funds($preimage, $amount));
check_added_monitors!($node, 1);
let events = $node.node.get_and_clear_pending_msg_events();
let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::TIMEOUT);
// Claim the payment on nodes[3], giving it knowledge of the preimage
- claim_funds!(nodes[3], nodes[2], payment_preimage_1);
+ claim_funds!(nodes[3], nodes[2], payment_preimage_1, 3_000_000);
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[3].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, 1);
{
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[3].chain_monitor.block_connected_checked(&header, 2, &Vec::new()[..], &[0; 0]);
- for i in 3..TEST_FINAL_CLTV + 2 + HTLC_FAIL_TIMEOUT_BLOCKS + 1 {
+ for i in 3..TEST_FINAL_CLTV + 2 + LATENCY_GRACE_PERIOD_BLOCKS + 1 {
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[3].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
}
let node_txn = test_txn_broadcast(&nodes[3], &chan_4, None, HTLCType::TIMEOUT);
// Claim the payment on nodes[4], giving it knowledge of the preimage
- claim_funds!(nodes[4], nodes[3], payment_preimage_2);
+ claim_funds!(nodes[4], nodes[3], payment_preimage_2, 3_000_000);
header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[4].chain_monitor.block_connected_checked(&header, 2, &Vec::new()[..], &[0; 0]);
fn test_justice_tx() {
// Test justice txn built on revoked HTLC-Success tx, against both sides
- let nodes = create_network(2);
+ let mut alice_config = UserConfig::new();
+ alice_config.channel_options.announced_channel = true;
+ alice_config.peer_channel_config_limits.force_announced_channel_preference = false;
+ alice_config.own_channel_config.our_to_self_delay = 6 * 24 * 5;
+ let mut bob_config = UserConfig::new();
+ bob_config.channel_options.announced_channel = true;
+ bob_config.peer_channel_config_limits.force_announced_channel_preference = false;
+ bob_config.own_channel_config.our_to_self_delay = 6 * 24 * 3;
+ let nodes = create_network(2, &[Some(alice_config), Some(bob_config)]);
// Create some new channels:
- let chan_5 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_5 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
// A pending HTLC which will be revoked:
let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
assert_eq!(revoked_local_txn[1].input[0].previous_output.txid, revoked_local_txn[0].txid());
assert_eq!(revoked_local_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC-Timeout
// Revoke the old state
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_3);
+ claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_3, 3_000_000);
{
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
// We test justice_tx build by A on B's revoked HTLC-Success tx
// Create some new channels:
- let chan_6 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_6 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
// A pending HTLC which will be revoked:
let payment_preimage_4 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_6.3.txid());
assert_eq!(revoked_local_txn[0].output.len(), 2); // Only HTLC and output back to A are present
// Revoke the old state
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_4);
+ claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_4, 3_000_000);
{
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
fn revoked_output_claim() {
// Simple test to ensure a node will claim a revoked output when a stale remote commitment
// transaction is broadcast by its counterparty
- let nodes = create_network(2);
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
// node[0] is gonna to revoke an old state thus node[1] should be able to claim the revoked output
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
assert_eq!(revoked_local_txn.len(), 1);
// Only output is the full channel value back to nodes[0]:
assert_eq!(revoked_local_txn[0].output.len(), 1);
// Send a payment through, updating everyone's latest commitment txn
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 5000000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 5000000, 5_000_000);
// Inform nodes[1] that nodes[0] broadcast a stale tx
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
#[test]
fn claim_htlc_outputs_shared_tx() {
// Node revoked old state, htlcs haven't time out yet, claim them in shared justice tx
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// Create some new channel:
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
// Rebalance the network to generate htlc in the two directions
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
// node[0] is gonna to revoke an old state thus node[1] should be able to claim both offered/received HTLC outputs on top of commitment tx
let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
let (_payment_preimage_2, payment_hash_2) = route_payment(&nodes[1], &vec!(&nodes[0])[..], 3000000);
check_spends!(revoked_local_txn[1], revoked_local_txn[0].clone());
//Revoke the old state
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1);
+ claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1, 3_000_000);
{
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
- connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
+ connect_blocks(&nodes[1].chain_monitor, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
let events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
#[test]
fn claim_htlc_outputs_single_tx() {
// Node revoked old state, htlcs have timed out, claim each of them in separated justice tx
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
// Rebalance the network to generate htlc in the two directions
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
// node[0] is gonna to revoke an old state thus node[1] should be able to claim both offered/received HTLC outputs on top of commitment tx, but this
// time as two different claim transactions as we're gonna to timeout htlc with given a high current height
let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
//Revoke the old state
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1);
+ claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1, 3_000_000);
{
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 200);
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 200);
- connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 200, true, header.bitcoin_hash());
+ connect_blocks(&nodes[1].chain_monitor, ANTI_REORG_DELAY - 1, 200, true, header.bitcoin_hash());
let events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
assert_eq!(node_txn[1].input.len(), 1);
assert_eq!(node_txn[2].input.len(), 1);
- let mut revoked_tx_map = HashMap::new();
- revoked_tx_map.insert(revoked_local_txn[0].txid(), revoked_local_txn[0].clone());
- node_txn[0].verify(&revoked_tx_map).unwrap();
- node_txn[1].verify(&revoked_tx_map).unwrap();
- node_txn[2].verify(&revoked_tx_map).unwrap();
+ fn get_txout(out_point: &BitcoinOutPoint, tx: &Transaction) -> Option<TxOut> {
+ if out_point.txid == tx.txid() {
+ tx.output.get(out_point.vout as usize).cloned()
+ } else {
+ None
+ }
+ }
+ node_txn[0].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap();
+ node_txn[1].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap();
+ node_txn[2].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap();
let mut witness_lens = BTreeSet::new();
witness_lens.insert(node_txn[0].input[0].witness.last().unwrap().len());
// the HTLC outputs via the preimage it learned (which, once confirmed should generate a
// PaymentSent event).
- let nodes = create_network(3);
+ let nodes = create_network(3, &[None, None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
// Rebalance the network a bit by relaying one payment through all the channels...
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000, 8_000_000);
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 commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
assert_eq!(commitment_tx.len(), 1);
check_spends!(commitment_tx[0], chan_2.3.clone());
- nodes[2].node.claim_funds(our_payment_preimage);
- nodes[2].node.claim_funds(our_payment_preimage_2);
+ nodes[2].node.claim_funds(our_payment_preimage, 3_000_000);
+ nodes[2].node.claim_funds(our_payment_preimage_2, 3_000_000);
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());
// \ \
// B's HTLC timeout tx B's timeout tx
- let nodes = create_network(3);
+ let nodes = create_network(3, &[None, None, None]);
// Create some intial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
// Rebalance the network a bit by relaying one payment thorugh all the channels...
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000, 8_000_000);
let (_payment_preimage, payment_hash) = 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};
}
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![timeout_tx]}, 1);
+ connect_blocks(&nodes[1].chain_monitor, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
check_added_monitors!(nodes[1], 0);
check_closed_broadcast!(nodes[1]);
// Test that in case of a revoked commitment tx, we detect the resolution of output by justice tx
// and fail backward accordingly.
- let nodes = create_network(3);
+ let nodes = create_network(3, &[None, None, None]);
// Create some initial channels
- create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
// 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();
// Revoke the old state
- claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
+ claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage, 3_000_000);
route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
- connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
+ connect_blocks(&nodes[1].chain_monitor, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
check_added_monitors!(nodes[1], 0);
check_closed_broadcast!(nodes[1]);
// * Once they remove it, we will send a (the first) commitment_signed without the HTLC,
// and once they revoke the previous commitment transaction (allowing us to send a new
// commitment_signed) we will be free to fail/fulfill the HTLC backwards.
- let mut nodes = create_network(3);
+ let mut nodes = create_network(3, &[None, None, None]);
// Create some initial channels
- create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
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);
+ claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage, if no_to_remote { 10_000 } else { 3_000_000});
let value = if use_dust {
// The dust limit applied to HTLC outputs considers the fee of the HTLC transaction as
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42};
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
- connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
+ connect_blocks(&nodes[1].chain_monitor, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
let events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(events.len(), if deliver_bs_raa { 1 } else { 2 });
_ => panic!("Unexpected event"),
};
}
- nodes[1].node.channel_state.lock().unwrap().next_forward = Instant::now();
nodes[1].node.process_pending_htlc_forwards();
check_added_monitors!(nodes[1], 1);
fn test_htlc_ignore_latest_remote_commitment() {
// Test that HTLC transactions spending the latest remote commitment transaction are simply
// ignored if we cannot claim them. This originally tickled an invalid unwrap().
- let nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
route_payment(&nodes[0], &[&nodes[1]], 10000000);
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id);
#[test]
fn test_force_close_fail_back() {
// Check which HTLCs are failed-backwards on channel force-closure
- let mut nodes = create_network(3);
- create_announced_chan_between_nodes(&nodes, 0, 1);
- create_announced_chan_between_nodes(&nodes, 1, 2);
+ let mut nodes = create_network(3, &[None, None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, 42).unwrap();
#[test]
fn test_unconf_chan() {
// After creating a chan between nodes, we disconnect all blocks previously seen to force a channel close on nodes[0] side
- let nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let channel_state = nodes[0].node.channel_state.lock().unwrap();
assert_eq!(channel_state.by_id.len(), 1);
#[test]
fn test_simple_peer_disconnect() {
// Test that we can reconnect when there are no lost messages
- let nodes = create_network(3);
- create_announced_chan_between_nodes(&nodes, 0, 1);
- create_announced_chan_between_nodes(&nodes, 1, 2);
+ let nodes = create_network(3, &[None, None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
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);
let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0;
let payment_hash_2 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1;
fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_hash_2);
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_1);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_1, 1_000_000);
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_disconnected(&nodes[1].node.get_our_node_id(), false);
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
- claim_payment_along_route(&nodes[0], &vec!(&nodes[1], &nodes[2]), true, payment_preimage_3);
+ claim_payment_along_route(&nodes[0], &vec!(&nodes[1], &nodes[2]), true, payment_preimage_3, 1_000_000);
fail_payment_along_route(&nodes[0], &[&nodes[1], &nodes[2]], true, payment_hash_5);
reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (1, 0), (1, 0), (false, false));
}
}
- claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_4);
+ claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_4, 1_000_000);
fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_hash_6);
}
fn do_test_drop_messages_peer_disconnect(messages_delivered: u8) {
// Test that we can reconnect when in-flight HTLC updates get dropped
- let mut nodes = create_network(2);
+ let mut nodes = create_network(2, &[None, None]);
if messages_delivered == 0 {
- create_chan_between_nodes_with_value_a(&nodes[0], &nodes[1], 100000, 10001);
+ create_chan_between_nodes_with_value_a(&nodes[0], &nodes[1], 100000, 10001, LocalFeatures::new(), LocalFeatures::new());
// nodes[1] doesn't receive the funding_locked message (it'll be re-sent on reconnect)
} else {
- create_announced_chan_between_nodes(&nodes, 0, 1);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
}
let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), Some(&nodes[0].node.list_usable_channels()), &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
- nodes[1].node.channel_state.lock().unwrap().next_forward = Instant::now();
nodes[1].node.process_pending_htlc_forwards();
let events_2 = nodes[1].node.get_and_clear_pending_events();
_ => panic!("Unexpected event"),
}
- nodes[1].node.claim_funds(payment_preimage_1);
+ nodes[1].node.claim_funds(payment_preimage_1, 1_000_000);
check_added_monitors!(nodes[1], 1);
let events_3 = nodes[1].node.get_and_clear_pending_msg_events();
// Channel should still work fine...
let payment_preimage_2 = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000).0;
- claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
+ claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
}
#[test]
#[test]
fn test_funding_peer_disconnect() {
// Test that we can lock in our funding tx while disconnected
- let nodes = create_network(2);
- let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
+ let nodes = create_network(2, &[None, None]);
+ let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, LocalFeatures::new(), LocalFeatures::new());
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);
let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), Some(&nodes[0].node.list_usable_channels()), &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
let (payment_preimage, _) = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000);
- claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
+ claim_payment(&nodes[0], &[&nodes[1]], payment_preimage, 1_000_000);
}
#[test]
fn test_drop_messages_peer_disconnect_dual_htlc() {
// Test that we can handle reconnecting when both sides of a channel have pending
// commitment_updates when we disconnect.
- let mut nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
_ => panic!("Unexpected event"),
}
- assert!(nodes[1].node.claim_funds(payment_preimage_1));
+ assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
check_added_monitors!(nodes[1], 1);
let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
check_added_monitors!(nodes[0], 1);
- claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
+ claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
}
#[test]
fn test_invalid_channel_announcement() {
//Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs
let secp_ctx = Secp256k1::new();
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
- let chan_announcement = create_chan_between_nodes(&nodes[0], &nodes[1]);
+ let chan_announcement = create_chan_between_nodes(&nodes[0], &nodes[1], LocalFeatures::new(), LocalFeatures::new());
let a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
let b_channel_lock = nodes[1].node.channel_state.lock().unwrap();
#[test]
fn test_no_txn_manager_serialize_deserialize() {
- let mut nodes = create_network(2);
+ let mut nodes = create_network(2, &[None, None]);
- let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
+ let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, LocalFeatures::new(), LocalFeatures::new());
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
let mut nodes_0_read = &nodes_0_serialized[..];
let config = UserConfig::new();
- let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
+ let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
let (_, nodes_0_deserialized) = {
let mut channel_monitors = HashMap::new();
channel_monitors.insert(chan_0_monitor.get_funding_txo().unwrap(), &chan_0_monitor);
node.router.handle_channel_update(&bs_update).unwrap();
}
- send_payment(&nodes[0], &[&nodes[1]], 1000000);
+ send_payment(&nodes[0], &[&nodes[1]], 1000000, 1_000_000);
}
#[test]
fn test_simple_manager_serialize_deserialize() {
- let mut nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let (our_payment_preimage, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
let (_, our_payment_hash) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
assert!(chan_0_monitor_read.is_empty());
let mut nodes_0_read = &nodes_0_serialized[..];
- let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
+ let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
let (_, nodes_0_deserialized) = {
let mut channel_monitors = HashMap::new();
channel_monitors.insert(chan_0_monitor.get_funding_txo().unwrap(), &chan_0_monitor);
reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
fail_payment(&nodes[0], &[&nodes[1]], our_payment_hash);
- claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage);
+ claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage, 1_000_000);
}
#[test]
fn test_manager_serialize_deserialize_inconsistent_monitor() {
// Test deserializing a ChannelManager with an out-of-date ChannelMonitor
- let mut nodes = create_network(4);
- create_announced_chan_between_nodes(&nodes, 0, 1);
- create_announced_chan_between_nodes(&nodes, 2, 0);
- let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3);
+ let mut nodes = create_network(4, &[None, None, None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 2, 0, LocalFeatures::new(), LocalFeatures::new());
+ let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3, LocalFeatures::new(), LocalFeatures::new());
let (our_payment_preimage, _) = route_payment(&nodes[2], &[&nodes[0], &nodes[1]], 1000000);
}
let mut nodes_0_read = &nodes_0_serialized[..];
- let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
+ let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
let (_, nodes_0_deserialized) = <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
default_config: UserConfig::new(),
keys_manager,
reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
reconnect_nodes(&nodes[0], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
//... and we can even still claim the payment!
- claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage);
+ claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage, 1_000_000);
nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id());
let reestablish = get_event_msg!(nodes[3], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id());
- if let Err(msgs::HandleError { action: Some(msgs::ErrorAction::SendErrorMessage { msg }), .. }) = nodes[0].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish) {
+ if let Err(msgs::LightningError { action: msgs::ErrorAction::SendErrorMessage { msg }, .. }) = nodes[0].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish) {
assert_eq!(msg.channel_id, channel_id);
} else { panic!("Unexpected result"); }
}
#[test]
fn test_claim_sizeable_push_msat() {
// Incidentally test SpendableOutput event generation due to detection of to_local output on commitment tx
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
- let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000, LocalFeatures::new(), LocalFeatures::new());
nodes[1].node.force_close_channel(&chan.2);
check_closed_broadcast!(nodes[1]);
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
// Same test as previous, just test on remote commitment tx, as per_commitment_point registration changes following you're funder/fundee and
// to_remote output is encumbered by a P2WPKH
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
- let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 99000000, LocalFeatures::new(), LocalFeatures::new());
nodes[0].node.force_close_channel(&chan.2);
check_closed_broadcast!(nodes[0]);
// Same test as previous, just test on remote revoked commitment tx, as per_commitment_point registration changes following you're funder/fundee and
// to_remote output is encumbered by a P2WPKH
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
- let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 59000000);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 59000000, LocalFeatures::new(), LocalFeatures::new());
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
assert_eq!(revoked_local_txn[0].input.len(), 1);
assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan.3.txid());
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
+ 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].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
check_closed_broadcast!(nodes[1]);
#[test]
fn test_static_spendable_outputs_preimage_tx() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
// Settle A's commitment tx on B's chain
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
- assert!(nodes[1].node.claim_funds(payment_preimage));
+ assert!(nodes[1].node.claim_funds(payment_preimage, 3_000_000));
check_added_monitors!(nodes[1], 1);
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()] }, 1);
let events = nodes[1].node.get_and_clear_pending_msg_events();
#[test]
fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.iter().next().unwrap().1.last_local_commitment_txn.clone();
assert_eq!(revoked_local_txn[0].input.len(), 1);
assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid());
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
+ 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].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
#[test]
fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
assert_eq!(revoked_local_txn[0].input.len(), 1);
assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid());
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
+ 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 };
// A will generate HTLC-Timeout from revoked commitment tx
#[test]
fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
let revoked_local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
assert_eq!(revoked_local_txn[0].input.len(), 1);
assert_eq!(revoked_local_txn[0].input[0].previous_output.txid, chan_1.3.txid());
- claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
+ 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 };
// B will generate HTLC-Success from revoked commitment tx
// Finally, check that B will claim the HTLC output if A's latest commitment transaction
// gets broadcast.
- let nodes = create_network(3);
+ let nodes = create_network(3, &[None, None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
// Rebalance the network a bit by relaying one payment through all the channels ...
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000, 8_000_000);
let (payment_preimage, _payment_hash) = 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};
let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
check_spends!(commitment_tx[0], chan_2.3.clone());
- nodes[2].node.claim_funds(payment_preimage);
+ nodes[2].node.claim_funds(payment_preimage, 3_000_000);
check_added_monitors!(nodes[2], 1);
let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
assert!(updates.update_add_htlcs.is_empty());
fn test_duplicate_payment_hash_one_failure_one_success() {
// Topology : A --> B --> C
// We route 2 payments with same hash between B and C, one will be timeout, the other successfully claim
- let mut nodes = create_network(3);
+ let mut nodes = create_network(3, &[None, None, None]);
- create_announced_chan_between_nodes(&nodes, 0, 1);
- let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+ let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
let (our_payment_preimage, duplicate_payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 900000);
*nodes[0].network_payment_count.borrow_mut() -= 1;
htlc_timeout_tx = node_txn[1].clone();
}
- nodes[2].node.claim_funds(our_payment_preimage);
+ nodes[2].node.claim_funds(our_payment_preimage, 900_000);
nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_txn[0].clone()] }, 1);
check_added_monitors!(nodes[2], 2);
let events = nodes[2].node.get_and_clear_pending_msg_events();
check_spends!(htlc_success_txn[1], commitment_txn[0].clone());
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![htlc_timeout_tx] }, 200);
+ connect_blocks(&nodes[1].chain_monitor, ANTI_REORG_DELAY - 1, 200, true, header.bitcoin_hash());
expect_pending_htlcs_forwardable!(nodes[1]);
let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(htlc_updates.update_add_htlcs.is_empty());
#[test]
fn test_dynamic_spendable_outputs_local_htlc_success_tx() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0;
let local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
check_spends!(local_txn[0], chan_1.3.clone());
// Give B knowledge of preimage to be able to generate a local HTLC-Success Tx
- nodes[1].node.claim_funds(payment_preimage);
+ nodes[1].node.claim_funds(payment_preimage, 9_000_000);
check_added_monitors!(nodes[1], 1);
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![local_txn[0].clone()] }, 1);
// - C - D -
// B / \ F
// And test where C fails back to A/B when D announces its latest commitment transaction
- let nodes = create_network(6);
+ let nodes = create_network(6, &[None, None, None, None, None, None]);
- create_announced_chan_between_nodes(&nodes, 0, 2);
- create_announced_chan_between_nodes(&nodes, 1, 2);
- let chan = create_announced_chan_between_nodes(&nodes, 2, 3);
- create_announced_chan_between_nodes(&nodes, 3, 4);
- create_announced_chan_between_nodes(&nodes, 3, 5);
+ create_announced_chan_between_nodes(&nodes, 0, 2, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
+ let chan = create_announced_chan_between_nodes(&nodes, 2, 3, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 3, 4, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes(&nodes, 3, 5, LocalFeatures::new(), LocalFeatures::new());
// Rebalance and check output sanity...
- send_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 500000);
- send_payment(&nodes[1], &[&nodes[2], &nodes[3], &nodes[5]], 500000);
+ send_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 500000, 500_000);
+ send_payment(&nodes[1], &[&nodes[2], &nodes[3], &nodes[5]], 500000, 500_000);
assert_eq!(nodes[3].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn[0].output.len(), 2);
let ds_dust_limit = nodes[3].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().our_dust_limit_satoshis;
} else {
nodes[2].chain_monitor.block_connected_checked(&header, 1, &[&ds_prev_commitment_tx[0]], &[1; 1]);
}
- connect_blocks(&nodes[2].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
+ connect_blocks(&nodes[2].chain_monitor, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
check_closed_broadcast!(nodes[2]);
expect_pending_htlcs_forwardable!(nodes[2]);
check_added_monitors!(nodes[2], 2);
#[test]
fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// Create some initial channels
- let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0;
let local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan_1.2).unwrap().last_local_commitment_txn.clone();
#[test]
fn test_static_output_closing_tx() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
- send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
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 };
}
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 nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
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));
+ assert!(nodes[1].node.claim_funds(our_payment_preimage, if use_dust { 50_000 } else { 3_000_000 }));
check_added_monitors!(nodes[1], 1);
let bs_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
}
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 mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
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]);
// 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 {
+ for i in 1..TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + CHAN_CONFIRM_DEPTH + 1 {
nodes[0].chain_monitor.block_connected_checked(&header, i, &Vec::new(), &Vec::new());
header.prev_blockhash = header.bitcoin_hash();
}
}
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);
+ let nodes = create_network(3, &[None, None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
// 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.
}
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 {
+ for i in 1..TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + CHAN_CONFIRM_DEPTH + 1 {
nodes[0].chain_monitor.block_connected_checked(&header, i, &Vec::new(), &Vec::new());
header.prev_blockhash = header.bitcoin_hash();
}
F2: for <'a> FnMut(&'a mut msgs::UpdateFailHTLC),
F3: FnMut(),
{
- use ln::msgs::HTLCFailChannelUpdate;
// reset block height
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
macro_rules! expect_htlc_forward {
($node: expr) => {{
expect_event!($node, Event::PendingHTLCsForwardable);
- $node.node.channel_state.lock().unwrap().next_forward = Instant::now();
$node.node.process_pending_htlc_forwards();
}}
}
const NODE: u16 = 0x2000;
const UPDATE: u16 = 0x1000;
- let mut nodes = create_network(3);
+ let mut nodes = create_network(3, &[None, None, None]);
for node in nodes.iter() {
*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 channels = [create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new()), create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new())];
let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap();
// positve case
- send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 40000);
+ send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 40000, 40_000);
// intermediate node failure
run_onion_failure_test("invalid_realm", 0, &nodes, &route, &payment_hash, |msg| {
}, || {}, true, Some(UPDATE|13), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, |msg| {
- let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - HTLC_FAIL_TIMEOUT_BLOCKS + 1;
+ let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS + 1;
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[1].chain_monitor.block_connected_checked(&header, height, &Vec::new()[..], &[0; 0]);
}, ||{}, true, Some(UPDATE|14), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
}, false, Some(PERM|15), None);
run_onion_failure_test("final_expiry_too_soon", 1, &nodes, &route, &payment_hash, |msg| {
- let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - HTLC_FAIL_TIMEOUT_BLOCKS + 1;
+ let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS + 1;
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
nodes[2].chain_monitor.block_connected_checked(&header, height, &Vec::new()[..], &[0; 0]);
}, || {}, true, Some(17), None);
#[test]
#[should_panic]
fn bolt2_open_channel_sending_node_checks_part1() { //This test needs to be on its own as we are catching a panic
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
//Force duplicate channel ids
for node in nodes.iter() {
*node.keys_manager.override_channel_id_priv.lock().unwrap() = Some([0; 32]);
let push_msat=10001;
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42).unwrap();
let node0_to_1_send_open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
- nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), &node0_to_1_send_open_channel).unwrap();
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), LocalFeatures::new(), &node0_to_1_send_open_channel).unwrap();
//Create a second channel with a channel_id collision
assert!(nodes[0].node.create_channel(nodes[0].node.get_our_node_id(), channel_value_satoshis, push_msat, 42).is_err());
#[test]
fn bolt2_open_channel_sending_node_checks_part2() {
- let nodes = create_network(2);
+ let nodes = create_network(2, &[None, None]);
// BOLT #2 spec: Sending node must set funding_satoshis to less than 2^24 satoshis
let channel_value_satoshis=2^24;
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 nodes = create_network(2, &[None, None]);
+ let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, LocalFeatures::new(), LocalFeatures::new());
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]);
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 mut nodes = create_network(2, &[None, None]);
+ let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 0, LocalFeatures::new(), LocalFeatures::new());
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]);
//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 mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0, LocalFeatures::new(), LocalFeatures::new());
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 {
#[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 mut nodes = create_network(2, &[None, None]);
let channel_value = 100000;
- let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 0);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 0, LocalFeatures::new(), LocalFeatures::new());
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);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], max_in_flight, 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 the max HTLC value in flight");
+ assert_eq!(err, "Cannot send value that would put us over the max HTLC value in flight our peer will accept");
} else {
assert!(false);
}
- send_payment(&nodes[0], &[&nodes[1]], max_in_flight);
+ send_payment(&nodes[0], &[&nodes[1]], max_in_flight, 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 mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, LocalFeatures::new(), LocalFeatures::new());
let htlc_minimum_msat: u64;
{
let chan_lock = nodes[0].node.channel_state.lock().unwrap();
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 {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote side tried to send less than our minimum HTLC value");
} else {
assert!(false);
#[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 mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, LocalFeatures::new(), LocalFeatures::new());
let their_channel_reserve = get_channel_value_stat!(nodes[0], chan.2).channel_reserve_msat;
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 {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote HTLC add would put them over their reserve value");
} else {
assert!(false);
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 mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, LocalFeatures::new(), LocalFeatures::new());
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);
+ let mut rng = thread_rng();
+ rng.fill_bytes(&mut session_key);
session_key
}).expect("RNG is bad!");
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 {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote tried to push more than our max accepted HTLCs");
} else {
assert!(false);
#[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 mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, LocalFeatures::new(), LocalFeatures::new());
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();
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");
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
+ assert_eq!(err,"Remote HTLC add would put them over our max HTLC value");
} else {
assert!(false);
}
#[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 mut nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, LocalFeatures::new(), LocalFeatures::new());
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();
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 {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err,"Remote provided CLTV expiry in seconds instead of block height");
} else {
assert!(false);
//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 mut nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
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();
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 {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote skipped HTLC ID");
} else {
assert!(false);
fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() {
//BOLT 2 Requirement: until the corresponding HTLC is irrevocably committed in both sides' commitment transactions: MUST NOT send an update_fulfill_htlc, update_fail_htlc, or update_fail_malformed_htlc.
- let mut nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &[], 1000000, TEST_FINAL_CLTV).unwrap();
let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
let err = nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_msg);
- if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote tried to fulfill/fail HTLC before it had been committed");
} else {
assert!(false);
fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() {
//BOLT 2 Requirement: until the corresponding HTLC is irrevocably committed in both sides' commitment transactions: MUST NOT send an update_fulfill_htlc, update_fail_htlc, or update_fail_malformed_htlc.
- let mut nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
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]);
let err = nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_msg);
- if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote tried to fulfill/fail HTLC before it had been committed");
} else {
assert!(false);
fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() {
//BOLT 2 Requirement: until the corresponding HTLC is irrevocably committed in both sides' commitment transactions: MUST NOT send an update_fulfill_htlc, update_fail_htlc, or update_fail_malformed_htlc.
- let mut nodes = create_network(2);
- let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
+ let mut nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
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]);
let err = nodes[0].node.handle_update_fail_malformed_htlc(&nodes[1].node.get_our_node_id(), &update_msg);
- if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote tried to fulfill/fail HTLC before it had been committed");
} else {
assert!(false);
fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() {
//BOLT 2 Requirement: A receiving node: if the id does not correspond to an HTLC in its current commitment transaction MUST fail the channel.
- let nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let our_payment_preimage = route_payment(&nodes[0], &[&nodes[1]], 100000).0;
- nodes[1].node.claim_funds(our_payment_preimage);
+ nodes[1].node.claim_funds(our_payment_preimage, 100_000);
check_added_monitors!(nodes[1], 1);
let events = nodes[1].node.get_and_clear_pending_msg_events();
update_fulfill_msg.htlc_id = 1;
let err = nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_fulfill_msg);
- if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote tried to fulfill/fail an HTLC we couldn't find");
} else {
assert!(false);
fn test_update_fulfill_htlc_bolt2_wrong_preimage() {
//BOLT 2 Requirement: A receiving node: if the payment_preimage value in update_fulfill_htlc doesn't SHA256 hash to the corresponding HTLC payment_hash MUST fail the channel.
- let nodes = create_network(2);
- create_announced_chan_between_nodes(&nodes, 0, 1);
+ let nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
let our_payment_preimage = route_payment(&nodes[0], &[&nodes[1]], 100000).0;
- nodes[1].node.claim_funds(our_payment_preimage);
+ nodes[1].node.claim_funds(our_payment_preimage, 100_000);
check_added_monitors!(nodes[1], 1);
let events = nodes[1].node.get_and_clear_pending_msg_events();
update_fulfill_msg.payment_preimage = PaymentPreimage([1; 32]);
let err = nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &update_fulfill_msg);
- if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Remote tried to fulfill HTLC with an incorrect preimage");
} else {
assert!(false);
fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_message() {
//BOLT 2 Requirement: A receiving node: if the BADONION bit in failure_code is not set for update_fail_malformed_htlc MUST fail the channel.
- let mut nodes = create_network(2);
- create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
+ let mut nodes = create_network(2, &[None, None]);
+ create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, LocalFeatures::new(), LocalFeatures::new());
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();
};
update_msg.failure_code &= !0x8000;
let err = nodes[0].node.handle_update_fail_malformed_htlc(&nodes[1].node.get_our_node_id(), &update_msg);
- if let Err(msgs::HandleError{err, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) = err {
+ if let Err(msgs::LightningError{err, action: msgs::ErrorAction::SendErrorMessage {..}}) = err {
assert_eq!(err, "Got update_fail_malformed_htlc with BADONION not set");
} else {
assert!(false);
//BOLT 2 Requirement: a receiving node which has an outgoing HTLC canceled by update_fail_malformed_htlc:
// * MUST return an error in the update_fail_htlc sent to the link which originally sent the HTLC, using the failure_code given and setting the data to sha256_of_onion.
- let mut nodes = create_network(3);
- create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
- create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1000000, 1000000);
+ let mut nodes = create_network(3, &[None, None, None]);
+ create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, LocalFeatures::new(), LocalFeatures::new());
+ create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1000000, 1000000, LocalFeatures::new(), LocalFeatures::new());
let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 100000, TEST_FINAL_CLTV).unwrap();
let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
check_added_monitors!(nodes[1], 1);
}
+
+fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) {
+ // Dust-HTLC failure updates must be delayed until failure-trigger tx (in this case local commitment) reach ANTI_REORG_DELAY
+ // We can have at most two valid local commitment tx, so both cases must be covered, and both txs must be checked to get them all as
+ // HTLC could have been removed from lastest local commitment tx but still valid until we get remote RAA
+
+ let nodes = create_network(2, &[None, None]);
+ let chan =create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+
+ let bs_dust_limit = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().our_dust_limit_satoshis;
+
+ // We route 2 dust-HTLCs between A and B
+ let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000);
+ let (_, payment_hash_2) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000);
+ route_payment(&nodes[0], &[&nodes[1]], 1000000);
+
+ // Cache one local commitment tx as previous
+ let as_prev_commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
+
+ // Fail one HTLC to prune it in the will-be-latest-local commitment tx
+ assert!(nodes[1].node.fail_htlc_backwards(&payment_hash_2));
+ check_added_monitors!(nodes[1], 0);
+ expect_pending_htlcs_forwardable!(nodes[1]);
+ check_added_monitors!(nodes[1], 1);
+
+ let remove = 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(), &remove.update_fail_htlcs[0]).unwrap();
+ nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &remove.commitment_signed).unwrap();
+ check_added_monitors!(nodes[0], 1);
+
+ // Cache one local commitment tx as lastest
+ let as_last_commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
+
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ match events[0] {
+ MessageSendEvent::SendRevokeAndACK { node_id, .. } => {
+ assert_eq!(node_id, nodes[1].node.get_our_node_id());
+ },
+ _ => panic!("Unexpected event"),
+ }
+ match events[1] {
+ MessageSendEvent::UpdateHTLCs { node_id, .. } => {
+ assert_eq!(node_id, nodes[1].node.get_our_node_id());
+ },
+ _ => panic!("Unexpected event"),
+ }
+
+ assert_ne!(as_prev_commitment_tx, as_last_commitment_tx);
+ // Fail the 2 dust-HTLCs, move their failure in maturation buffer (htlc_updated_waiting_threshold_conf)
+ let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ if announce_latest {
+ nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&as_last_commitment_tx[0]], &[1; 1]);
+ } else {
+ nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&as_prev_commitment_tx[0]], &[1; 1]);
+ }
+
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+ _ => panic!("Unexpected event"),
+ }
+
+ assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
+ connect_blocks(&nodes[0].chain_monitor, ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
+ let events = nodes[0].node.get_and_clear_pending_events();
+ // Only 2 PaymentFailed events should show up, over-dust HTLC has to be failed by timeout tx
+ assert_eq!(events.len(), 2);
+ let mut first_failed = false;
+ for event in events {
+ match event {
+ Event::PaymentFailed { payment_hash, .. } => {
+ if payment_hash == payment_hash_1 {
+ assert!(!first_failed);
+ first_failed = true;
+ } else {
+ assert_eq!(payment_hash, payment_hash_2);
+ }
+ }
+ _ => panic!("Unexpected event"),
+ }
+ }
+}
+
+#[test]
+fn test_failure_delay_dust_htlc_local_commitment() {
+ do_test_failure_delay_dust_htlc_local_commitment(true);
+ 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 nodes = create_network(2, &[None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+
+ // 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().our_dust_limit_satoshis;
+ let bs_dust_limit = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().our_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, 1, &[&dummy_tx], &[1;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].chain_monitor, 20, 1, true, header.bitcoin_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
+ // Broadcast of remote commitment tx, trigger failure-update of dust-HTLCs
+ // Broadcast of timeout tx on remote commitment tx, trigger failure-udate of non-dust HTLCs
+ // Broadcast of local commitment tx, trigger failure-update of dust-HTLCs
+ // Broadcast of HTLC-timeout tx on local commitment tx, trigger failure-update of non-dust HTLCs
+
+ let nodes = create_network(3, &[None, None, None]);
+ let chan = create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+
+ let bs_dust_limit = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().our_dust_limit_satoshis;
+
+ let (_payment_preimage_1, dust_hash) = route_payment(&nodes[0], &[&nodes[1]], bs_dust_limit*1000);
+ let (_payment_preimage_2, non_dust_hash) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
+
+ let as_commitment_tx = nodes[0].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
+ let bs_commitment_tx = nodes[1].node.channel_state.lock().unwrap().by_id.get(&chan.2).unwrap().last_local_commitment_txn.clone();
+
+ // We revoked bs_commitment_tx
+ if revoked {
+ let (payment_preimage_3, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
+ claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_3, 1_000_000);
+ }
+
+ let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ let mut timeout_tx = Vec::new();
+ if local {
+ // We fail dust-HTLC 1 by broadcast of local commitment tx
+ nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&as_commitment_tx[0]], &[1; 1]);
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+ _ => panic!("Unexpected event"),
+ }
+ assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
+ timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone());
+ let parent_hash = connect_blocks(&nodes[0].chain_monitor, ANTI_REORG_DELAY - 1, 2, true, header.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, dust_hash);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ assert_eq!(timeout_tx[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
+ // We fail non-dust-HTLC 2 by broadcast of local HTLC-timeout tx on local commitment tx
+ let header_2 = BlockHeader { version: 0x20000000, prev_blockhash: parent_hash, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
+ nodes[0].chain_monitor.block_connected_checked(&header_2, 7, &[&timeout_tx[0]], &[1; 1]);
+ let header_3 = BlockHeader { version: 0x20000000, prev_blockhash: header_2.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ connect_blocks(&nodes[0].chain_monitor, ANTI_REORG_DELAY - 1, 8, true, header_3.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, non_dust_hash);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ } else {
+ // We fail dust-HTLC 1 by broadcast of remote commitment tx. If revoked, fail also non-dust HTLC
+ nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&bs_commitment_tx[0]], &[1; 1]);
+ assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+ _ => panic!("Unexpected event"),
+ }
+ timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone());
+ let parent_hash = connect_blocks(&nodes[0].chain_monitor, ANTI_REORG_DELAY - 1, 2, true, header.bitcoin_hash());
+ let header_2 = BlockHeader { version: 0x20000000, prev_blockhash: parent_hash, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ if !revoked {
+ 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, dust_hash);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ assert_eq!(timeout_tx[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
+ // We fail non-dust-HTLC 2 by broadcast of local timeout tx on remote commitment tx
+ nodes[0].chain_monitor.block_connected_checked(&header_2, 7, &[&timeout_tx[0]], &[1; 1]);
+ assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0);
+ let header_3 = BlockHeader { version: 0x20000000, prev_blockhash: header_2.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+ connect_blocks(&nodes[0].chain_monitor, ANTI_REORG_DELAY - 1, 8, true, header_3.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, non_dust_hash);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ } else {
+ // If revoked, both dust & non-dust HTLCs should have been failed after ANTI_REORG_DELAY confs of revoked
+ // commitment tx
+ let events = nodes[0].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 2);
+ let first;
+ match events[0] {
+ Event::PaymentFailed { payment_hash, .. } => {
+ if payment_hash == dust_hash { first = true; }
+ else { first = false; }
+ },
+ _ => panic!("Unexpected event"),
+ }
+ match events[1] {
+ Event::PaymentFailed { payment_hash, .. } => {
+ if first { assert_eq!(payment_hash, non_dust_hash); }
+ else { assert_eq!(payment_hash, dust_hash); }
+ },
+ _ => panic!("Unexpected event"),
+ }
+ }
+ }
+}
+
+#[test]
+fn test_sweep_outbound_htlc_failure_update() {
+ do_test_sweep_outbound_htlc_failure_update(false, true);
+ do_test_sweep_outbound_htlc_failure_update(false, false);
+ do_test_sweep_outbound_htlc_failure_update(true, false);
+}
+
+#[test]
+fn test_upfront_shutdown_script() {
+ // BOLT 2 : Option upfront shutdown script, if peer commit its closing_script at channel opening
+ // enforce it at shutdown message
+
+ let mut config = UserConfig::new();
+ config.channel_options.announced_channel = true;
+ config.peer_channel_config_limits.force_announced_channel_preference = false;
+ config.channel_options.commit_upfront_shutdown_pubkey = false;
+ let nodes = create_network(3, &[None, Some(config), None]);
+
+ // We test that in case of peer committing upfront to a script, if it changes at closing, we refuse to sign
+ let flags = LocalFeatures::new();
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
+ nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ let mut node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
+ node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
+ // Test we enforce upfront_scriptpbukey if by providing a diffrent one at closing that we disconnect peer
+ if let Err(error) = nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown) {
+ match error.action {
+ ErrorAction::SendErrorMessage { msg } => {
+ assert_eq!(msg.data,"Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey");
+ },
+ _ => { assert!(false); }
+ }
+ } else { assert!(false); }
+ let events = nodes[2].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+ _ => panic!("Unexpected event"),
+ }
+
+ // We test that in case of peer committing upfront to a script, if it doesn't change at closing, we sign
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone());
+ nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
+ // We test that in case of peer committing upfront to a script, if it oesn't change at closing, we sign
+ if let Ok(_) = nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown) {}
+ else { assert!(false) }
+ let events = nodes[2].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::SendShutdown { node_id, .. } => { assert_eq!(node_id, nodes[0].node.get_our_node_id()) }
+ _ => panic!("Unexpected event"),
+ }
+
+ // We test that if case of peer non-signaling we don't enforce committed script at channel opening
+ let mut flags_no = LocalFeatures::new();
+ flags_no.unset_upfront_shutdown_script();
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags_no, flags.clone());
+ nodes[0].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ let mut node_1_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
+ node_1_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
+ if let Ok(_) = nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_1_shutdown) {}
+ else { assert!(false) }
+ let events = nodes[1].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::SendShutdown { node_id, .. } => { assert_eq!(node_id, nodes[0].node.get_our_node_id()) }
+ _ => panic!("Unexpected event"),
+ }
+
+ // We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
+ // channel smoothly, opt-out is from channel initiator here
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 1000000, 1000000, flags.clone(), flags.clone());
+ nodes[1].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ let mut node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
+ node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
+ if let Ok(_) = nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown) {}
+ else { assert!(false) }
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::SendShutdown { node_id, .. } => { assert_eq!(node_id, nodes[1].node.get_our_node_id()) }
+ _ => panic!("Unexpected event"),
+ }
+
+ //// We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close
+ //// channel smoothly
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags.clone(), flags.clone());
+ nodes[1].node.close_channel(&OutPoint::new(chan.3.txid(), 0).to_channel_id()).unwrap();
+ let mut node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
+ node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh();
+ if let Ok(_) = nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown) {}
+ else { assert!(false) }
+ let events = nodes[0].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 2);
+ match events[0] {
+ MessageSendEvent::SendShutdown { node_id, .. } => { assert_eq!(node_id, nodes[1].node.get_our_node_id()) }
+ _ => panic!("Unexpected event"),
+ }
+ match events[1] {
+ MessageSendEvent::SendClosingSigned { node_id, .. } => { assert_eq!(node_id, nodes[1].node.get_our_node_id()) }
+ _ => panic!("Unexpected event"),
+ }
+}
+
+#[test]
+fn test_user_configurable_csv_delay() {
+ // We test our channel constructors yield errors when we pass them absurd csv delay
+
+ let mut low_our_to_self_config = UserConfig::new();
+ low_our_to_self_config.own_channel_config.our_to_self_delay = 6;
+ let mut high_their_to_self_config = UserConfig::new();
+ high_their_to_self_config.peer_channel_config_limits.their_to_self_delay = 100;
+ let nodes = create_network(2, &[Some(high_their_to_self_config.clone()), None]);
+
+ // We test config.our_to_self > BREAKDOWN_TIMEOUT is enforced in Channel::new_outbound()
+ let keys_manager: Arc<KeysInterface> = Arc::new(KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new()), 10, 20));
+ if let Err(error) = Channel::new_outbound(&test_utils::TestFeeEstimator { sat_per_kw: 253 }, &keys_manager, nodes[1].node.get_our_node_id(), 1000000, 1000000, 0, Arc::new(test_utils::TestLogger::new()), &low_our_to_self_config) {
+ match error {
+ APIError::APIMisuseError { err } => { assert_eq!(err, "Configured with an unreasonable our_to_self_delay putting user funds at risks"); },
+ _ => panic!("Unexpected event"),
+ }
+ } else { assert!(false) }
+
+ // We test config.our_to_self > BREAKDOWN_TIMEOUT is enforced in Channel::new_from_req()
+ nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42).unwrap();
+ let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
+ open_channel.to_self_delay = 200;
+ if let Err(error) = Channel::new_from_req(&test_utils::TestFeeEstimator { sat_per_kw: 253 }, &keys_manager, nodes[1].node.get_our_node_id(), LocalFeatures::new(), &open_channel, 0, Arc::new(test_utils::TestLogger::new()), &low_our_to_self_config) {
+ match error {
+ ChannelError::Close(err) => { assert_eq!(err, "Configured with an unreasonable our_to_self_delay putting user funds at risks"); },
+ _ => panic!("Unexpected event"),
+ }
+ } else { assert!(false); }
+
+ // We test msg.to_self_delay <= config.their_to_self_delay is enforced in Chanel::accept_channel()
+ nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1000000, 1000000, 42).unwrap();
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), LocalFeatures::new(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id())).unwrap();
+ let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+ accept_channel.to_self_delay = 200;
+ if let Err(error) = nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), LocalFeatures::new(), &accept_channel) {
+ match error.action {
+ ErrorAction::SendErrorMessage { msg } => {
+ assert_eq!(msg.data,"They wanted our payments to be delayed by a needlessly long period");
+ },
+ _ => { assert!(false); }
+ }
+ } else { assert!(false); }
+
+ // We test msg.to_self_delay <= config.their_to_self_delay is enforced in Channel::new_from_req()
+ nodes[1].node.create_channel(nodes[0].node.get_our_node_id(), 1000000, 1000000, 42).unwrap();
+ let mut open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
+ open_channel.to_self_delay = 200;
+ if let Err(error) = Channel::new_from_req(&test_utils::TestFeeEstimator { sat_per_kw: 253 }, &keys_manager, nodes[1].node.get_our_node_id(), LocalFeatures::new(), &open_channel, 0, Arc::new(test_utils::TestLogger::new()), &high_their_to_self_config) {
+ match error {
+ ChannelError::Close(err) => { assert_eq!(err, "They wanted our payments to be delayed by a needlessly long period"); },
+ _ => panic!("Unexpected event"),
+ }
+ } else { assert!(false); }
+}
+
+#[test]
+fn test_data_loss_protect() {
+ // We want to be sure that :
+ // * we don't broadcast our Local Commitment Tx in case of fallen behind
+ // * we close channel in case of detecting other being fallen behind
+ // * we are able to claim our own outputs thanks to remote my_current_per_commitment_point
+ let mut nodes = create_network(2, &[None, None]);
+
+ let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, LocalFeatures::new(), LocalFeatures::new());
+
+ // 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();
+
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000, 8_000_000);
+
+ 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);
+
+ // Restore node A from previous state
+ let logger: Arc<Logger> = Arc::new(test_utils::TestLogger::with_id(format!("node {}", 0)));
+ let chan_monitor = <(Sha256dHash, ChannelMonitor)>::read(&mut ::std::io::Cursor::new(previous_chan_monitor_state.0), Arc::clone(&logger)).unwrap().1;
+ let chain_monitor = Arc::new(ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&logger)));
+ let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())});
+ let feeest = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 });
+ let monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone(), logger.clone(), feeest.clone()));
+ let mut channel_monitors = HashMap::new();
+ channel_monitors.insert(OutPoint { txid: chan.3.txid(), index: 0 }, &chan_monitor);
+ let node_state_0 = <(Sha256dHash, ChannelManager)>::read(&mut ::std::io::Cursor::new(previous_node_state), ChannelManagerReadArgs {
+ keys_manager: Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::clone(&logger), 42, 21)),
+ fee_estimator: feeest.clone(),
+ monitor: monitor.clone(),
+ chain_monitor: chain_monitor.clone(),
+ logger: Arc::clone(&logger),
+ tx_broadcaster,
+ default_config: UserConfig::new(),
+ channel_monitors: &channel_monitors
+ }).unwrap().1;
+ nodes[0].node = Arc::new(node_state_0);
+ monitor.add_update_monitor(OutPoint { txid: chan.3.txid(), index: 0 }, chan_monitor.clone()).is_ok();
+ nodes[0].chan_monitor = monitor;
+ nodes[0].chain_monitor = chain_monitor;
+ check_added_monitors!(nodes[0], 1);
+
+ nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id());
+ nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id());
+
+ let reestablish_0 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
+
+ // Check we update monitor following learning of per_commitment_point from B
+ if let Err(err) = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_0[0]) {
+ match err.action {
+ ErrorAction::SendErrorMessage { msg } => {
+ assert_eq!(msg.data, "We have fallen behind - we have received proof that if we broadcast remote is going to claim our funds - we can't do any automated broadcasting");
+ },
+ _ => panic!("Unexpected event!"),
+ }
+ } else { assert!(false); }
+ check_added_monitors!(nodes[0], 1);
+
+ {
+ let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
+ assert_eq!(node_txn.len(), 0);
+ }
+
+ let mut reestablish_1 = Vec::with_capacity(1);
+ for msg in nodes[0].node.get_and_clear_pending_msg_events() {
+ if let MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } = msg {
+ assert_eq!(*node_id, nodes[1].node.get_our_node_id());
+ reestablish_1.push(msg.clone());
+ } else if let MessageSendEvent::BroadcastChannelUpdate { .. } = msg {
+ } else {
+ panic!("Unexpected event")
+ }
+ }
+
+ // Check we close channel detecting A is fallen-behind
+ if let Err(err) = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]) {
+ match err.action {
+ ErrorAction::SendErrorMessage { msg } => {
+ assert_eq!(msg.data, "Peer attempted to reestablish channel with a very old local commitment transaction"); },
+ _ => panic!("Unexpected event!"),
+ }
+ } else { assert!(false); }
+
+ let events = nodes[1].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::BroadcastChannelUpdate { .. } => {},
+ _ => panic!("Unexpected event"),
+ }
+
+ // Check A is able to claim to_remote output
+ let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
+ assert_eq!(node_txn.len(), 1);
+ check_spends!(node_txn[0], chan.3.clone());
+ 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].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()]}, 1);
+ let spend_txn = check_spendable_outputs!(nodes[0], 1);
+ assert_eq!(spend_txn.len(), 1);
+ check_spends!(spend_txn[0], node_txn[0].clone());
+}
+
+#[test]
+fn test_check_htlc_underpaying() {
+ // Send payment through A -> B but A is maliciously
+ // sending a probe payment (i.e less than expected value0
+ // to B, B should refuse payment.
+
+ let nodes = create_network(2, &[None, None, None]);
+
+ // Create some initial channels
+ create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
+
+ let (payment_preimage, _) = route_payment(&nodes[0], &[&nodes[1]], 10_000);
+
+ // Node 3 is expecting payment of 100_000 but receive 10_000,
+ // fail htlc like we didn't know the preimage.
+ nodes[1].node.claim_funds(payment_preimage, 100_000);
+ nodes[1].node.process_pending_htlc_forwards();
+
+ let events = nodes[1].node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ let (update_fail_htlc, commitment_signed) = match events[0] {
+ MessageSendEvent::UpdateHTLCs { node_id: _ , updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
+ assert!(update_add_htlcs.is_empty());
+ assert!(update_fulfill_htlcs.is_empty());
+ assert_eq!(update_fail_htlcs.len(), 1);
+ assert!(update_fail_malformed_htlcs.is_empty());
+ assert!(update_fee.is_none());
+ (update_fail_htlcs[0].clone(), commitment_signed)
+ },
+ _ => panic!("Unexpected event"),
+ };
+ check_added_monitors!(nodes[1], 1);
+
+ nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlc).unwrap();
+ commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true);
+
+ let events = nodes[0].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ if let &Event::PaymentFailed { payment_hash:_, ref rejected_by_dest, ref error_code } = &events[0] {
+ assert_eq!(*rejected_by_dest, true);
+ assert_eq!(error_code.unwrap(), 0x4000|15);
+ } else {
+ panic!("Unexpected event");
+ }
+ nodes[1].node.get_and_clear_pending_events();
+}