use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
use chain::keysinterface::{KeysInterface, Recipient};
use ln::{PaymentHash, PaymentSecret};
+use ln::channel::EXPIRE_PREV_CONFIG_TICKS;
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, HTLCForwardInfo, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingHTLCInfo, PendingHTLCRouting};
use ln::onion_utils;
use routing::gossip::{NetworkUpdate, RoutingFees, NodeId};
use routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop};
use ln::features::{InitFeatures, InvoiceFeatures, NodeFeatures};
use ln::msgs;
-use ln::msgs::{ChannelMessageHandler, ChannelUpdate, OptionalField};
+use ln::msgs::{ChannelMessageHandler, ChannelUpdate};
use ln::wire::Encode;
-use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
+use util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider};
use util::ser::{ReadableArgs, Writeable, Writer};
use util::{byte_utils, test_utils};
use util::config::{UserConfig, ChannelConfig};
expect_htlc_forward!(&nodes[2]);
expect_event!(&nodes[2], Event::PaymentReceived);
callback_node();
- expect_pending_htlcs_forwardable!(nodes[2]);
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[2], vec![HTLCDestination::FailedPayment { payment_hash: payment_hash.clone() }]);
}
let update_2_1 = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
- if let &Event::PaymentPathFailed { ref rejected_by_dest, ref network_update, ref all_paths_failed, ref short_channel_id, ref error_code, .. } = &events[0] {
- assert_eq!(*rejected_by_dest, !expected_retryable);
+ if let &Event::PaymentPathFailed { ref payment_failed_permanently, ref network_update, ref all_paths_failed, ref short_channel_id, ref error_code, .. } = &events[0] {
+ assert_eq!(*payment_failed_permanently, !expected_retryable);
assert_eq!(*all_paths_failed, true);
assert_eq!(*error_code, expected_error_code);
if expected_channel_update.is_some() {
flags: 0,
cltv_expiry_delta: 0,
htlc_minimum_msat: 0,
- htlc_maximum_msat: OptionalField::Absent,
+ htlc_maximum_msat: msgs::MAX_VALUE_MSAT,
fee_base_msat: 0,
fee_proportional_millionths: 0,
excess_data: vec![],
payment_hash, payment_secret);
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
+ // Closure to force expiry of a channel's previous config.
+ let expire_prev_config = || {
+ for _ in 0..EXPIRE_PREV_CONFIG_TICKS {
+ nodes[1].node.timer_tick_occurred();
+ }
+ };
+
// Closure to update and retrieve the latest ChannelUpdate.
let update_and_get_channel_update = |config: &ChannelConfig, expect_new_update: bool,
- prev_update: Option<&msgs::ChannelUpdate>| -> Option<msgs::ChannelUpdate> {
+ prev_update: Option<&msgs::ChannelUpdate>, should_expire_prev_config: bool| -> Option<msgs::ChannelUpdate> {
nodes[1].node.update_channel_config(
channel_to_update_counterparty, &[channel_to_update.0], config,
).unwrap();
if prev_update.is_some() {
assert!(new_update.contents.timestamp > prev_update.unwrap().contents.timestamp)
}
+ if should_expire_prev_config {
+ expire_prev_config();
+ }
Some(new_update)
};
.find(|channel| channel.channel_id == channel_to_update.0).unwrap()
.config.unwrap();
config.forwarding_fee_base_msat = u32::max_value();
- let msg = update_and_get_channel_update(&config, true, None).unwrap();
+ let msg = update_and_get_channel_update(&config, true, None, false).unwrap();
+
+ // The old policy should still be in effect until a new block is connected.
+ send_along_route_with_secret(&nodes[0], route.clone(), &[&[&nodes[1], &nodes[2]]], PAYMENT_AMT,
+ payment_hash, payment_secret);
+ claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
+
+ // Connect a block, which should expire the previous config, leading to a failure when
+ // forwarding the HTLC.
+ expire_prev_config();
expect_onion_failure("fee_insufficient", UPDATE|12, &msg);
// Redundant updates should not trigger a new ChannelUpdate.
- assert!(update_and_get_channel_update(&config, false, None).is_none());
+ assert!(update_and_get_channel_update(&config, false, None, false).is_none());
// Similarly, updates that do not have an affect on ChannelUpdate should not trigger a new one.
config.force_close_avoidance_max_fee_satoshis *= 2;
- assert!(update_and_get_channel_update(&config, false, None).is_none());
+ assert!(update_and_get_channel_update(&config, false, None, false).is_none());
// Reset the base fee to the default and increase the proportional fee which should trigger a
// new ChannelUpdate.
config.forwarding_fee_base_msat = default_config.forwarding_fee_base_msat;
config.cltv_expiry_delta = u16::max_value();
- let msg = update_and_get_channel_update(&config, true, Some(&msg)).unwrap();
+ let msg = update_and_get_channel_update(&config, true, Some(&msg), true).unwrap();
expect_onion_failure("incorrect_cltv_expiry", UPDATE|13, &msg);
// Reset the proportional fee and increase the CLTV expiry delta which should trigger a new
// ChannelUpdate.
config.cltv_expiry_delta = default_config.cltv_expiry_delta;
config.forwarding_fee_proportional_millionths = u32::max_value();
- let msg = update_and_get_channel_update(&config, true, Some(&msg)).unwrap();
+ let msg = update_and_get_channel_update(&config, true, Some(&msg), true).unwrap();
expect_onion_failure("fee_insufficient", UPDATE|12, &msg);
// To test persistence of the updated config, we'll re-initialize the ChannelManager.
};
expect_pending_htlcs_forwardable_ignore!(nodes[1]);
nodes[1].node.process_pending_htlc_forwards();
- expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash }]);
nodes[1].node.process_pending_htlc_forwards();
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
check_added_monitors!(&nodes[1], 1);
}
expect_pending_htlcs_forwardable_ignore!(nodes[1]);
nodes[1].node.process_pending_htlc_forwards();
- expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash }]);
nodes[1].node.process_pending_htlc_forwards();
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
check_added_monitors!(&nodes[1], 1);
}
expect_pending_htlcs_forwardable_ignore!(nodes[1]);
nodes[1].node.process_pending_htlc_forwards();
- expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash }]);
nodes[1].node.process_pending_htlc_forwards();
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
check_added_monitors!(&nodes[1], 1);
expect_pending_htlcs_forwardable_ignore!(nodes[1]);
nodes[1].node.process_pending_htlc_forwards();
- expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash }]);
nodes[1].node.process_pending_htlc_forwards();
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
check_added_monitors!(&nodes[1], 1);
nodes[1].node.process_pending_htlc_forwards();
expect_pending_htlcs_forwardable_ignore!(nodes[1]);
nodes[1].node.process_pending_htlc_forwards();
- expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash: payment_hash.clone() }]);
nodes[1].node.process_pending_htlc_forwards();
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
check_added_monitors!(&nodes[1], 1);
nodes[1].node.process_pending_htlc_forwards();
expect_payment_received!(nodes[1], payment_hash, payment_secret, recv_amt_msat);
nodes[1].node.fail_htlc_backwards(&payment_hash);
- expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash }]);
nodes[1].node.process_pending_htlc_forwards();
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());