+ #[test]
+ fn test_configured_holder_selected_channel_reserve_satoshis() {
+
+ // Test that `new_outbound` and `new_from_req` create a channel with the correct
+ // channel reserves, when `their_channel_reserve_proportional_millionths` is configured.
+ test_self_and_counterparty_channel_reserve(10_000_000, 0.02, 0.02);
+
+ // Test with valid but unreasonably high channel reserves
+ // Requesting and accepting parties have requested for 49%-49% and 60%-30% channel reserve
+ test_self_and_counterparty_channel_reserve(10_000_000, 0.49, 0.49);
+ test_self_and_counterparty_channel_reserve(10_000_000, 0.60, 0.30);
+
+ // Test with calculated channel reserve less than lower bound
+ // i.e `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
+ test_self_and_counterparty_channel_reserve(100_000, 0.00002, 0.30);
+
+ // Test with invalid channel reserves since sum of both is greater than or equal
+ // to channel value
+ test_self_and_counterparty_channel_reserve(10_000_000, 0.50, 0.50);
+ test_self_and_counterparty_channel_reserve(10_000_000, 0.60, 0.50);
+ }
+
+ fn test_self_and_counterparty_channel_reserve(channel_value_satoshis: u64, outbound_selected_channel_reserve_perc: f64, inbound_selected_channel_reserve_perc: f64) {
+ let fee_est = LowerBoundedFeeEstimator::new(&TestFeeEstimator { fee_est: 15_000 });
+ let logger = test_utils::TestLogger::new();
+ let secp_ctx = Secp256k1::new();
+ let seed = [42; 32];
+ let network = Network::Testnet;
+ let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
+ let outbound_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+ let inbound_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
+
+
+ let mut outbound_node_config = UserConfig::default();
+ outbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (outbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
+ let chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(), channel_value_satoshis, 100_000, 42, &outbound_node_config, 0, 42).unwrap();
+
+ let expected_outbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.channel_value_satoshis as f64 * outbound_selected_channel_reserve_perc) as u64);
+ assert_eq!(chan.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve);
+
+ let chan_open_channel_msg = chan.get_open_channel(genesis_block(network).header.block_hash());
+ let mut inbound_node_config = UserConfig::default();
+ inbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (inbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
+
+ if outbound_selected_channel_reserve_perc + inbound_selected_channel_reserve_perc < 1.0 {
+ let chan_inbound_node = Channel::<EnforcingSigner>::new_from_req(&&fee_est, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_open_channel_msg, 7, &inbound_node_config, 0, &&logger, 42).unwrap();
+
+ let expected_inbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.channel_value_satoshis as f64 * inbound_selected_channel_reserve_perc) as u64);
+
+ assert_eq!(chan_inbound_node.holder_selected_channel_reserve_satoshis, expected_inbound_selected_chan_reserve);
+ assert_eq!(chan_inbound_node.counterparty_selected_channel_reserve_satoshis.unwrap(), expected_outbound_selected_chan_reserve);
+ } else {
+ // Channel Negotiations failed
+ let result = Channel::<EnforcingSigner>::new_from_req(&&fee_est, &&keys_provider, inbound_node_id, &channelmanager::provided_init_features(), &chan_open_channel_msg, 7, &inbound_node_config, 0, &&logger, 42);
+ assert!(result.is_err());
+ }
+ }
+