#![cfg_attr(rustfmt, rustfmt_skip)]
use crate::chain::{BlockLocator, ChannelMonitorUpdateStatus, Watch};
use crate::chain::chaininterface::LowerBoundedFeeEstimator;
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateStep};
use crate::routing::router::{PaymentParameters, RouteParameters};
use crate::sign::EntropySource;
use crate::chain::transaction::OutPoint;
use crate::events::{ClosureReason, Event, HTLCHandlingFailureType};
use crate::ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId, RAACommitmentOrder};
use crate::ln::outbound_payment::RecipientOnionFields;
use crate::ln::msgs;
use crate::ln::types::ChannelId;
use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, RoutingMessageHandler, ErrorAction, MessageSendEvent};
use crate::util::test_channel_signer::TestChannelSigner;
use crate::util::test_utils;
use crate::util::errors::APIError;
use crate::util::ser::{Writeable, ReadableArgs};
use crate::util::config::{HTLCInterceptionFlags, UserConfig};
use bitcoin::hashes::Hash;
use types::payment::{PaymentHash, PaymentPreimage};
use crate::prelude::*;
use crate::ln::functional_test_utils::*;
#[test]
fn test_funding_peer_disconnect() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes_0_deserialized;
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
confirm_transaction(&nodes[0], &tx);
let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
assert!(events_1.is_empty());
let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]);
reconnect_args.send_channel_ready.1 = true;
reconnect_nodes(reconnect_args);
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
confirm_transaction(&nodes[1], &tx);
let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
assert!(events_2.is_empty());
nodes[0].node.peer_connected(nodes[1].node.get_our_node_id(), &msgs::Init {
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
let as_reestablish = get_chan_reestablish_msgs!(nodes[0], nodes[1]).pop().unwrap();
nodes[1].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]).pop().unwrap();
nodes[0].node.handle_channel_reestablish(nodes[1].node.get_our_node_id(), &bs_reestablish);
let events_3 = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events_3.len(), 1);
let as_channel_ready = match events_3[0] {
MessageSendEvent::SendChannelReady { ref node_id, ref msg } => {
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
msg.clone()
},
_ => panic!("Unexpected event {:?}", events_3[0]),
};
nodes[1].node.handle_channel_reestablish(nodes[0].node.get_our_node_id(), &as_reestablish);
let events_4 = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events_4.len(), 3);
let chan_id;
let bs_channel_ready = match events_4[0] {
MessageSendEvent::SendChannelReady { ref node_id, ref msg } => {
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
chan_id = msg.channel_id;
msg.clone()
},
_ => panic!("Unexpected event {:?}", events_4[0]),
};
let bs_announcement_sigs = match events_4[1] {
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
msg.clone()
},
_ => panic!("Unexpected event {:?}", events_4[1]),
};
match events_4[2] {
MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } => {
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
},
_ => panic!("Unexpected event {:?}", events_4[2]),
}
nodes[1].node.handle_channel_ready(nodes[0].node.get_our_node_id(), &as_channel_ready);
let events_5 = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events_5.len(), 1);
match events_5[0] {
MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } => {
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
},
_ => panic!("Unexpected event {:?}", events_5[0]),
};
nodes[0].node.handle_channel_ready(nodes[1].node.get_our_node_id(), &bs_channel_ready);
let events_6 = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events_6.len(), 1);
let as_announcement_sigs = match events_6[0] {
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
msg.clone()
},
_ => panic!("Unexpected event {:?}", events_6[0]),
};
expect_channel_ready_event(&nodes[0], &nodes[1].node.get_our_node_id());
expect_channel_ready_event(&nodes[1], &nodes[0].node.get_our_node_id());
nodes[0].node.handle_announcement_signatures(nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
let events_7 = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events_7.len(), 1);
let (chan_announcement, as_update) = match events_7[0] {
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
(msg.clone(), update_msg.clone().unwrap())
},
_ => panic!("Unexpected event {:?}", events_7[0]),
};
nodes[1].node.handle_announcement_signatures(nodes[0].node.get_our_node_id(), &as_announcement_sigs);
let events_8 = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events_8.len(), 1);
let bs_update = match events_8[0] {
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
assert_eq!(*msg, chan_announcement);
update_msg.clone().unwrap()
},
_ => panic!("Unexpected event {:?}", events_8[0]),
};
let node_1_pubkey = nodes[1].node.get_our_node_id();
nodes[0].gossip_sync.handle_channel_announcement(Some(node_1_pubkey), &chan_announcement).unwrap();
nodes[0].gossip_sync.handle_channel_update(Some(node_1_pubkey), &bs_update).unwrap();
nodes[0].gossip_sync.handle_channel_update(Some(node_1_pubkey), &as_update).unwrap();
let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000).0;
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
reload_node!(nodes[0], &nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1]));
}
#[test]
fn test_no_txn_manager_serialize_deserialize() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes_0_deserialized;
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001);
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
let chan_0_monitor_serialized =
get_monitor!(nodes[0], ChannelId::v1_from_funding_outpoint(OutPoint { txid: tx.compute_txid(), index: 0 })).encode();
reload_node!(nodes[0], nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
nodes[0].node.peer_connected(nodes[1].node.get_our_node_id(), &msgs::Init {
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
nodes[1].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
nodes[1].node.handle_channel_reestablish(nodes[0].node.get_our_node_id(), &reestablish_1[0]);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
nodes[0].node.handle_channel_reestablish(nodes[1].node.get_our_node_id(), &reestablish_2[0]);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
let (channel_ready, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
for (i, node) in nodes.iter().enumerate() {
let counterparty_node_id = nodes[(i + 1) % 2].node.get_our_node_id();
assert!(node.gossip_sync.handle_channel_announcement(Some(counterparty_node_id), &announcement).unwrap());
node.gossip_sync.handle_channel_update(Some(counterparty_node_id), &as_update).unwrap();
node.gossip_sync.handle_channel_update(Some(counterparty_node_id), &bs_update).unwrap();
}
send_payment(&nodes[0], &[&nodes[1]], 1000000);
}
#[test]
fn test_manager_serialize_deserialize_events() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes_0_deserialized;
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel_value = 100000;
let push_msat = 10001;
let node_a = nodes.remove(0);
let node_b = nodes.remove(0);
node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None, None).unwrap();
handle_and_accept_open_channel(&node_b, node_a.node.get_our_node_id(), &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id()));
node_a.node.handle_accept_channel(node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id()));
let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, &node_b.node.get_our_node_id(), channel_value, 42);
node_a.node.funding_transaction_generated(temporary_channel_id, node_b.node.get_our_node_id(), tx.clone()).unwrap();
check_added_monitors(&node_a, 0);
let funding_created = get_event_msg!(node_a, MessageSendEvent::SendFundingCreated, node_b.node.get_our_node_id());
let channel_id = ChannelId::v1_from_funding_txid(
funding_created.funding_txid.as_byte_array(), funding_created.funding_output_index
);
node_b.node.handle_funding_created(node_a.node.get_our_node_id(), &funding_created);
{
let mut added_monitors = node_b.chain_monitor.added_monitors.lock().unwrap();
assert_eq!(added_monitors.len(), 1);
assert_eq!(added_monitors[0].0, channel_id);
added_monitors.clear();
}
let bs_funding_signed = get_event_msg!(node_b, MessageSendEvent::SendFundingSigned, node_a.node.get_our_node_id());
node_a.node.handle_funding_signed(node_b.node.get_our_node_id(), &bs_funding_signed);
{
let mut added_monitors = node_a.chain_monitor.added_monitors.lock().unwrap();
assert_eq!(added_monitors.len(), 1);
assert_eq!(added_monitors[0].0, channel_id);
added_monitors.clear();
}
expect_channel_pending_event(&node_a, &node_b.node.get_our_node_id());
expect_channel_pending_event(&node_b, &node_a.node.get_our_node_id());
nodes.push(node_a);
nodes.push(node_b);
let chan_0_monitor_serialized = get_monitor!(nodes[0], bs_funding_signed.channel_id).encode();
reload_node!(nodes[0], nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
let events_4 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_4.len(), 0);
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].compute_txid(), funding_output.txid);
assert_eq!(nodes[0].node.list_channels().len(), 1);
nodes[0].node.peer_connected(nodes[1].node.get_our_node_id(), &msgs::Init {
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
nodes[1].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
nodes[1].node.handle_channel_reestablish(nodes[0].node.get_our_node_id(), &reestablish_1[0]);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
nodes[0].node.handle_channel_reestablish(nodes[1].node.get_our_node_id(), &reestablish_2[0]);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
let (channel_ready, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
for (i, node) in nodes.iter().enumerate() {
let counterparty_node_id = nodes[(i + 1) % 2].node.get_our_node_id();
assert!(node.gossip_sync.handle_channel_announcement(Some(counterparty_node_id), &announcement).unwrap());
node.gossip_sync.handle_channel_update(Some(counterparty_node_id), &as_update).unwrap();
node.gossip_sync.handle_channel_update(Some(counterparty_node_id), &bs_update).unwrap();
}
send_payment(&nodes[0], &[&nodes[1]], 1000000);
}
#[test]
fn test_simple_manager_serialize_deserialize() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes_0_deserialized;
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
let (our_payment_preimage, ..) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
let (_, our_payment_hash, ..) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
let chan_0_monitor_serialized = get_monitor!(nodes[0], chan_id).encode();
reload_node!(nodes[0], nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister, new_chain_monitor, nodes_0_deserialized);
reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1]));
fail_payment(&nodes[0], &[&nodes[1]], our_payment_hash);
claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage);
}
#[test]
fn test_manager_serialize_deserialize_inconsistent_monitor() {
let chanmon_cfgs = create_chanmon_cfgs(4);
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
let logger;
let fee_estimator;
let persister;
let new_chain_monitor;
let legacy_cfg = test_legacy_channel_config();
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[Some(legacy_cfg.clone()), Some(legacy_cfg.clone()), Some(legacy_cfg.clone()), Some(legacy_cfg)]);
let nodes_0_deserialized;
let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
let chan_id_2 = create_announced_chan_between_nodes(&nodes, 2, 0).2;
let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3);
let mut node_0_stale_monitors_serialized = Vec::new();
for chan_id_iter in &[chan_id_1, chan_id_2, channel_id] {
let mut writer = test_utils::TestVecWriter(Vec::new());
get_monitor!(nodes[0], *chan_id_iter).write(&mut writer).unwrap();
node_0_stale_monitors_serialized.push(writer.0);
}
let (our_payment_preimage, ..) = route_payment(&nodes[2], &[&nodes[0], &nodes[1]], 1000000);
let nodes_0_serialized = nodes[0].node.encode();
route_payment(&nodes[0], &[&nodes[3]], 1000000);
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
nodes[2].node.peer_disconnected(nodes[0].node.get_our_node_id());
nodes[3].node.peer_disconnected(nodes[0].node.get_our_node_id());
let mut node_0_monitors_serialized = Vec::new();
for chan_id_iter in &[chan_id_1, chan_id_2, channel_id] {
node_0_monitors_serialized.push(get_monitor!(nodes[0], *chan_id_iter).encode());
}
logger = test_utils::TestLogger::new();
fee_estimator = test_utils::TestFeeEstimator::new(253);
persister = test_utils::TestPersister::new();
let keys_manager = &chanmon_cfgs[0].keys_manager;
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster, &logger, &fee_estimator, &persister, keys_manager);
nodes[0].chain_monitor = &new_chain_monitor;
let mut node_0_stale_monitors = Vec::new();
for serialized in node_0_stale_monitors_serialized.iter() {
let mut read = &serialized[..];
let (_, monitor) = <(BlockLocator, ChannelMonitor<TestChannelSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
assert!(read.is_empty());
node_0_stale_monitors.push(monitor);
}
let mut node_0_monitors = Vec::new();
for serialized in node_0_monitors_serialized.iter() {
let mut read = &serialized[..];
let (_, monitor) = <(BlockLocator, ChannelMonitor<TestChannelSigner>)>::read(&mut read, (keys_manager, keys_manager)).unwrap();
assert!(read.is_empty());
node_0_monitors.push(monitor);
}
let mut nodes_0_read = &nodes_0_serialized[..];
if let Err(msgs::DecodeError::DangerousValue) =
<(BlockLocator, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestMessageRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
config: UserConfig::default(),
entropy_source: keys_manager,
node_signer: keys_manager,
signer_provider: keys_manager,
fee_estimator: &fee_estimator,
router: &nodes[0].router,
message_router: &nodes[0].message_router,
chain_monitor: nodes[0].chain_monitor,
tx_broadcaster: nodes[0].tx_broadcaster,
logger: &logger,
channel_monitors: node_0_stale_monitors.iter().map(|monitor| { (monitor.channel_id(), monitor) }).collect(),
reconstruct_manager_from_monitors: None,
}) { } else {
panic!("If the monitor(s) are stale, this indicates a bug and we should get an Err return");
};
let mut nodes_0_read = &nodes_0_serialized[..];
let (_, nodes_0_deserialized_tmp) =
<(BlockLocator, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestRouter, &test_utils::TestMessageRouter, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
config: UserConfig::default(),
entropy_source: keys_manager,
node_signer: keys_manager,
signer_provider: keys_manager,
fee_estimator: &fee_estimator,
router: nodes[0].router,
message_router: &nodes[0].message_router,
chain_monitor: nodes[0].chain_monitor,
tx_broadcaster: nodes[0].tx_broadcaster,
logger: &logger,
channel_monitors: node_0_monitors.iter().map(|monitor| { (monitor.channel_id(), monitor) }).collect(),
reconstruct_manager_from_monitors: None,
}).unwrap();
nodes_0_deserialized = nodes_0_deserialized_tmp;
assert!(nodes_0_read.is_empty());
for monitor in node_0_monitors.drain(..) {
assert_eq!(nodes[0].chain_monitor.watch_channel(monitor.channel_id(), monitor),
Ok(ChannelMonitorUpdateStatus::Completed));
check_added_monitors(&nodes[0], 1);
}
nodes[0].node = &nodes_0_deserialized;
check_closed_event(&nodes[0], 1, ClosureReason::OutdatedChannelManager, &[nodes[3].node.get_our_node_id()], 100000);
{ nodes[0].node.timer_tick_occurred();
let txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
assert_eq!(txn.len(), 1);
check_spends!(txn[0], funding_tx);
assert_eq!(txn[0].input[0].previous_output.txid, funding_tx.compute_txid());
}
check_added_monitors(&nodes[0], 1);
reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1]));
reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[2]));
claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage);
nodes[3].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
let reestablish = get_chan_reestablish_msgs!(nodes[3], nodes[0]).pop().unwrap();
nodes[0].node.peer_connected(nodes[3].node.get_our_node_id(), &msgs::Init {
features: nodes[3].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
nodes[0].node.handle_channel_reestablish(nodes[3].node.get_our_node_id(), &reestablish);
let mut found_err = false;
for msg_event in nodes[0].node.get_and_clear_pending_msg_events() {
if let MessageSendEvent::HandleError { ref action, .. } = msg_event {
match action {
&ErrorAction::SendErrorMessage { ref msg } => {
assert_eq!(msg.channel_id, channel_id);
assert!(!found_err);
found_err = true;
},
_ => panic!("Unexpected event!"),
}
}
}
assert!(found_err);
}
#[cfg(feature = "std")]
fn do_test_data_loss_protect(reconnect_panicing: bool, substantially_old: bool, not_stale: bool) {
use crate::ln::outbound_payment::Retry;
use crate::types::string::UntrustedString;
let mut chanmon_cfgs = create_chanmon_cfgs(2);
chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true;
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let legacy_cfg = test_legacy_channel_config();
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(legacy_cfg.clone()), Some(legacy_cfg)]);
let nodes_0_deserialized;
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
let previous_node_state = nodes[0].node.encode();
let previous_chain_monitor_state = get_monitor!(nodes[0], chan.2).encode();
assert!(!substantially_old || !not_stale, "substantially_old and not_stale doesn't make sense");
if not_stale || !substantially_old {
let pay_params = PaymentParameters::for_keysend(nodes[1].node.get_our_node_id(), 100, false);
let route_params = RouteParameters::from_payment_params_and_value(pay_params, 40000);
nodes[0].node.send_spontaneous_payment(None, RecipientOnionFields::spontaneous_empty(40000), PaymentId([0; 32]), route_params, Retry::Attempts(0)).unwrap();
check_added_monitors(&nodes[0], 1);
let update_add_commit = SendEvent::from_node(&nodes[0]);
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &update_add_commit.msgs[0]);
nodes[1].node.handle_commitment_signed_batch_test(nodes[0].node.get_our_node_id(), &update_add_commit.commitment_msg);
check_added_monitors(&nodes[1], 1);
let (raa, cs) = get_revoke_commit_msgs(&nodes[1], &nodes[0].node.get_our_node_id());
nodes[0].node.handle_revoke_and_ack(nodes[1].node.get_our_node_id(), &raa);
check_added_monitors(&nodes[0], 1);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
if !not_stale {
nodes[0].node.handle_commitment_signed_batch_test(nodes[1].node.get_our_node_id(), &cs);
check_added_monitors(&nodes[0], 1);
let raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
nodes[1].node.handle_revoke_and_ack(nodes[0].node.get_our_node_id(), &raa);
check_added_monitors(&nodes[1], 1);
expect_htlc_failure_conditions(nodes[1].node.get_and_clear_pending_events(), &[]);
}
} else {
send_payment(&nodes[0], &[&nodes[1]], 8000000);
send_payment(&nodes[0], &[&nodes[1]], 8000000);
}
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
reload_node!(nodes[0], previous_node_state, &[&previous_chain_monitor_state], persister, new_chain_monitor, nodes_0_deserialized);
if reconnect_panicing {
nodes[0].node.peer_connected(nodes[1].node.get_our_node_id(), &msgs::Init {
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
nodes[1].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
nodes[1].node.handle_channel_reestablish(nodes[0].node.get_our_node_id(), &reestablish_1[0]);
let reestablish_msg;
if substantially_old {
let warn_msg = "Peer attempted to reestablish channel with a very old local commitment transaction: 0 (received) vs 4 (expected)".to_owned();
let warn_reestablish = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(warn_reestablish.len(), 2);
match warn_reestablish[1] {
MessageSendEvent::HandleError { action: ErrorAction::SendWarningMessage { ref msg, .. }, .. } => {
assert_eq!(msg.data, warn_msg);
},
_ => panic!("Unexpected events: {:?}", warn_reestablish),
}
reestablish_msg = match &warn_reestablish[0] {
MessageSendEvent::SendChannelReestablish { msg, .. } => msg.clone(),
_ => panic!("Unexpected events: {:?}", warn_reestablish),
};
} else {
let msgs = nodes[1].node.get_and_clear_pending_msg_events();
assert!(msgs.len() >= 4);
match msgs.last() {
Some(MessageSendEvent::SendChannelUpdate { .. }) => {},
_ => panic!("Unexpected events: {:?}", msgs),
}
assert!(msgs.iter().any(|msg| matches!(msg, MessageSendEvent::SendRevokeAndACK { .. })));
assert!(msgs.iter().any(|msg| matches!(msg, MessageSendEvent::UpdateHTLCs { .. })));
reestablish_msg = match &msgs[0] {
MessageSendEvent::SendChannelReestablish { msg, .. } => msg.clone(),
_ => panic!("Unexpected events: {:?}", msgs),
};
}
{
let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
assert!(node_txn.is_empty());
}
let reconnect_res = std::panic::catch_unwind(|| {
nodes[0].node.handle_channel_reestablish(nodes[1].node.get_our_node_id(), &reestablish_msg);
});
if not_stale {
assert!(reconnect_res.is_ok());
check_closed_broadcast(&nodes[0], 1, true);
check_added_monitors(&nodes[0], 1);
check_closed_event(&nodes[0], 1, ClosureReason::ProcessingError {
err: "Peer attempted to reestablish channel with a future remote commitment transaction: 2 (received) vs 1 (expected)".to_owned()
}, &[nodes[1].node.get_our_node_id()], 1000000);
} else {
assert!(reconnect_res.is_err());
std::mem::forget(nodes);
}
} else {
let message = "Channel force-closed".to_owned();
assert!(!not_stale, "We only care about the stale case when not testing panicking");
nodes[0]
.node
.force_close_broadcasting_latest_txn(&chan.2, &nodes[1].node.get_our_node_id(), message.clone())
.unwrap();
check_added_monitors(&nodes[0], 1);
let reason =
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
check_closed_event(&nodes[0], 1, reason, &[nodes[1].node.get_our_node_id()], 1000000);
{
let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
assert_eq!(node_txn.len(), 1);
}
for msg in nodes[0].node.get_and_clear_pending_msg_events() {
if let MessageSendEvent::BroadcastChannelUpdate { .. } = msg {
} else if let MessageSendEvent::HandleError { ref action, .. } = msg {
match action {
&ErrorAction::SendErrorMessage { ref msg } => {
assert_eq!(&msg.data, "Channel force-closed");
},
_ => panic!("Unexpected event!"),
}
} else {
panic!("Unexpected event {:?}", msg)
}
}
assert!(nodes[0].node.list_usable_channels().is_empty());
nodes[0].node.peer_connected(nodes[1].node.get_our_node_id(), &msgs::Init {
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
nodes[1].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
let retry_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
nodes[0].node.handle_channel_reestablish(nodes[1].node.get_our_node_id(), &retry_reestablish[0]);
let mut err_msgs_0 = Vec::with_capacity(1);
if let MessageSendEvent::HandleError { ref action, .. } = nodes[0].node.get_and_clear_pending_msg_events()[1] {
match action {
&ErrorAction::SendErrorMessage { ref msg } => {
let peer_msg = format!(
"Got a message for a channel from the wrong node! No such channel_id {} for the passed counterparty_node_id {}",
chan.2, nodes[1].node.get_our_node_id()
);
assert_eq!(msg.data, peer_msg);
err_msgs_0.push(msg.clone());
},
_ => panic!("Unexpected event!"),
}
} else {
panic!("Unexpected event!");
}
assert_eq!(err_msgs_0.len(), 1);
nodes[1].node.handle_error(nodes[0].node.get_our_node_id(), &err_msgs_0[0]);
assert!(nodes[1].node.list_usable_channels().is_empty());
check_added_monitors(&nodes[1], 1);
let peer_msg = format!(
"Got a message for a channel from the wrong node! No such channel_id {} for the passed counterparty_node_id {}",
chan.2, nodes[1].node.get_our_node_id()
);
let reason = ClosureReason::CounterpartyForceClosed { peer_msg: UntrustedString(peer_msg) };
check_closed_event(&nodes[1], 1, reason, &[nodes[0].node.get_our_node_id()], 1000000);
check_closed_broadcast(&nodes[1], 1, false);
}
}
#[test]
#[cfg(feature = "std")]
fn test_data_loss_protect() {
do_test_data_loss_protect(true, false, true);
do_test_data_loss_protect(true, true, false);
do_test_data_loss_protect(true, false, false);
do_test_data_loss_protect(false, true, false);
do_test_data_loss_protect(false, false, false);
}
fn do_test_partial_claim_before_restart(persist_both_monitors: bool, double_restart: bool) {
let chanmon_cfgs = create_chanmon_cfgs(4);
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
let (persist_d_1, persist_d_2);
let (chain_d_1, chain_d_2);
let mut config = test_default_channel_config();
config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = 10;
let configs: [Option<UserConfig>; 4] = core::array::from_fn(|_| Some(config.clone()));
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &configs);
let (node_d_1, node_d_2);
let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100_000, 0);
let chan_id_persisted = create_announced_chan_between_nodes_with_value(&nodes, 1, 3, 100_000, 0).2;
let chan_id_not_persisted = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 100_000, 0).2;
let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[3], 15_000_000);
assert_eq!(route.paths.len(), 2);
route.paths.sort_by(|path_a, _| {
if path_a.hops[0].pubkey == nodes[1].node.get_our_node_id() {
core::cmp::Ordering::Less } else { core::cmp::Ordering::Greater }
});
nodes[0].node.send_payment_with_route(route, payment_hash,
RecipientOnionFields::secret_only(payment_secret, 15_000_000), PaymentId(payment_hash.0)).unwrap();
check_added_monitors(&nodes[0], 2);
let mut send_events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(send_events.len(), 2);
let node_1_msgs = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut send_events);
let node_2_msgs = remove_first_msg_event_to_node(&nodes[2].node.get_our_node_id(), &mut send_events);
do_pass_along_path(PassAlongPathArgs::new(&nodes[0],&[&nodes[1], &nodes[3]], 15_000_000, payment_hash, node_1_msgs)
.with_payment_secret(payment_secret)
.without_clearing_recipient_events());
do_pass_along_path(PassAlongPathArgs::new(&nodes[0], &[&nodes[2], &nodes[3]], 15_000_000, payment_hash, node_2_msgs)
.with_payment_secret(payment_secret)
.without_clearing_recipient_events());
let mut original_monitor = test_utils::TestVecWriter(Vec::new());
if !persist_both_monitors {
for channel_id in nodes[3].chain_monitor.chain_monitor.list_monitors() {
if channel_id == chan_id_not_persisted {
assert!(original_monitor.0.is_empty());
nodes[3].chain_monitor.chain_monitor.get_monitor(channel_id).unwrap().write(&mut original_monitor).unwrap();
}
}
}
let original_manager = nodes[3].node.encode();
expect_payment_claimable!(nodes[3], payment_hash, payment_secret, 15_000_000);
nodes[3].node.claim_funds(payment_preimage);
check_added_monitors(&nodes[3], 2);
expect_payment_claimed!(nodes[3], payment_hash, 15_000_000);
let mut updated_monitor = test_utils::TestVecWriter(Vec::new());
for channel_id in nodes[3].chain_monitor.chain_monitor.list_monitors() {
if channel_id == chan_id_persisted {
assert!(updated_monitor.0.is_empty());
nodes[3].chain_monitor.chain_monitor.get_monitor(channel_id).unwrap().write(&mut updated_monitor).unwrap();
}
}
if persist_both_monitors {
for channel_id in nodes[3].chain_monitor.chain_monitor.list_monitors() {
if channel_id == chan_id_not_persisted {
assert!(original_monitor.0.is_empty());
nodes[3].chain_monitor.chain_monitor.get_monitor(channel_id).unwrap().write(&mut original_monitor).unwrap();
}
}
}
reload_node!(nodes[3], original_manager.clone(), &[&updated_monitor.0, &original_monitor.0], persist_d_1, chain_d_1, node_d_1);
nodes[3].disable_monitor_completeness_assertion();
if double_restart {
reload_node!(nodes[3], node_d_1.encode(), &[&updated_monitor.0, &original_monitor.0], persist_d_2, chain_d_2, node_d_2);
nodes[3].disable_monitor_completeness_assertion();
}
assert!(get_monitor!(nodes[3], chan_id_persisted).get_stored_preimages().contains_key(&payment_hash));
assert_eq!(
get_monitor!(nodes[3], chan_id_not_persisted).get_stored_preimages().contains_key(&payment_hash),
persist_both_monitors,
);
nodes[1].node.peer_disconnected(nodes[3].node.get_our_node_id());
nodes[2].node.peer_disconnected(nodes[3].node.get_our_node_id());
let events = nodes[3].node.get_and_clear_pending_events();
assert_eq!(events.len(), if persist_both_monitors { 4 } else { 3 });
if let Event::PaymentClaimable { amount_msat: 15_000_000, .. } = events[0] { } else { panic!(); }
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[1] { } else { panic!(); }
if persist_both_monitors {
if let Event::ChannelClosed { reason: ClosureReason::OutdatedChannelManager, .. } = events[2] { } else { panic!(); }
if let Event::PaymentClaimed { amount_msat: 15_000_000, .. } = events[3] { } else { panic!(); }
check_added_monitors(&nodes[3], 4);
} else {
if let Event::PaymentClaimed { amount_msat: 15_000_000, .. } = events[2] { } else { panic!(); }
check_added_monitors(&nodes[3], 3);
}
assert!(get_monitor!(nodes[3], chan_id_persisted).get_stored_preimages().contains_key(&payment_hash));
assert!(get_monitor!(nodes[3], chan_id_not_persisted).get_stored_preimages().contains_key(&payment_hash));
if let Event::PaymentClaimed { payment_hash: our_payment_hash, amount_msat: 15_000_000, .. } =
events[if persist_both_monitors { 3 } else { 2 }]
{
assert_eq!(payment_hash, our_payment_hash);
} else { panic!(); }
assert_eq!(nodes[3].node.list_channels().len(), if persist_both_monitors { 0 } else { 1 });
if !persist_both_monitors {
nodes[3].node.peer_connected(nodes[2].node.get_our_node_id(), &msgs::Init {
features: nodes[2].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
let reestablish_1 = get_chan_reestablish_msgs!(nodes[3], nodes[2]);
nodes[2].node.peer_connected(nodes[3].node.get_our_node_id(), &msgs::Init {
features: nodes[3].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
let reestablish_2 = get_chan_reestablish_msgs!(nodes[2], nodes[3]);
nodes[2].node.handle_channel_reestablish(nodes[3].node.get_our_node_id(), &reestablish_1[0]);
get_event_msg!(nodes[2], MessageSendEvent::SendChannelUpdate, nodes[3].node.get_our_node_id());
assert!(nodes[2].node.get_and_clear_pending_msg_events().is_empty());
nodes[3].node.handle_channel_reestablish(nodes[2].node.get_our_node_id(), &reestablish_2[0]);
let mut ds_msgs = nodes[3].node.get_and_clear_pending_msg_events();
check_added_monitors(&nodes[3], 1);
assert_eq!(ds_msgs.len(), 2);
if let MessageSendEvent::SendChannelUpdate { .. } = ds_msgs[0] {} else { panic!(); }
let mut cs_updates = match ds_msgs.remove(1) {
MessageSendEvent::UpdateHTLCs { mut updates, .. } => {
let mut fulfill = updates.update_fulfill_htlcs.remove(0);
nodes[2].node.handle_update_fulfill_htlc(nodes[3].node.get_our_node_id(), fulfill);
check_added_monitors(&nodes[2], 1);
let cs_updates = get_htlc_update_msgs(&nodes[2], &nodes[0].node.get_our_node_id());
expect_payment_forwarded!(nodes[2], nodes[0], nodes[3], Some(1000), false, false);
do_commitment_signed_dance(&nodes[2], &nodes[3], &updates.commitment_signed, false, true);
cs_updates
}
_ => panic!(),
};
let fulfill = cs_updates.update_fulfill_htlcs.remove(0);
nodes[0].node.handle_update_fulfill_htlc(nodes[2].node.get_our_node_id(), fulfill);
do_commitment_signed_dance(&nodes[0], &nodes[2], &cs_updates.commitment_signed, false, true);
expect_payment_sent!(nodes[0], payment_preimage);
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
send_payment(&nodes[0], &[&nodes[2], &nodes[3]], 100_000);
assert!(!get_monitor!(nodes[3], chan_id_not_persisted).get_stored_preimages().contains_key(&payment_hash));
}
}
#[test]
fn test_partial_claim_before_restart() {
do_test_partial_claim_before_restart(false, false);
do_test_partial_claim_before_restart(false, true);
do_test_partial_claim_before_restart(true, false);
do_test_partial_claim_before_restart(true, true);
}
#[test]
fn test_mpp_claim_htlc_fulfills_unblocked_on_reload() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes_1_deserialized;
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan_a = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
let chan_b = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 0);
let chan_id_a = chan_a.2;
let chan_id_b = chan_b.2;
let scid_a = chan_a.0.contents.short_channel_id;
let scid_b = chan_b.0.contents.short_channel_id;
let amt_msat = 50_000_000;
let (route, payment_hash, payment_preimage, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], amt_msat);
assert_eq!(route.paths.len(), 2);
send_along_route_with_secret(
&nodes[0], route, &[&[&nodes[1]], &[&nodes[1]]], amt_msat, payment_hash,
payment_secret,
);
{
let mut fee_est = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
*fee_est *= 2;
}
nodes[0].node.timer_tick_occurred();
check_added_monitors(&nodes[0], 2);
let node_0_id = nodes[0].node.get_our_node_id();
let node_1_id = nodes[1].node.get_our_node_id();
let fee_msgs = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(fee_msgs.len(), 2);
for ev in &fee_msgs {
match ev {
MessageSendEvent::UpdateHTLCs { updates, .. } => {
nodes[1].node.handle_update_fee(node_0_id, updates.update_fee.as_ref().unwrap());
nodes[1].node.handle_commitment_signed_batch_test(
node_0_id, &updates.commitment_signed,
);
check_added_monitors(&nodes[1], 1);
},
_ => panic!("Unexpected message: {:?}", ev),
}
}
let node_1_msgs = nodes[1].node.get_and_clear_pending_msg_events();
let mut commitment_signed_msgs = Vec::new();
for ev in &node_1_msgs {
match ev {
MessageSendEvent::SendRevokeAndACK { msg, .. } => {
nodes[0].node.handle_revoke_and_ack(node_1_id, msg);
check_added_monitors(&nodes[0], 1);
},
MessageSendEvent::UpdateHTLCs { updates, .. } => {
commitment_signed_msgs.push(updates.commitment_signed.clone());
},
_ => panic!("Unexpected message: {:?}", ev),
}
}
let node_0_msgs = nodes[0].node.get_and_clear_pending_msg_events();
for ev in &node_0_msgs {
match ev {
MessageSendEvent::SendRevokeAndACK { msg, .. } => {
nodes[1].node.handle_revoke_and_ack(node_0_id, msg);
check_added_monitors(&nodes[1], 1);
},
_ => panic!("Unexpected message: {:?}", ev),
}
}
let mon_b_serialized = get_monitor!(nodes[1], chan_id_b).encode();
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
nodes[1].node.claim_funds(payment_preimage);
check_added_monitors(&nodes[1], 2);
let (update_id_a, _) = get_latest_mon_update_id(&nodes[1], chan_id_a);
nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(chan_id_a, update_id_a);
for commitment_signed in &commitment_signed_msgs {
nodes[0].node.handle_commitment_signed_batch_test(node_1_id, commitment_signed);
check_added_monitors(&nodes[0], 1);
}
let node_0_msgs = nodes[0].node.get_and_clear_pending_msg_events();
for ev in &node_0_msgs {
match ev {
MessageSendEvent::SendRevokeAndACK { msg, .. } => {
nodes[1].node.handle_revoke_and_ack(node_0_id, msg);
check_added_monitors(&nodes[1], 0);
},
_ => panic!("Unexpected message: {:?}", ev),
}
}
let node_1_serialized = nodes[1].node.encode();
let mon_a_serialized = get_monitor!(nodes[1], chan_id_a).encode();
nodes[0].node.peer_disconnected(node_1_id);
reload_node!(
nodes[1],
node_1_serialized,
&[&mon_a_serialized, &mon_b_serialized],
persister,
new_chain_monitor,
nodes_1_deserialized
);
let node_1_id = nodes[1].node.get_our_node_id();
nodes[0].node.peer_connected(node_1_id, &msgs::Init {
features: nodes[1].node.init_features(), networks: None, remote_network_address: None,
}, true).unwrap();
nodes[1].node.peer_connected(node_0_id, &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None,
}, false).unwrap();
let reestablish_0 = nodes[0].node.get_and_clear_pending_msg_events();
let reestablish_1 = nodes[1].node.get_and_clear_pending_msg_events();
let mut reestablish_0_chan_ids = Vec::new();
let mut reestablish_1_chan_ids = Vec::new();
for ev in &reestablish_1 {
match ev {
MessageSendEvent::SendChannelReestablish { node_id, msg } => {
assert_eq!(*node_id, node_0_id);
reestablish_1_chan_ids.push(msg.channel_id);
nodes[0].node.handle_channel_reestablish(node_1_id, msg);
},
_ => panic!("Unexpected message: {:?}", ev),
}
}
for ev in &reestablish_0 {
match ev {
MessageSendEvent::SendChannelReestablish { node_id, msg } => {
assert_eq!(*node_id, node_1_id);
reestablish_0_chan_ids.push(msg.channel_id);
nodes[1].node.handle_channel_reestablish(node_0_id, msg);
},
_ => panic!("Unexpected message: {:?}", ev),
}
}
assert_eq!(reestablish_0_chan_ids.len(), 2);
assert!(reestablish_0_chan_ids.contains(&chan_id_a));
assert!(reestablish_0_chan_ids.contains(&chan_id_b));
assert_eq!(reestablish_1_chan_ids.len(), 2);
assert!(reestablish_1_chan_ids.contains(&chan_id_a));
assert!(reestablish_1_chan_ids.contains(&chan_id_b));
check_added_monitors(&nodes[0], 0);
check_added_monitors(&nodes[1], 3);
let restart_msgs_0 = nodes[0].node.get_and_clear_pending_msg_events();
let restart_msgs_1 = nodes[1].node.get_and_clear_pending_msg_events();
let mut restart_scids_0 = Vec::new();
let mut restart_scids_1 = Vec::new();
let mut startup_fulfill_chan_ids = Vec::new();
for ev in &restart_msgs_0 {
match ev {
MessageSendEvent::SendChannelUpdate { node_id, msg } => {
assert_eq!(*node_id, node_1_id);
restart_scids_0.push(msg.contents.short_channel_id);
},
_ => panic!("Unexpected restart message from node 0: {:?}", ev),
}
}
for ev in &restart_msgs_1 {
match ev {
MessageSendEvent::SendChannelUpdate { node_id, msg } => {
assert_eq!(*node_id, node_0_id);
restart_scids_1.push(msg.contents.short_channel_id);
},
MessageSendEvent::UpdateHTLCs { node_id, channel_id, updates } => {
assert_eq!(*node_id, node_0_id);
startup_fulfill_chan_ids.push(*channel_id);
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
assert!(updates.update_add_htlcs.is_empty());
assert!(updates.update_fail_htlcs.is_empty());
assert!(updates.update_fail_malformed_htlcs.is_empty());
assert!(updates.update_fee.is_none());
for fulfill in &updates.update_fulfill_htlcs {
nodes[0].node.handle_update_fulfill_htlc(node_1_id, fulfill.clone());
}
do_commitment_signed_dance(
&nodes[0], &nodes[1], &updates.commitment_signed, false, false,
);
},
_ => panic!("Unexpected restart message from node 1: {:?}", ev),
}
}
assert_eq!(restart_scids_0.len(), 2);
assert!(restart_scids_0.contains(&scid_a));
assert!(restart_scids_0.contains(&scid_b));
assert_eq!(restart_scids_1.len(), 2);
assert!(restart_scids_1.contains(&scid_a));
assert!(restart_scids_1.contains(&scid_b));
assert_eq!(startup_fulfill_chan_ids, vec![chan_id_a]);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
check_added_monitors(&nodes[0], 0);
check_added_monitors(&nodes[1], 0);
let startup_payment_events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(startup_payment_events.len(), 2);
let mut saw_startup_payment_sent = false;
let mut startup_success_scids = Vec::new();
for ev in &startup_payment_events {
match ev {
Event::PaymentSent {
payment_preimage: sent_preimage,
payment_hash: sent_hash,
amount_msat: sent_amount,
fee_paid_msat,
..
} => {
assert_eq!(*sent_preimage, payment_preimage);
assert_eq!(*sent_hash, payment_hash);
assert_eq!(*sent_amount, Some(amt_msat));
assert_eq!(*fee_paid_msat, Some(0));
saw_startup_payment_sent = true;
},
Event::PaymentPathSuccessful { payment_hash: Some(path_hash), path, .. } => {
assert_eq!(*path_hash, payment_hash);
assert_eq!(path.hops.len(), 1);
startup_success_scids.push(path.hops[0].short_channel_id);
},
_ => panic!("Unexpected startup payment event: {:?}", ev),
}
}
assert!(saw_startup_payment_sent);
assert_eq!(startup_success_scids, vec![scid_a]);
let claim_events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(claim_events.len(), 1);
match &claim_events[0] {
Event::PaymentClaimed { payment_hash: claimed_hash, amount_msat, htlcs, .. } => {
assert_eq!(*claimed_hash, payment_hash);
assert_eq!(*amount_msat, amt_msat);
assert_eq!(htlcs.len(), 2);
},
_ => panic!("Unexpected event: {:?}", claim_events[0]),
}
check_added_monitors(&nodes[0], 1);
check_added_monitors(&nodes[1], 2);
let fulfill_msgs = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(fulfill_msgs.len(), 1);
match &fulfill_msgs[0] {
MessageSendEvent::UpdateHTLCs { node_id, channel_id, updates } => {
assert_eq!(*node_id, node_0_id);
assert_eq!(*channel_id, chan_id_b);
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
assert!(updates.update_add_htlcs.is_empty());
assert!(updates.update_fail_htlcs.is_empty());
assert!(updates.update_fail_malformed_htlcs.is_empty());
assert!(updates.update_fee.is_none());
for fulfill in &updates.update_fulfill_htlcs {
nodes[0].node.handle_update_fulfill_htlc(node_1_id, fulfill.clone());
}
do_commitment_signed_dance(
&nodes[0], &nodes[1], &updates.commitment_signed, false, false,
);
},
_ => panic!("Unexpected fulfill message: {:?}", fulfill_msgs[0]),
}
check_added_monitors(&nodes[1], 0);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
let final_payment_events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(final_payment_events.len(), 1);
match &final_payment_events[0] {
Event::PaymentPathSuccessful { payment_hash: Some(path_hash), path, .. } => {
assert_eq!(*path_hash, payment_hash);
assert_eq!(path.hops.len(), 1);
assert_eq!(path.hops[0].short_channel_id, scid_b);
},
_ => panic!("Unexpected final payment event: {:?}", final_payment_events[0]),
}
check_added_monitors(&nodes[0], 0);
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
check_added_monitors(&nodes[0], 0);
check_added_monitors(&nodes[1], 0);
let pending: Vec<_> = nodes[0].node.list_channels().iter()
.filter(|channel| channel.channel_id == chan_id_a || channel.channel_id == chan_id_b)
.filter(|channel| !channel.pending_outbound_htlcs.is_empty())
.map(|channel| channel.channel_id)
.collect();
assert!(pending.is_empty(), "HTLC fulfills remained stuck on channels {:?}", pending);
}
fn do_forwarded_payment_no_manager_persistence(use_cs_commitment: bool, claim_htlc: bool, use_intercept: bool) {
if !use_cs_commitment { assert!(!claim_htlc); }
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let mut intercept_forwards_config = test_legacy_channel_config();
intercept_forwards_config.htlc_interception_flags =
HTLCInterceptionFlags::ToInterceptSCIDs as u8;
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(intercept_forwards_config), None]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
let intercept_scid = nodes[1].node.get_intercept_scid();
let (mut route, payment_hash, payment_preimage, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000);
if use_intercept {
route.paths[0].hops[1].short_channel_id = intercept_scid;
}
let payment_id = PaymentId(nodes[0].keys_manager.backing.get_secure_random_bytes());
let htlc_expiry = nodes[0].best_block_info().1 + TEST_FINAL_CLTV;
nodes[0].node.send_payment_with_route(route, payment_hash,
RecipientOnionFields::secret_only(payment_secret, 1_000_000), payment_id).unwrap();
check_added_monitors(&nodes[0], 1);
let payment_event = SendEvent::from_node(&nodes[0]);
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
do_commitment_signed_dance(&nodes[1], &nodes[0], &payment_event.commitment_msg, false, false);
let node_encoded = nodes[1].node.encode();
expect_htlc_failure_conditions(nodes[1].node.get_and_clear_pending_events(), &[]);
let mut intercept_id = None;
let mut expected_outbound_amount_msat = None;
if use_intercept {
nodes[1].node.test_process_pending_update_add_htlcs();
let events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::HTLCIntercepted { intercept_id: ev_id, expected_outbound_amount_msat: ev_amt, .. } => {
intercept_id = Some(ev_id);
expected_outbound_amount_msat = Some(ev_amt);
},
_ => panic!()
}
nodes[1].node.forward_intercepted_htlc(intercept_id.unwrap(), &chan_id_2,
nodes[2].node.get_our_node_id(), expected_outbound_amount_msat.unwrap()).unwrap();
}
nodes[1].node.process_pending_htlc_forwards();
let payment_event = SendEvent::from_node(&nodes[1]);
nodes[2].node.handle_update_add_htlc(nodes[1].node.get_our_node_id(), &payment_event.msgs[0]);
nodes[2].node.handle_commitment_signed_batch_test(nodes[1].node.get_our_node_id(), &payment_event.commitment_msg);
check_added_monitors(&nodes[2], 1);
if claim_htlc {
get_monitor!(nodes[2], chan_id_2).provide_payment_preimage_unsafe_legacy(
&payment_hash, &payment_preimage, &nodes[2].tx_broadcaster,
&LowerBoundedFeeEstimator(nodes[2].fee_estimator), &nodes[2].logger
);
}
assert!(nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
let _ = nodes[2].node.get_and_clear_pending_msg_events();
let message = "Channel force-closed".to_owned();
nodes[2]
.node
.force_close_broadcasting_latest_txn(&chan_id_2, &nodes[1].node.get_our_node_id(), message.clone())
.unwrap();
let cs_commitment_tx = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
assert_eq!(cs_commitment_tx.len(), if claim_htlc { 2 } else { 1 });
check_added_monitors(&nodes[2], 1);
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
check_closed_event(&nodes[2], 1, reason, &[nodes[1].node.get_our_node_id()], 100000);
check_closed_broadcast(&nodes[2], 1, true);
let chan_0_monitor_serialized = get_monitor!(nodes[1], chan_id_1).encode();
let chan_1_monitor_serialized = get_monitor!(nodes[1], chan_id_2).encode();
reload_node!(nodes[1], node_encoded, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], persister, new_chain_monitor, nodes_1_deserialized);
check_closed_event(&nodes[1], 1, ClosureReason::OutdatedChannelManager, &[nodes[2].node.get_our_node_id()], 100000);
if use_intercept {
let forward_err = nodes[1].node.forward_intercepted_htlc(intercept_id.unwrap(), &chan_id_1,
nodes[0].node.get_our_node_id(), expected_outbound_amount_msat.unwrap()).unwrap_err();
assert_eq!(forward_err, APIError::APIMisuseError {
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.unwrap().0))
});
}
nodes[1].node.timer_tick_occurred();
let bs_commitment_tx = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
assert_eq!(bs_commitment_tx.len(), 1);
check_added_monitors(&nodes[1], 1);
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1]));
if use_cs_commitment {
confirm_transaction(&nodes[1], &cs_commitment_tx[0]);
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
if claim_htlc {
confirm_transaction(&nodes[1], &cs_commitment_tx[1]);
} else {
connect_blocks(&nodes[1], htlc_expiry - nodes[1].best_block_info().1 + 1);
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
assert_eq!(txn.len(), if nodes[1].connect_style.borrow().updates_best_block_first() { 2 } else { 1 });
let bs_htlc_timeout_tx = txn.pop().unwrap();
confirm_transaction(&nodes[1], &bs_htlc_timeout_tx);
}
} else {
confirm_transaction(&nodes[1], &bs_commitment_tx[0]);
}
if !claim_htlc {
expect_and_process_pending_htlcs_and_htlc_handling_failed(
&nodes[1],
&[HTLCHandlingFailureType::Forward { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_id_2 }]
);
} else {
expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(1000), false, true);
}
check_added_monitors(&nodes[1], 1);
let mut update = get_htlc_update_msgs(&nodes[1], &nodes[0].node.get_our_node_id());
if claim_htlc {
nodes[0].node.handle_update_fulfill_htlc(nodes[1].node.get_our_node_id(), update.update_fulfill_htlcs.remove(0));
} else {
nodes[0].node.handle_update_fail_htlc(nodes[1].node.get_our_node_id(), &update.update_fail_htlcs[0]);
}
do_commitment_signed_dance(&nodes[0], &nodes[1], &update.commitment_signed, false, false);
if claim_htlc {
expect_payment_sent!(nodes[0], payment_preimage);
} else {
expect_payment_failed!(nodes[0], payment_hash, false);
}
}
#[test]
fn forwarded_payment_no_manager_persistence() {
do_forwarded_payment_no_manager_persistence(true, true, false);
do_forwarded_payment_no_manager_persistence(true, false, false);
do_forwarded_payment_no_manager_persistence(false, false, false);
}
#[test]
fn intercepted_payment_no_manager_persistence() {
do_forwarded_payment_no_manager_persistence(true, true, true);
do_forwarded_payment_no_manager_persistence(true, false, true);
do_forwarded_payment_no_manager_persistence(false, false, true);
}
#[test]
fn removed_payment_no_manager_persistence() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let legacy_cfg = test_legacy_channel_config();
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[Some(legacy_cfg.clone()), Some(legacy_cfg.clone()), Some(legacy_cfg)]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
let (_, payment_hash, ..) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000);
let node_encoded = nodes[1].node.encode();
nodes[2].node.fail_htlc_backwards(&payment_hash);
expect_and_process_pending_htlcs_and_htlc_handling_failed(
&nodes[2],
&[HTLCHandlingFailureType::Receive { payment_hash }]
);
check_added_monitors(&nodes[2], 1);
let events = nodes[2].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
match &events[0] {
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { update_fail_htlcs, commitment_signed, .. }, .. } => {
nodes[1].node.handle_update_fail_htlc(nodes[2].node.get_our_node_id(), &update_fail_htlcs[0]);
do_commitment_signed_dance(&nodes[1], &nodes[2], &commitment_signed, false, false);
},
_ => panic!("Unexpected event"),
}
let chan_0_monitor_serialized = get_monitor!(nodes[1], chan_id_1).encode();
let chan_1_monitor_serialized = get_monitor!(nodes[1], chan_id_2).encode();
reload_node!(nodes[1], node_encoded, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], persister, new_chain_monitor, nodes_1_deserialized);
match nodes[1].node.pop_pending_event().unwrap() {
Event::ChannelClosed { ref reason, .. } => {
assert_eq!(*reason, ClosureReason::OutdatedChannelManager);
},
_ => panic!("Unexpected event"),
}
nodes[1].node.test_process_background_events();
check_added_monitors(&nodes[1], 1);
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1]));
expect_and_process_pending_htlcs_and_htlc_handling_failed(
&nodes[1],
&[HTLCHandlingFailureType::Forward { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_id_2 }]
);
check_added_monitors(&nodes[1], 1);
let events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
match &events[0] {
MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { update_fail_htlcs, commitment_signed, .. }, .. } => {
nodes[0].node.handle_update_fail_htlc(nodes[1].node.get_our_node_id(), &update_fail_htlcs[0]);
do_commitment_signed_dance(&nodes[0], &nodes[1], &commitment_signed, false, false);
},
_ => panic!("Unexpected event"),
}
expect_payment_failed!(nodes[0], payment_hash, false);
}
#[test]
fn manager_persisted_pre_outbound_edge_forward() {
do_manager_persisted_pre_outbound_edge_forward(false);
}
#[test]
fn manager_persisted_pre_outbound_edge_intercept_forward() {
do_manager_persisted_pre_outbound_edge_forward(true);
}
fn do_manager_persisted_pre_outbound_edge_forward(intercept_htlc: bool) {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let mut intercept_forwards_config = test_default_channel_config();
intercept_forwards_config.htlc_interception_flags =
HTLCInterceptionFlags::ToInterceptSCIDs as u8;
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(intercept_forwards_config), None]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
let amt_msat = 5000;
let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
if intercept_htlc {
route.paths[0].hops[1].short_channel_id = nodes[1].node.get_intercept_scid();
}
nodes[0].node.send_payment_with_route(route, payment_hash, RecipientOnionFields::secret_only(payment_secret, amt_msat), PaymentId(payment_hash.0)).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
do_commitment_signed_dance(&nodes[1], &nodes[0], &updates.commitment_signed, false, false);
assert_eq!(
nodes[1].node.test_get_inbound_committed_htlcs_with_onion(nodes[0].node.get_our_node_id(), chan_id_1),
1
);
nodes[1].node.test_process_pending_update_add_htlcs();
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[2].node.peer_disconnected(nodes[1].node.get_our_node_id());
let node_b_encoded = nodes[1].node.encode();
let chan_0_monitor_serialized = get_monitor!(nodes[1], chan_id_1).encode();
let chan_1_monitor_serialized = get_monitor!(nodes[1], chan_id_2).encode();
reload_node!(nodes[1], node_b_encoded, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], persister, new_chain_monitor, nodes_1_deserialized);
reconnect_nodes(ReconnectArgs::new(&nodes[1], &nodes[0]));
let mut args_b_c = ReconnectArgs::new(&nodes[1], &nodes[2]);
args_b_c.send_channel_ready = (true, true);
args_b_c.send_announcement_sigs = (true, true);
reconnect_nodes(args_b_c);
assert_eq!(
nodes[1].node.test_get_inbound_committed_htlcs_with_onion(nodes[0].node.get_our_node_id(), chan_id_1),
1
);
nodes[1].node.process_pending_htlc_forwards();
if intercept_htlc {
let events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
let (intercept_id, expected_outbound_amt_msat) = match events[0] {
Event::HTLCIntercepted { intercept_id, expected_outbound_amount_msat, .. } => {
(intercept_id, expected_outbound_amount_msat)
},
_ => panic!()
};
nodes[1].node.forward_intercepted_htlc(intercept_id, &chan_id_2,
nodes[2].node.get_our_node_id(), expected_outbound_amt_msat).unwrap();
nodes[1].node.process_pending_htlc_forwards();
}
check_added_monitors(&nodes[1], 1);
let updates = get_htlc_update_msgs(&nodes[1], &nodes[2].node.get_our_node_id());
nodes[2].node.handle_update_add_htlc(nodes[1].node.get_our_node_id(), &updates.update_add_htlcs[0]);
do_commitment_signed_dance(&nodes[2], &nodes[1], &updates.commitment_signed, false, false);
expect_and_process_pending_htlcs(&nodes[2], false);
assert_eq!(
nodes[1].node.test_get_inbound_committed_htlcs_with_onion(nodes[0].node.get_our_node_id(), chan_id_1),
0
);
expect_payment_claimable!(nodes[2], payment_hash, payment_secret, amt_msat, None, nodes[2].node.get_our_node_id());
let path: &[&[_]] = &[&[&nodes[1], &nodes[2]]];
do_claim_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], path, payment_preimage));
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
}
#[test]
fn test_manager_persisted_post_outbound_edge_forward() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
let amt_msat = 5000;
let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
nodes[0].node.send_payment_with_route(route, payment_hash, RecipientOnionFields::secret_only(payment_secret, amt_msat), PaymentId(payment_hash.0)).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
do_commitment_signed_dance(&nodes[1], &nodes[0], &updates.commitment_signed, false, false);
nodes[1].node.process_pending_htlc_forwards();
check_added_monitors(&nodes[1], 1);
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[2].node.peer_disconnected(nodes[1].node.get_our_node_id());
let node_b_encoded = nodes[1].node.encode();
let chan_0_monitor_serialized = get_monitor!(nodes[1], chan_id_1).encode();
let chan_1_monitor_serialized = get_monitor!(nodes[1], chan_id_2).encode();
reload_node!(nodes[1], node_b_encoded, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], persister, new_chain_monitor, nodes_1_deserialized);
reconnect_nodes(ReconnectArgs::new(&nodes[1], &nodes[0]));
let mut args_b_c = ReconnectArgs::new(&nodes[1], &nodes[2]);
args_b_c.send_channel_ready = (true, true);
args_b_c.send_announcement_sigs = (true, true);
args_b_c.pending_htlc_adds = (0, 1);
reconnect_nodes(args_b_c);
nodes[1].node.process_pending_htlc_forwards();
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
expect_and_process_pending_htlcs(&nodes[2], false);
expect_payment_claimable!(nodes[2], payment_hash, payment_secret, amt_msat, None, nodes[2].node.get_our_node_id());
let path: &[&[_]] = &[&[&nodes[1], &nodes[2]]];
do_claim_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], path, payment_preimage));
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
}
#[test]
fn test_manager_persisted_post_outbound_edge_holding_cell() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
let amt_msat = 1000;
let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
let onion = RecipientOnionFields::secret_only(payment_secret, amt_msat);
nodes[0].node.send_payment_with_route(route, payment_hash, onion, PaymentId(payment_hash.0)).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
do_commitment_signed_dance(&nodes[1], &nodes[0], &updates.commitment_signed, false, false);
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
let (route_2, payment_hash_2, payment_preimage_2, payment_secret_2) = get_route_and_payment_hash!(nodes[2], nodes[1], amt_msat);
let onion = RecipientOnionFields::secret_only(payment_secret_2, amt_msat);
nodes[2].node.send_payment_with_route(route_2, payment_hash_2, onion, PaymentId(payment_hash_2.0)).unwrap();
let send_event =
SendEvent::from_event(nodes[2].node.get_and_clear_pending_msg_events().remove(0));
nodes[1].node.handle_update_add_htlc(nodes[2].node.get_our_node_id(), &send_event.msgs[0]);
nodes[1].node.handle_commitment_signed_batch_test(nodes[2].node.get_our_node_id(), &send_event.commitment_msg);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
check_added_monitors(&nodes[1], 1);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
nodes[1].node.process_pending_htlc_forwards();
check_added_monitors(&nodes[1], 0);
assert_eq!(
nodes[1].node.test_holding_cell_outbound_htlc_forwards_count(nodes[2].node.get_our_node_id(), chan_id_2),
1
);
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[2].node.peer_disconnected(nodes[1].node.get_our_node_id());
let node_b_encoded = nodes[1].node.encode();
let chan_0_monitor_serialized = get_monitor!(nodes[1], chan_id_1).encode();
let chan_1_monitor_serialized = get_monitor!(nodes[1], chan_id_2).encode();
reload_node!(nodes[1], node_b_encoded, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], persister, new_chain_monitor, nodes_1_deserialized);
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
let (latest_update, _) = get_latest_mon_update_id(&nodes[1], chan_id_2);
nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(chan_id_2, latest_update);
reconnect_nodes(ReconnectArgs::new(&nodes[1], &nodes[0]));
let mut reconnect_args = ReconnectArgs::new(&nodes[1], &nodes[2]);
reconnect_args.pending_raa = (false, true);
reconnect_args.pending_responding_commitment_signed = (false, true);
reconnect_args.expect_renegotiated_funding_locked_monitor_update = (false, true);
reconnect_args.allow_post_commitment_dance_msgs = (false, true);
reconnect_nodes(reconnect_args);
let holding_cell_htlc_msgs = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(holding_cell_htlc_msgs.len(), 1);
match &holding_cell_htlc_msgs[0] {
MessageSendEvent::UpdateHTLCs { node_id, updates, .. } => {
assert_eq!(*node_id, nodes[2].node.get_our_node_id());
assert_eq!(updates.update_add_htlcs.len(), 1);
nodes[2].node.handle_update_add_htlc(nodes[1].node.get_our_node_id(), &updates.update_add_htlcs[0]);
do_commitment_signed_dance(&nodes[2], &nodes[1], &updates.commitment_signed, false, false);
}
_ => panic!("Unexpected message: {:?}", holding_cell_htlc_msgs[0]),
}
nodes[1].node.process_pending_htlc_forwards();
let msgs = nodes[1].node.get_and_clear_pending_msg_events();
assert!(msgs.is_empty(), "Expected 0 messages, got {:?}", msgs);
expect_and_process_pending_htlcs(&nodes[2], false);
expect_payment_claimable!(nodes[2], payment_hash, payment_secret, amt_msat, None, nodes[2].node.get_our_node_id());
expect_payment_claimable!(nodes[1], payment_hash_2, payment_secret_2, amt_msat, None, nodes[1].node.get_our_node_id());
let path: &[&[_]] = &[&[&nodes[1], &nodes[2]]];
do_claim_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], path, payment_preimage));
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
nodes[1].node.claim_funds(payment_preimage_2);
expect_payment_claimed!(nodes[1], payment_hash_2, amt_msat);
check_added_monitors(&nodes[1], 1);
let mut update = get_htlc_update_msgs(&nodes[1], &nodes[2].node.get_our_node_id());
nodes[2].node.handle_update_fulfill_htlc(nodes[1].node.get_our_node_id(), update.update_fulfill_htlcs.remove(0));
do_commitment_signed_dance(&nodes[2], &nodes[1], &update.commitment_signed, false, false);
expect_payment_sent(&nodes[2], payment_preimage_2, None, true, true);
}
#[test]
fn test_reload_partial_funding_batch() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let new_persister;
let new_chain_monitor;
let legacy_cfg = test_legacy_channel_config();
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[Some(legacy_cfg.clone()), Some(legacy_cfg.clone()), Some(legacy_cfg)]);
let new_channel_manager;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let (tx, funding_created_msgs) = create_batch_channel_funding(&nodes[0], &[
(&nodes[1], 100_000, 0, 42, None),
(&nodes[2], 200_000, 0, 43, None),
]);
nodes[1].node.handle_funding_created(nodes[0].node.get_our_node_id(), &funding_created_msgs[0]);
check_added_monitors(&nodes[1], 1);
expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
nodes[0].node.handle_funding_signed(nodes[1].node.get_our_node_id(), &funding_signed_msg);
check_added_monitors(&nodes[0], 1);
assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
let channel_id_1 = ChannelId::v1_from_funding_outpoint(OutPoint { txid: tx.compute_txid(), index: 0 });
let node_encoded = nodes[0].node.encode();
let channel_monitor_1_serialized = get_monitor!(nodes[0], channel_id_1).encode();
reload_node!(nodes[0], node_encoded, &[&channel_monitor_1_serialized], new_persister, new_chain_monitor, new_channel_manager);
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
check_added_monitors(&nodes[0], 1);
{
let mut monitor_updates = nodes[0].chain_monitor.monitor_updates.lock().unwrap();
let monitor_updates_1 = monitor_updates.get(&channel_id_1).unwrap();
assert_eq!(monitor_updates_1.len(), 1);
assert_eq!(monitor_updates_1[0].updates.len(), 1);
assert!(matches!(monitor_updates_1[0].updates[0], ChannelMonitorUpdateStep::ChannelForceClosed { .. }));
}
{
let broadcasted_txs = nodes[0].tx_broadcaster.txn_broadcast();
assert_eq!(broadcasted_txs.len(), 1);
assert!(broadcasted_txs[0].compute_txid() != tx.compute_txid());
assert_eq!(broadcasted_txs[0].input.len(), 1);
assert_eq!(broadcasted_txs[0].input[0].previous_output.txid, tx.compute_txid());
}
assert!(nodes[0].node.list_channels().is_empty());
}
#[test]
fn test_htlc_localremoved_persistence() {
let chanmon_cfgs: Vec<TestChanMonCfg> = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let persister;
let chain_monitor;
let deserialized_chanmgr;
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let payee_pubkey = nodes[1].node.get_our_node_id();
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
let route_params = RouteParameters::from_payment_params_and_value(
PaymentParameters::for_keysend(payee_pubkey, 40, false), 10_000);
let route = find_route(
&nodes[0], &route_params
).unwrap();
let test_preimage = PaymentPreimage([42; 32]);
let mismatch_payment_hash = PaymentHash([43; 32]);
let session_privs = nodes[0].node.test_add_new_pending_payment(mismatch_payment_hash,
RecipientOnionFields::spontaneous_empty(10_000), PaymentId(mismatch_payment_hash.0), &route).unwrap();
nodes[0].node.test_send_payment_internal(&route, mismatch_payment_hash,
RecipientOnionFields::spontaneous_empty(10_000), Some(test_preimage), PaymentId(mismatch_payment_hash.0), session_privs).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &updates.update_add_htlcs[0]);
do_commitment_signed_dance(&nodes[1], &nodes[0], &updates.commitment_signed, false, false);
expect_and_process_pending_htlcs(&nodes[1], false);
expect_htlc_handling_failed_destinations!(nodes[1].node.get_and_clear_pending_events(), &[HTLCHandlingFailureType::Receive { payment_hash: mismatch_payment_hash }]);
check_added_monitors(&nodes[1], 1);
let msgs = get_htlc_update_msgs(&nodes[1], &nodes[0].node.get_our_node_id());
let htlc_fail_msg = msgs.update_fail_htlcs[0].clone();
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
let monitor_encoded = get_monitor!(nodes[1], _chan.3).encode();
reload_node!(nodes[1], nodes[1].node.encode(), &[&monitor_encoded], persister, chain_monitor, deserialized_chanmgr);
nodes[0].node.peer_connected(nodes[1].node.get_our_node_id(), &msgs::Init {
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
}, true).unwrap();
let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
assert_eq!(reestablish_1.len(), 1);
nodes[1].node.peer_connected(nodes[0].node.get_our_node_id(), &msgs::Init {
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
}, false).unwrap();
let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
assert_eq!(reestablish_2.len(), 1);
nodes[0].node.handle_channel_reestablish(nodes[1].node.get_our_node_id(), &reestablish_2[0]);
handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
nodes[1].node.handle_channel_reestablish(nodes[0].node.get_our_node_id(), &reestablish_1[0]);
let msgs = handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
let htlc_fail_msg_after_reload = msgs.2.unwrap().update_fail_htlcs[0].clone();
assert_eq!(htlc_fail_msg, htlc_fail_msg_after_reload);
}
#[test]
#[cfg(peer_storage)]
fn test_peer_storage() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let (persister, chain_monitor);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let nodes_0_deserialized;
let legacy_cfg = test_legacy_channel_config();
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(legacy_cfg.clone()), Some(legacy_cfg)]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let (_, _, cid, _) = create_announced_chan_between_nodes(&nodes, 0, 1);
send_payment(&nodes[0], &[&nodes[1]], 1000);
let nodes_0_serialized = nodes[0].node.encode();
let old_state_monitor = get_monitor!(nodes[0], cid).encode();
send_payment(&nodes[0], &[&nodes[1]], 10000);
send_payment(&nodes[0], &[&nodes[1]], 9999);
connect_blocks(&nodes[0], 1);
connect_blocks(&nodes[0], 1);
let peer_storage_msg_events_node0 =
nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_msg_events();
let peer_storage_msg_events_node1 =
nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_msg_events();
assert_ne!(peer_storage_msg_events_node0.len(), 0);
assert_ne!(peer_storage_msg_events_node1.len(), 0);
for ps_msg in peer_storage_msg_events_node0 {
match ps_msg {
MessageSendEvent::SendPeerStorage { ref node_id, ref msg } => {
assert_eq!(*node_id, node_b_id);
nodes[1].node.handle_peer_storage(node_a_id, msg.clone());
},
_ => panic!("Unexpected event"),
}
}
for ps_msg in peer_storage_msg_events_node1 {
match ps_msg {
MessageSendEvent::SendPeerStorage { ref node_id, ref msg } => {
assert_eq!(*node_id, node_a_id);
nodes[0].node.handle_peer_storage(node_b_id, msg.clone());
},
_ => panic!("Unexpected event"),
}
}
nodes[0].node.peer_disconnected(node_b_id);
nodes[1].node.peer_disconnected(node_a_id);
reload_node!(
nodes[0],
test_legacy_channel_config(),
&nodes_0_serialized,
&[&old_state_monitor[..]],
persister,
chain_monitor,
nodes_0_deserialized
);
let init_msg = msgs::Init {
features: nodes[1].node.init_features(),
networks: None,
remote_network_address: None,
};
nodes[0].node.peer_connected(node_b_id, &init_msg, true).unwrap();
nodes[1].node.peer_connected(node_a_id, &init_msg, true).unwrap();
let node_1_events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(node_1_events.len(), 2);
let node_0_events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(node_0_events.len(), 1);
match node_0_events[0] {
MessageSendEvent::SendChannelReestablish { ref node_id, .. } => {
assert_eq!(*node_id, node_b_id);
},
_ => panic!("Unexpected event"),
}
if let MessageSendEvent::SendPeerStorageRetrieval { node_id, msg } = &node_1_events[0] {
assert_eq!(*node_id, node_a_id);
let res = std::panic::catch_unwind(|| {
nodes[0].node.handle_peer_storage_retrieval(node_b_id, msg.clone());
});
assert!(res.is_err());
} else {
panic!("Unexpected event {node_1_events:?}")
}
if let MessageSendEvent::SendChannelReestablish { .. } = &node_1_events[1] {
} else {
panic!("Unexpected event {node_1_events:?}")
}
let res = std::panic::catch_unwind(|| drop(nodes));
assert!(res.is_err());
}
#[test]
fn test_hold_completed_inflight_monitor_updates_upon_manager_reload() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let (persister_a, persister_b);
let (chain_monitor_a, chain_monitor_b);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes_0_deserialized_a;
let nodes_0_deserialized_b;
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
send_payment(&nodes[0], &[&nodes[1]], 1_000_000);
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
let (route, payment_hash, _, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1_000_000);
let payment_id = PaymentId(payment_hash.0);
let onion = RecipientOnionFields::secret_only(payment_secret, 1_000_000);
nodes[0].node.send_payment_with_route(route, payment_hash, onion, payment_id).unwrap();
check_added_monitors(&nodes[0], 1);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
let node_0_serialized = nodes[0].node.encode();
let (_, latest_update_id) = nodes[0].chain_monitor.get_latest_mon_update_id(chan_id);
nodes[0].chain_monitor.chain_monitor.force_channel_monitor_updated(chan_id, latest_update_id);
let monitor_serialized_updated = get_monitor!(nodes[0], chan_id).encode();
nodes[0].node.peer_disconnected(nodes[1].node.get_our_node_id());
nodes[1].node.peer_disconnected(nodes[0].node.get_our_node_id());
reload_node!(
nodes[0],
test_default_channel_config(),
&node_0_serialized,
&[&monitor_serialized_updated[..]],
persister_a,
chain_monitor_a,
nodes_0_deserialized_a
);
let node_0_serialized = nodes[0].node.encode();
reload_node!(
nodes[0],
test_default_channel_config(),
&node_0_serialized,
&[&monitor_serialized_updated[..]],
persister_b,
chain_monitor_b,
nodes_0_deserialized_b
);
let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]);
reconnect_args.pending_htlc_adds = (0, 1);
reconnect_nodes(reconnect_args);
}
#[test]
fn outbound_removed_holding_cell_resolved_no_double_forward() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let node_0_id = nodes[0].node.get_our_node_id();
let node_1_id = nodes[1].node.get_our_node_id();
let node_2_id = nodes[2].node.get_our_node_id();
let chan_0_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
let chan_1_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
let chan_id_0_1 = chan_0_1.2;
let chan_id_1_2 = chan_1_2.2;
let (route, payment_hash, payment_preimage, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000);
send_along_route_with_secret(
&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 1_000_000, payment_hash, payment_secret,
);
nodes[2].node.claim_funds(payment_preimage);
check_added_monitors(&nodes[2], 1);
expect_payment_claimed!(nodes[2], payment_hash, 1_000_000);
nodes[0].node.peer_disconnected(node_1_id);
nodes[1].node.peer_disconnected(node_0_id);
let updates_2_1 = get_htlc_update_msgs(&nodes[2], &node_1_id);
nodes[1].node.handle_update_fulfill_htlc(node_2_id, updates_2_1.update_fulfill_htlcs[0].clone());
check_added_monitors(&nodes[1], 1);
do_commitment_signed_dance(&nodes[1], &nodes[2], &updates_2_1.commitment_signed, false, false);
expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(1000), false, false);
let node_1_serialized = nodes[1].node.encode();
let mon_0_1_serialized = get_monitor!(nodes[1], chan_id_0_1).encode();
let mon_1_2_serialized = get_monitor!(nodes[1], chan_id_1_2).encode();
reload_node!(
nodes[1],
node_1_serialized,
&[&mon_0_1_serialized, &mon_1_2_serialized],
persister,
new_chain_monitor,
nodes_1_deserialized
);
nodes[1].node.process_pending_htlc_forwards();
let mut reconnect_args = ReconnectArgs::new(&nodes[1], &nodes[0]);
reconnect_args.pending_cell_htlc_claims = (0, 1);
reconnect_nodes(reconnect_args);
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
}
#[test]
fn test_reload_node_with_preimage_in_monitor_claims_htlc() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let node_0_id = nodes[0].node.get_our_node_id();
let node_1_id = nodes[1].node.get_our_node_id();
let node_2_id = nodes[2].node.get_our_node_id();
let chan_0_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
let chan_1_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
let chan_id_0_1 = chan_0_1.2;
let chan_id_1_2 = chan_1_2.2;
let (route, payment_hash, payment_preimage, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000);
send_along_route_with_secret(
&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 1_000_000, payment_hash, payment_secret,
);
nodes[2].node.claim_funds(payment_preimage);
check_added_monitors(&nodes[2], 1);
expect_payment_claimed!(nodes[2], payment_hash, 1_000_000);
nodes[0].node.peer_disconnected(node_1_id);
nodes[1].node.peer_disconnected(node_0_id);
let updates_2_1 = get_htlc_update_msgs(&nodes[2], &node_1_id);
nodes[1].node.handle_update_fulfill_htlc(node_2_id, updates_2_1.update_fulfill_htlcs[0].clone());
check_added_monitors(&nodes[1], 1);
do_commitment_signed_dance(&nodes[1], &nodes[2], &updates_2_1.commitment_signed, false, false);
expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(1000), false, false);
nodes[1].node.test_clear_channel_holding_cell(node_0_id, chan_id_0_1);
let node_1_serialized = nodes[1].node.encode();
let mon_0_1_serialized = get_monitor!(nodes[1], chan_id_0_1).encode();
let mon_1_2_serialized = get_monitor!(nodes[1], chan_id_1_2).encode();
reload_node!(
nodes[1],
node_1_serialized,
&[&mon_0_1_serialized, &mon_1_2_serialized],
persister,
new_chain_monitor,
nodes_1_deserialized,
Some(true)
);
expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(1000), false, false);
check_added_monitors(&nodes[1], 1);
let mut reconnect_args = ReconnectArgs::new(&nodes[1], &nodes[0]);
reconnect_args.pending_cell_htlc_claims = (0, 1);
reconnect_nodes(reconnect_args);
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
}
#[test]
fn test_reload_node_without_preimage_fails_htlc() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let node_0_id = nodes[0].node.get_our_node_id();
let node_1_id = nodes[1].node.get_our_node_id();
let node_2_id = nodes[2].node.get_our_node_id();
let chan_0_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
let chan_1_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
let chan_id_0_1 = chan_0_1.2;
let chan_id_1_2 = chan_1_2.2;
let (route, payment_hash, _, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000);
send_along_route_with_secret(
&nodes[0], route, &[&[&nodes[1], &nodes[2]]], 1_000_000, payment_hash, payment_secret,
);
nodes[0].node.peer_disconnected(node_1_id);
nodes[1].node.peer_disconnected(node_0_id);
nodes[2].node.fail_htlc_backwards(&payment_hash);
expect_and_process_pending_htlcs_and_htlc_handling_failed(
&nodes[2], &[HTLCHandlingFailureType::Receive { payment_hash }]
);
check_added_monitors(&nodes[2], 1);
let updates_2_1 = get_htlc_update_msgs(&nodes[2], &node_1_id);
nodes[1].node.handle_update_fail_htlc(node_2_id, &updates_2_1.update_fail_htlcs[0]);
do_commitment_signed_dance(&nodes[1], &nodes[2], &updates_2_1.commitment_signed, false, false);
expect_and_process_pending_htlcs_and_htlc_handling_failed(
&nodes[1], &[HTLCHandlingFailureType::Forward { node_id: Some(node_2_id), channel_id: chan_id_1_2 }]
);
nodes[1].node.test_clear_channel_holding_cell(node_0_id, chan_id_0_1);
let node_1_serialized = nodes[1].node.encode();
let mon_0_1_serialized = get_monitor!(nodes[1], chan_id_0_1).encode();
let mon_1_2_serialized = get_monitor!(nodes[1], chan_id_1_2).encode();
reload_node!(
nodes[1],
node_1_serialized,
&[&mon_0_1_serialized, &mon_1_2_serialized],
persister,
new_chain_monitor,
nodes_1_deserialized,
Some(true)
);
let events = nodes[1].node.get_and_clear_pending_events();
assert!(!events.is_empty(), "Expected HTLCHandlingFailed event");
for event in events {
match event {
Event::HTLCHandlingFailed { .. } => {},
_ => panic!("Unexpected event {:?}", event),
}
}
nodes[1].node.process_pending_htlc_forwards();
check_added_monitors(&nodes[1], 0);
let mut reconnect_args = ReconnectArgs::new(&nodes[1], &nodes[0]);
reconnect_args.pending_cell_htlc_fails = (0, 1);
reconnect_nodes(reconnect_args);
expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new());
}
#[test]
fn test_reload_with_mpp_claims_on_same_channel() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let persister;
let new_chain_monitor;
let mut config = test_default_channel_config();
config.channel_handshake_config.announced_channel_max_inbound_htlc_value_in_flight_percentage = 10;
let configs: [Option<UserConfig>; 3] = core::array::from_fn(|_| Some(config.clone()));
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &configs);
let nodes_1_deserialized;
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let node_0_id = nodes[0].node.get_our_node_id();
let node_1_id = nodes[1].node.get_our_node_id();
let node_2_id = nodes[2].node.get_our_node_id();
let chan_0_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 2_000_000, 0);
let chan_1_2_a = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0);
let chan_1_2_b = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0);
let chan_id_0_1 = chan_0_1.2;
let chan_id_1_2_a = chan_1_2_a.2;
let chan_id_1_2_b = chan_1_2_b.2;
let amt_msat = 150_000_000;
let (route, payment_hash, payment_preimage, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
let payment_id = PaymentId(nodes[0].keys_manager.backing.get_secure_random_bytes());
let onion = RecipientOnionFields::secret_only(payment_secret, amt_msat);
nodes[0].node.send_payment_with_route(route, payment_hash, onion, payment_id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
let payment_event_1 = SendEvent::from_event(events.remove(0));
nodes[1].node.handle_update_add_htlc(node_0_id, &payment_event_1.msgs[0]);
check_added_monitors(&nodes[1], 0);
nodes[1].node.handle_commitment_signed_batch_test(node_0_id, &payment_event_1.commitment_msg);
check_added_monitors(&nodes[1], 1);
let (_, raa, holding_cell_htlcs) =
do_main_commitment_signed_dance(&nodes[1], &nodes[0], false);
assert_eq!(holding_cell_htlcs.len(), 1);
let payment_event_2 = holding_cell_htlcs.into_iter().next().unwrap();
nodes[1].node.handle_revoke_and_ack(node_0_id, &raa);
check_added_monitors(&nodes[1], 1);
nodes[1].node.process_pending_htlc_forwards();
check_added_monitors(&nodes[1], 1);
let mut events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
let ev_1_2 = events.remove(0);
pass_along_path(
&nodes[1], &[&nodes[2]], amt_msat, payment_hash, Some(payment_secret), ev_1_2, false, None,
);
pass_along_path(
&nodes[0], &[&nodes[1], &nodes[2]], amt_msat, payment_hash, Some(payment_secret),
payment_event_2, true, None,
);
nodes[2].node.claim_funds(payment_preimage);
check_added_monitors(&nodes[2], 2);
expect_payment_claimed!(nodes[2], payment_hash, amt_msat);
nodes[0].node.peer_disconnected(node_1_id);
nodes[1].node.peer_disconnected(node_0_id);
let mut events = nodes[2].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 2);
for ev in events {
match ev {
MessageSendEvent::UpdateHTLCs { ref node_id, ref updates, .. } => {
assert_eq!(*node_id, node_1_id);
assert_eq!(updates.update_fulfill_htlcs.len(), 1);
nodes[1].node.handle_update_fulfill_htlc(node_2_id, updates.update_fulfill_htlcs[0].clone());
check_added_monitors(&nodes[1], 1);
do_commitment_signed_dance(&nodes[1], &nodes[2], &updates.commitment_signed, false, false);
},
_ => panic!("Unexpected event"),
}
}
let events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(events.len(), 2);
for event in events {
expect_payment_forwarded(
event, &nodes[1], &nodes[0], &nodes[2], Some(1000), None, false, false, false,
);
}
nodes[1].node.test_clear_channel_holding_cell(node_0_id, chan_id_0_1);
let node_1_serialized = nodes[1].node.encode();
let mon_0_1_serialized = get_monitor!(nodes[1], chan_id_0_1).encode();
let mon_1_2_a_serialized = get_monitor!(nodes[1], chan_id_1_2_a).encode();
let mon_1_2_b_serialized = get_monitor!(nodes[1], chan_id_1_2_b).encode();
reload_node!(
nodes[1],
node_1_serialized,
&[&mon_0_1_serialized, &mon_1_2_a_serialized, &mon_1_2_b_serialized],
persister,
new_chain_monitor,
nodes_1_deserialized,
Some(true)
);
nodes[1].disable_monitor_completeness_assertion();
let events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(events.len(), 2);
for event in events {
expect_payment_forwarded(
event, &nodes[1], &nodes[0], &nodes[2], Some(1000), None, false, false, false,
);
}
check_added_monitors(&nodes[1], 2);
let mut reconnect_args = ReconnectArgs::new(&nodes[1], &nodes[0]);
reconnect_args.pending_cell_htlc_claims = (0, 2);
reconnect_nodes(reconnect_args);
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
}