+
+ // Increase the base fee which should trigger a new ChannelUpdate.
+ let mut config = nodes[1].node.list_usable_channels().iter()
+ .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, 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, 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, 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), 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), true).unwrap();
+ expect_onion_failure("fee_insufficient", UPDATE|12, &msg);
+
+ // To test persistence of the updated config, we'll re-initialize the ChannelManager.
+ let config_after_restart = {
+ let persister = test_utils::TestPersister::new();
+ let chain_monitor = test_utils::TestChainMonitor::new(
+ Some(nodes[1].chain_source), nodes[1].tx_broadcaster.clone(), nodes[1].logger,
+ node_cfgs[1].fee_estimator, &persister, nodes[1].keys_manager,
+ );
+
+ let mut chanmon_1 = <(_, ChannelMonitor<_>)>::read(
+ &mut &get_monitor!(nodes[1], other_channel.3).encode()[..], nodes[1].keys_manager,
+ ).unwrap().1;
+ let mut chanmon_2 = <(_, ChannelMonitor<_>)>::read(
+ &mut &get_monitor!(nodes[1], channel_to_update.0).encode()[..], nodes[1].keys_manager,
+ ).unwrap().1;
+ let mut channel_monitors = HashMap::new();
+ channel_monitors.insert(chanmon_1.get_funding_txo().0, &mut chanmon_1);
+ channel_monitors.insert(chanmon_2.get_funding_txo().0, &mut chanmon_2);
+
+ let chanmgr = <(_, ChannelManager<_, _, _, _, _, _>)>::read(
+ &mut &nodes[1].node.encode()[..], ChannelManagerReadArgs {
+ default_config: *nodes[1].node.get_current_default_configuration(),
+ keys_manager: nodes[1].keys_manager,
+ fee_estimator: node_cfgs[1].fee_estimator,
+ chain_monitor: &chain_monitor,
+ tx_broadcaster: nodes[1].tx_broadcaster.clone(),
+ logger: nodes[1].logger,
+ channel_monitors: channel_monitors,
+ },
+ ).unwrap().1;
+ chanmgr.list_channels().iter()
+ .find(|channel| channel.channel_id == channel_to_update.0).unwrap()
+ .config.unwrap()
+ };
+ assert_eq!(config, config_after_restart);