X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fpayment_tests.rs;h=2ae606106c92a7591be57770bf6627a3bac9dc95;hb=e4c44f3c5becabccdb6df4e4b30aaa14671f9705;hp=a051ce05473ef1716108f2ea923d70561fb46eca;hpb=8dde17773ace41d2d0bac2493abf2b01db67bd84;p=rust-lightning diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index a051ce05..2ae60610 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -18,7 +18,7 @@ use crate::chain::transaction::OutPoint; use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentFailureReason}; use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS; use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, RecentPaymentDetails, RecipientOnionFields, HTLCForwardInfo, PendingHTLCRouting, PendingAddHTLCInfo}; -use crate::ln::features::InvoiceFeatures; +use crate::ln::features::Bolt11InvoiceFeatures; use crate::ln::{msgs, PaymentSecret, PaymentPreimage}; use crate::ln::msgs::ChannelMessageHandler; use crate::ln::outbound_payment::Retry; @@ -519,12 +519,16 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { check_added_monitors!(nodes[0], 1); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap(); + 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(); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an // error, as the channel has hit the chain. - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).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 as_err = nodes[0].node.get_and_clear_pending_msg_events(); @@ -603,9 +607,9 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { let mut peer_state = per_peer_state.get(&nodes[2].node.get_our_node_id()) .unwrap().lock().unwrap(); let mut channel = peer_state.channel_by_id.get_mut(&chan_id_2).unwrap(); - let mut new_config = channel.config(); + let mut new_config = channel.context.config(); new_config.forwarding_fee_base_msat += 100_000; - channel.update_config(&new_config); + channel.context.update_config(&new_config); new_route.paths[0].hops[0].fee_msat += 100_000; } @@ -689,12 +693,16 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) { assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0).len(), 1); check_added_monitors!(nodes[0], 1); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: nodes[1].node.init_features(), remote_network_address: None }, true).unwrap(); + 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(); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an // error, as the channel has hit the chain. - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: nodes[0].node.init_features(), remote_network_address: None }, false).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 as_err = nodes[0].node.get_and_clear_pending_msg_events(); @@ -778,6 +786,9 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) { reload_node!(nodes[0], test_default_channel_config(), nodes_0_serialized, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], second_persister, second_new_chain_monitor, second_nodes_0_deserialized); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); + nodes[0].node.test_process_background_events(); + check_added_monitors(&nodes[0], 1); + reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); // Now resend the payment, delivering the HTLC and actually claiming it this time. This ensures @@ -803,6 +814,9 @@ fn do_test_completed_payment_not_retryable_on_reload(use_dust: bool) { reload_node!(nodes[0], test_default_channel_config(), nodes_0_serialized, &[&chan_0_monitor_serialized, &chan_1_monitor_serialized], third_persister, third_new_chain_monitor, third_nodes_0_deserialized); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id()); + nodes[0].node.test_process_background_events(); + check_added_monitors(&nodes[0], 1); + reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); match nodes[0].node.send_payment_with_route(&new_route, payment_hash, RecipientOnionFields::secret_only(payment_secret), payment_id) { @@ -948,6 +962,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co let height = nodes[0].blocks.lock().unwrap().len() as u32 - 1; nodes[0].chain_monitor.chain_monitor.block_connected(&claim_block, height); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + check_added_monitors(&nodes[0], 1); } #[test] @@ -1394,7 +1409,7 @@ fn test_trivial_inflight_htlc_tracking(){ let chan_1_used_liquidity = inflight_htlcs.used_liquidity_msat( &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) , &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), - channel_1.get_short_channel_id().unwrap() + channel_1.context.get_short_channel_id().unwrap() ); assert_eq!(chan_1_used_liquidity, None); } @@ -1406,7 +1421,7 @@ fn test_trivial_inflight_htlc_tracking(){ let chan_2_used_liquidity = inflight_htlcs.used_liquidity_msat( &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()) , &NodeId::from_pubkey(&nodes[2].node.get_our_node_id()), - channel_2.get_short_channel_id().unwrap() + channel_2.context.get_short_channel_id().unwrap() ); assert_eq!(chan_2_used_liquidity, None); @@ -1431,7 +1446,7 @@ fn test_trivial_inflight_htlc_tracking(){ let chan_1_used_liquidity = inflight_htlcs.used_liquidity_msat( &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) , &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), - channel_1.get_short_channel_id().unwrap() + channel_1.context.get_short_channel_id().unwrap() ); // First hop accounts for expected 1000 msat fee assert_eq!(chan_1_used_liquidity, Some(501000)); @@ -1444,7 +1459,7 @@ fn test_trivial_inflight_htlc_tracking(){ let chan_2_used_liquidity = inflight_htlcs.used_liquidity_msat( &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()) , &NodeId::from_pubkey(&nodes[2].node.get_our_node_id()), - channel_2.get_short_channel_id().unwrap() + channel_2.context.get_short_channel_id().unwrap() ); assert_eq!(chan_2_used_liquidity, Some(500000)); @@ -1470,7 +1485,7 @@ fn test_trivial_inflight_htlc_tracking(){ let chan_1_used_liquidity = inflight_htlcs.used_liquidity_msat( &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) , &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), - channel_1.get_short_channel_id().unwrap() + channel_1.context.get_short_channel_id().unwrap() ); assert_eq!(chan_1_used_liquidity, None); } @@ -1482,7 +1497,7 @@ fn test_trivial_inflight_htlc_tracking(){ let chan_2_used_liquidity = inflight_htlcs.used_liquidity_msat( &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()) , &NodeId::from_pubkey(&nodes[2].node.get_our_node_id()), - channel_2.get_short_channel_id().unwrap() + channel_2.context.get_short_channel_id().unwrap() ); assert_eq!(chan_2_used_liquidity, None); } @@ -1523,7 +1538,7 @@ fn test_holding_cell_inflight_htlcs() { let used_liquidity = inflight_htlcs.used_liquidity_msat( &NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) , &NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), - channel.get_short_channel_id().unwrap() + channel.context.get_short_channel_id().unwrap() ); assert_eq!(used_liquidity, Some(2000000)); @@ -1620,7 +1635,9 @@ fn do_test_intercepted_payment(test: InterceptTest) { // Check for unknown channel id error. let unknown_chan_id_err = nodes[1].node.forward_intercepted_htlc(intercept_id, &[42; 32], nodes[2].node.get_our_node_id(), expected_outbound_amount_msat).unwrap_err(); - assert_eq!(unknown_chan_id_err , APIError::ChannelUnavailable { err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!([42; 32]), nodes[2].node.get_our_node_id()) }); + assert_eq!(unknown_chan_id_err , APIError::ChannelUnavailable { + err: format!("Funded channel with id {} not found for the passed counterparty node_id {}. Channel may still be opening.", + log_bytes!([42; 32]), nodes[2].node.get_our_node_id()) }); if test == InterceptTest::Fail { // Ensure we can fail the intercepted payment back. @@ -1644,7 +1661,9 @@ fn do_test_intercepted_payment(test: InterceptTest) { // Check that we'll fail as expected when sending to a channel that isn't in `ChannelReady` yet. let temp_chan_id = nodes[1].node.create_channel(nodes[2].node.get_our_node_id(), 100_000, 0, 42, None).unwrap(); let unusable_chan_err = nodes[1].node.forward_intercepted_htlc(intercept_id, &temp_chan_id, nodes[2].node.get_our_node_id(), expected_outbound_amount_msat).unwrap_err(); - assert_eq!(unusable_chan_err , APIError::ChannelUnavailable { err: format!("Channel with id {} not fully established", log_bytes!(temp_chan_id)) }); + assert_eq!(unusable_chan_err , APIError::ChannelUnavailable { + err: format!("Funded channel with id {} not found for the passed counterparty node_id {}. Channel may still be opening.", + log_bytes!(temp_chan_id), nodes[2].node.get_our_node_id()) }); assert_eq!(nodes[1].node.get_and_clear_pending_msg_events().len(), 1); // Open the just-in-time channel so the payment can then be forwarded. @@ -1717,6 +1736,133 @@ fn do_test_intercepted_payment(test: InterceptTest) { } } +#[test] +fn accept_underpaying_htlcs_config() { + do_accept_underpaying_htlcs_config(1); + do_accept_underpaying_htlcs_config(2); + do_accept_underpaying_htlcs_config(3); +} + +fn do_accept_underpaying_htlcs_config(num_mpp_parts: usize) { + let chanmon_cfgs = create_chanmon_cfgs(3); + let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); + let mut intercept_forwards_config = test_default_channel_config(); + intercept_forwards_config.accept_intercept_htlcs = true; + let mut underpay_config = test_default_channel_config(); + underpay_config.channel_config.accept_underpaying_htlcs = true; + let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, Some(intercept_forwards_config), Some(underpay_config)]); + let nodes = create_network(3, &node_cfgs, &node_chanmgrs); + + let mut chan_ids = Vec::new(); + for _ in 0..num_mpp_parts { + let _ = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000, 0); + let channel_id = create_unannounced_chan_between_nodes_with_value(&nodes, 1, 2, 2_000_000, 0).0.channel_id; + chan_ids.push(channel_id); + } + + // Send the initial payment. + let amt_msat = 900_000; + let skimmed_fee_msat = 20; + let mut route_hints = Vec::new(); + for _ in 0..num_mpp_parts { + route_hints.push(RouteHint(vec![RouteHintHop { + src_node_id: nodes[1].node.get_our_node_id(), + short_channel_id: nodes[1].node.get_intercept_scid(), + fees: RoutingFees { + base_msat: 1000, + proportional_millionths: 0, + }, + cltv_expiry_delta: MIN_CLTV_EXPIRY_DELTA, + htlc_minimum_msat: None, + htlc_maximum_msat: Some(amt_msat / num_mpp_parts as u64 + 5), + }])); + } + let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV) + .with_route_hints(route_hints).unwrap() + .with_bolt11_features(nodes[2].node.invoice_features()).unwrap(); + let route_params = RouteParameters { + payment_params, + final_value_msat: amt_msat, + }; + let (payment_hash, payment_secret) = nodes[2].node.create_inbound_payment(Some(amt_msat), 60 * 60, None).unwrap(); + nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), + PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap(); + check_added_monitors!(nodes[0], num_mpp_parts); // one monitor per path + let mut events: Vec = nodes[0].node.get_and_clear_pending_msg_events().into_iter().map(|e| SendEvent::from_event(e)).collect(); + assert_eq!(events.len(), num_mpp_parts); + + // Forward the intercepted payments. + for (idx, ev) in events.into_iter().enumerate() { + nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &ev.msgs[0]); + do_commitment_signed_dance(&nodes[1], &nodes[0], &ev.commitment_msg, false, true); + + 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] { + crate::events::Event::HTLCIntercepted { + intercept_id, expected_outbound_amount_msat, payment_hash: pmt_hash, .. + } => { + assert_eq!(pmt_hash, payment_hash); + (intercept_id, expected_outbound_amount_msat) + }, + _ => panic!() + }; + nodes[1].node.forward_intercepted_htlc(intercept_id, &chan_ids[idx], + nodes[2].node.get_our_node_id(), expected_outbound_amt_msat - skimmed_fee_msat).unwrap(); + expect_pending_htlcs_forwardable!(nodes[1]); + let payment_event = { + { + let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); + assert_eq!(added_monitors.len(), 1); + added_monitors.clear(); + } + let mut events = nodes[1].node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + SendEvent::from_event(events.remove(0)) + }; + nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]); + do_commitment_signed_dance(&nodes[2], &nodes[1], &payment_event.commitment_msg, false, true); + if idx == num_mpp_parts - 1 { + expect_pending_htlcs_forwardable!(nodes[2]); + } + } + + // Claim the payment and check that the skimmed fee is as expected. + let payment_preimage = nodes[2].node.get_payment_preimage(payment_hash, payment_secret).unwrap(); + let events = nodes[2].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + crate::events::Event::PaymentClaimable { + ref payment_hash, ref purpose, amount_msat, counterparty_skimmed_fee_msat, receiver_node_id, .. + } => { + assert_eq!(payment_hash, payment_hash); + assert_eq!(amt_msat - skimmed_fee_msat * num_mpp_parts as u64, amount_msat); + assert_eq!(skimmed_fee_msat * num_mpp_parts as u64, counterparty_skimmed_fee_msat); + assert_eq!(nodes[2].node.get_our_node_id(), receiver_node_id.unwrap()); + match purpose { + crate::events::PaymentPurpose::InvoicePayment { payment_preimage: ev_payment_preimage, + payment_secret: ev_payment_secret, .. } => + { + assert_eq!(payment_preimage, ev_payment_preimage.unwrap()); + assert_eq!(payment_secret, *ev_payment_secret); + }, + _ => panic!(), + } + }, + _ => panic!("Unexpected event"), + } + let mut expected_paths_vecs = Vec::new(); + let mut expected_paths = Vec::new(); + for _ in 0..num_mpp_parts { expected_paths_vecs.push(vec!(&nodes[1], &nodes[2])); } + for i in 0..num_mpp_parts { expected_paths.push(&expected_paths_vecs[i][..]); } + let total_fee_msat = do_claim_payment_along_route_with_extra_penultimate_hop_fees( + &nodes[0], &expected_paths[..], &vec![skimmed_fee_msat as u32; num_mpp_parts][..], false, + payment_preimage); + // The sender doesn't know that the penultimate hop took an extra fee. + expect_payment_sent(&nodes[0], payment_preimage, + Some(Some(total_fee_msat - skimmed_fee_msat * num_mpp_parts as u64)), true); +} + #[derive(PartialEq)] enum AutoRetry { Success, @@ -1757,7 +1903,7 @@ fn do_automatic_retries(test: AutoRetry) { #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; let amt_msat = 1000; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -1976,7 +2122,7 @@ fn auto_retry_partial_failure() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2188,7 +2334,7 @@ fn auto_retry_zero_attempts_send_error() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2228,7 +2374,7 @@ fn fails_paying_after_rejected_by_payee() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2275,7 +2421,7 @@ fn retry_multi_path_single_failed_payment() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2338,12 +2484,11 @@ fn retry_multi_path_single_failed_payment() { assert_eq!(events.len(), 1); match events[0] { Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently: false, - failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { err: ref err_msg }}, + failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { .. }}, short_channel_id: Some(expected_scid), .. } => { assert_eq!(payment_hash, ev_payment_hash); assert_eq!(expected_scid, route.paths[1].hops[0].short_channel_id); - assert!(err_msg.contains("max HTLC")); }, _ => panic!("Unexpected event"), } @@ -2369,7 +2514,7 @@ fn immediate_retry_on_failure() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2413,12 +2558,11 @@ fn immediate_retry_on_failure() { assert_eq!(events.len(), 1); match events[0] { Event::PaymentPathFailed { payment_hash: ev_payment_hash, payment_failed_permanently: false, - failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { err: ref err_msg }}, + failure: PathFailure::InitialSend { err: APIError::ChannelUnavailable { .. }}, short_channel_id: Some(expected_scid), .. } => { assert_eq!(payment_hash, ev_payment_hash); assert_eq!(expected_scid, route.paths[1].hops[0].short_channel_id); - assert!(err_msg.contains("max HTLC")); }, _ => panic!("Unexpected event"), } @@ -2458,7 +2602,7 @@ fn no_extra_retries_on_back_to_back_fail() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2660,7 +2804,7 @@ fn test_simple_partial_retry() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2826,7 +2970,7 @@ fn test_threaded_payment_retries() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -3032,6 +3176,7 @@ fn do_no_missing_sent_on_midpoint_reload(persist_manager_with_payment: bool) { reload_node!(nodes[0], test_default_channel_config(), &nodes[0].node.encode(), &[&chan_0_monitor_serialized], persister_c, chain_monitor_c, nodes_0_deserialized_c); let events = nodes[0].node.get_and_clear_pending_events(); assert!(events.is_empty()); + check_added_monitors(&nodes[0], 1); } #[test] @@ -3073,7 +3218,7 @@ fn do_claim_from_closed_chan(fail_payment: bool) { final_value_msat: 10_000_000, }; let mut route = nodes[0].router.find_route(&nodes[0].node.get_our_node_id(), &route_params, - None, &nodes[0].node.compute_inflight_htlcs()).unwrap(); + None, nodes[0].node.compute_inflight_htlcs()).unwrap(); // Make sure the route is ordered as the B->D path before C->D route.paths.sort_by(|a, _| if a.hops[0].pubkey == nodes[1].node.get_our_node_id() { std::cmp::Ordering::Less } else { std::cmp::Ordering::Greater });