//! 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::HandleError{ err: error_str, action: Some(msgs::ErrorAction::SendErrorMessage {..})}) => {
+ assert_eq!(error_str, expected_error_str, "unexpected HandleError string (expected `{}`, actual `{}`)", expected_error_str, error_str)
+ },
+ Err(msgs::HandleError{..}) => {panic!("unexpected HandleError 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
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
#[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
#[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();
#[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);
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);
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);
claim_payment(&nodes[1], &vec!(&nodes[2], &nodes[3], &nodes[1])[..], payment_preimage_1);
// 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;
// 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 {
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);
}
fn do_channel_reserve_test(test_recv: bool) {
- use util::rng;
use std::sync::atomic::Ordering;
use ln::msgs::HandleError;
- 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"),
}
}
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!");
{
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"),
}
}
// 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.
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);
{
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]);
}
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;
// 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;
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);
#[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);
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);
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);
// 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);
// \ \
// 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);
}
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![timeout_tx]}, 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]);
// 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 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 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);
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();
#[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);
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);
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);
#[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);
#[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,
#[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);
#[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;
#[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();
#[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();
#[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();
// 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);
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;
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, 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());
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();
// - 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);
} 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);
let closing_tx = close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true).2;
}
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 });
}
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();
}
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
}, || {}, 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);
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);
}
#[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();
#[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;
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!");
#[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();
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");
+ 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();
//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();
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]);
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]);
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]);
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;
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;
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();
//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);
+
+ 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);
+ claim_payment(&nodes[1], &vec!(&nodes[0])[..], preimage_2);
+}
+
+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);
+ }
+
+ 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) {
+ if let Some(error) = error.action {
+ match error {
+ 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); }
+ } 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) {
+ if let Some(error) = error.action {
+ match error {
+ ErrorAction::SendErrorMessage { msg } => {
+ assert_eq!(msg.data,"They wanted our payments to be delayed by a needlessly long period");
+ },
+ _ => { assert!(false); }
+ }
+ } else { 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);
+ send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000);
+
+ 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]) {
+ if let Some(error) = err.action {
+ match error {
+ 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); }
+ } 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]) {
+ if let Some(error) = err.action {
+ match error {
+ 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); }
+ } 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());
+}