Merge pull request #334 from ariard/2019-04-fee-estimation-monitor
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Sun, 21 Apr 2019 23:44:58 +0000 (19:44 -0400)
committerGitHub <noreply@github.com>
Sun, 21 Apr 2019 23:44:58 +0000 (19:44 -0400)
Add Fee Estimation in ChannelMonitor

fuzz/fuzz_targets/chanmon_fail_consistency.rs
fuzz/fuzz_targets/full_stack_target.rs
src/ln/channel.rs
src/ln/channelmonitor.rs
src/ln/functional_test_utils.rs
src/util/config.rs
src/util/transaction_utils.rs

index dd8023ecddc9f10a1b2d4a7e553ea8285bbc7f0d..b12ebea60f5d43806e46f7d2cafb4db2cc6e43a0 100644 (file)
@@ -148,7 +148,7 @@ pub fn do_test(data: &[u8]) {
                        let mut config = UserConfig::new();
                        config.channel_options.fee_proportional_millionths = 0;
                        config.channel_options.announced_channel = true;
-                       config.channel_limits.min_dust_limit_satoshis = 0;
+                       config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
                        (ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config).unwrap(),
                        monitor)
                } }
index 8b477dfa905c90ca9caf16522dca75575d2c80f9..16bebfbd01bde8b64908d5cbf58ab0645d67a794 100644 (file)
@@ -350,7 +350,7 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
        let mut config = UserConfig::new();
        config.channel_options.fee_proportional_millionths =  slice_to_be32(get_slice!(4));
        config.channel_options.announced_channel = get_slice!(1)[0] != 0;
-       config.channel_limits.min_dust_limit_satoshis = 0;
+       config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
        let channelmanager = ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config).unwrap();
        let router = Arc::new(Router::new(PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret()), watch.clone(), Arc::clone(&logger)));
 
index b67468b3859ecd5e1a50c951ce02d6670f39d05d..17d1d5aa042301ebf16b7a0190089ca406ca4cf0 100644 (file)
@@ -410,13 +410,6 @@ impl Channel {
                1000 // TODO
        }
 
-       fn derive_minimum_depth(_channel_value_satoshis_msat: u64, _value_to_self_msat: u64) -> u32 {
-               // Note that in order to comply with BOLT 7 announcement_signatures requirements this must
-               // be at least 6.
-               const CONF_TARGET: u32 = 12; //TODO: Should be much higher
-               CONF_TARGET
-       }
-
        // Constructors:
        pub fn new_outbound(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel, APIError> {
                let chan_keys = keys_provider.get_channel_keys(false);
@@ -565,32 +558,32 @@ impl Channel {
                }
 
                // Now check against optional parameters as set by config...
-               if msg.funding_satoshis < config.channel_limits.min_funding_satoshis {
+               if msg.funding_satoshis < config.peer_channel_config_limits.min_funding_satoshis {
                        return Err(ChannelError::Close("funding satoshis is less than the user specified limit"));
                }
-               if msg.htlc_minimum_msat > config.channel_limits.max_htlc_minimum_msat {
+               if msg.htlc_minimum_msat > config.peer_channel_config_limits.max_htlc_minimum_msat {
                        return Err(ChannelError::Close("htlc minimum msat is higher than the user specified limit"));
                }
-               if msg.max_htlc_value_in_flight_msat < config.channel_limits.min_max_htlc_value_in_flight_msat {
+               if msg.max_htlc_value_in_flight_msat < config.peer_channel_config_limits.min_max_htlc_value_in_flight_msat {
                        return Err(ChannelError::Close("max htlc value in flight msat is less than the user specified limit"));
                }
-               if msg.channel_reserve_satoshis > config.channel_limits.max_channel_reserve_satoshis {
+               if msg.channel_reserve_satoshis > config.peer_channel_config_limits.max_channel_reserve_satoshis {
                        return Err(ChannelError::Close("channel reserve satoshis is higher than the user specified limit"));
                }
-               if msg.max_accepted_htlcs < config.channel_limits.min_max_accepted_htlcs {
+               if msg.max_accepted_htlcs < config.peer_channel_config_limits.min_max_accepted_htlcs {
                        return Err(ChannelError::Close("max accepted htlcs is less than the user specified limit"));
                }
-               if msg.dust_limit_satoshis < config.channel_limits.min_dust_limit_satoshis {
+               if msg.dust_limit_satoshis < config.peer_channel_config_limits.min_dust_limit_satoshis {
                        return Err(ChannelError::Close("dust limit satoshis is less than the user specified limit"));
                }
-               if msg.dust_limit_satoshis > config.channel_limits.max_dust_limit_satoshis {
+               if msg.dust_limit_satoshis > config.peer_channel_config_limits.max_dust_limit_satoshis {
                        return Err(ChannelError::Close("dust limit satoshis is greater than the user specified limit"));
                }
 
                // Convert things into internal flags and prep our state:
 
                let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false };
-               if config.channel_limits.force_announced_channel_preference {
+               if config.peer_channel_config_limits.force_announced_channel_preference {
                        if local_config.announced_channel != their_announce {
                                return Err(ChannelError::Close("Peer tried to open channel but their announcement preference is different from ours"));
                        }
@@ -687,7 +680,7 @@ impl Channel {
                        our_htlc_minimum_msat: Channel::derive_our_htlc_minimum_msat(msg.feerate_per_kw as u64),
                        their_to_self_delay: msg.to_self_delay,
                        their_max_accepted_htlcs: msg.max_accepted_htlcs,
-                       minimum_depth: Channel::derive_minimum_depth(msg.funding_satoshis*1000, msg.push_msat),
+                       minimum_depth: config.own_channel_config.minimum_depth,
 
                        their_funding_pubkey: Some(msg.funding_pubkey),
                        their_revocation_basepoint: Some(msg.revocation_basepoint),
@@ -1383,25 +1376,25 @@ impl Channel {
                }
 
                // Now check against optional parameters as set by config...
-               if msg.htlc_minimum_msat > config.channel_limits.max_htlc_minimum_msat {
+               if msg.htlc_minimum_msat > config.peer_channel_config_limits.max_htlc_minimum_msat {
                        return Err(ChannelError::Close("htlc minimum msat is higher than the user specified limit"));
                }
-               if msg.max_htlc_value_in_flight_msat < config.channel_limits.min_max_htlc_value_in_flight_msat {
+               if msg.max_htlc_value_in_flight_msat < config.peer_channel_config_limits.min_max_htlc_value_in_flight_msat {
                        return Err(ChannelError::Close("max htlc value in flight msat is less than the user specified limit"));
                }
-               if msg.channel_reserve_satoshis > config.channel_limits.max_channel_reserve_satoshis {
+               if msg.channel_reserve_satoshis > config.peer_channel_config_limits.max_channel_reserve_satoshis {
                        return Err(ChannelError::Close("channel reserve satoshis is higher than the user specified limit"));
                }
-               if msg.max_accepted_htlcs < config.channel_limits.min_max_accepted_htlcs {
+               if msg.max_accepted_htlcs < config.peer_channel_config_limits.min_max_accepted_htlcs {
                        return Err(ChannelError::Close("max accepted htlcs is less than the user specified limit"));
                }
-               if msg.dust_limit_satoshis < config.channel_limits.min_dust_limit_satoshis {
+               if msg.dust_limit_satoshis < config.peer_channel_config_limits.min_dust_limit_satoshis {
                        return Err(ChannelError::Close("dust limit satoshis is less than the user specified limit"));
                }
-               if msg.dust_limit_satoshis > config.channel_limits.max_dust_limit_satoshis {
+               if msg.dust_limit_satoshis > config.peer_channel_config_limits.max_dust_limit_satoshis {
                        return Err(ChannelError::Close("dust limit satoshis is greater than the user specified limit"));
                }
-               if msg.minimum_depth > config.channel_limits.max_minimum_depth {
+               if msg.minimum_depth > config.peer_channel_config_limits.max_minimum_depth {
                        return Err(ChannelError::Close("We consider the minimum depth to be unreasonably large"));
                }
 
index 0b0838781d14fc5369000a8b007305d9df638b92..e1d960e5130baaff7a7622f24e01c6d785efe4a0 100644 (file)
@@ -842,18 +842,8 @@ impl ChannelMonitor {
                                writer.write_all(&delayed_payment_base_key[..])?;
                                writer.write_all(&payment_base_key[..])?;
                                writer.write_all(&shutdown_pubkey.serialize())?;
-                               if let Some(ref prev_latest_per_commitment_point) = *prev_latest_per_commitment_point {
-                                       writer.write_all(&[1; 1])?;
-                                       writer.write_all(&prev_latest_per_commitment_point.serialize())?;
-                               } else {
-                                       writer.write_all(&[0; 1])?;
-                               }
-                               if let Some(ref latest_per_commitment_point) = *latest_per_commitment_point {
-                                       writer.write_all(&[1; 1])?;
-                                       writer.write_all(&latest_per_commitment_point.serialize())?;
-                               } else {
-                                       writer.write_all(&[0; 1])?;
-                               }
+                               prev_latest_per_commitment_point.write(writer)?;
+                               latest_per_commitment_point.write(writer)?;
                                match funding_info  {
                                        &Some((ref outpoint, ref script)) => {
                                                writer.write_all(&outpoint.txid[..])?;
@@ -864,8 +854,8 @@ impl ChannelMonitor {
                                                debug_assert!(false, "Try to serialize a useless Local monitor !");
                                        },
                                }
-                               write_option!(current_remote_commitment_txid);
-                               write_option!(prev_remote_commitment_txid);
+                               current_remote_commitment_txid.write(writer)?;
+                               prev_remote_commitment_txid.write(writer)?;
                        },
                        Storage::Watchtower { .. } => unimplemented!(),
                }
@@ -905,7 +895,7 @@ impl ChannelMonitor {
                                writer.write_all(&byte_utils::be64_to_array($htlc_output.amount_msat))?;
                                writer.write_all(&byte_utils::be32_to_array($htlc_output.cltv_expiry))?;
                                writer.write_all(&$htlc_output.payment_hash.0[..])?;
-                               write_option!(&$htlc_output.transaction_output_index);
+                               $htlc_output.transaction_output_index.write(writer)?;
                        }
                }
 
index c5d6751d9a999c6ecc19119dd8ff121f2bff6092..9a24d503ceea3d5323ab8783f84d274f56d0388f 100644 (file)
@@ -824,7 +824,7 @@ pub fn create_network(node_count: usize) -> Vec<Node> {
                let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone(), logger.clone(), feeest.clone()));
                let mut config = UserConfig::new();
                config.channel_options.announced_channel = true;
-               config.channel_limits.force_announced_channel_preference = false;
+               config.peer_channel_config_limits.force_announced_channel_preference = false;
                let node = ChannelManager::new(Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger), keys_manager.clone(), config).unwrap();
                let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), chain_monitor.clone(), Arc::clone(&logger));
                nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, keys_manager, node_seed: seed,
index a3abdbedeecc9e88174899b05b76330dda22ce22..f3b574b93fba6c40389761994cb92cddb1b3480a 100644 (file)
@@ -4,8 +4,10 @@
 /// Top-level config which holds ChannelHandshakeLimits and ChannelConfig.
 #[derive(Clone, Debug)]
 pub struct UserConfig {
-       /// Limits applied during channel creation.
-       pub channel_limits: ChannelHandshakeLimits,
+       /// Channel config that we propose to our counterparty.
+       pub own_channel_config: ChannelHandshakeConfig,
+       /// Limits applied to our counterparty's proposed channel config settings.
+       pub peer_channel_config_limits: ChannelHandshakeLimits,
        /// Channel config which affects behavior during channel lifetime.
        pub channel_options: ChannelConfig,
 }
@@ -14,12 +16,31 @@ impl UserConfig {
        /// Provides sane defaults for most configurations (but with 0 relay fees!)
        pub fn new() -> Self{
                UserConfig {
-                       channel_limits: ChannelHandshakeLimits::new(),
+                       own_channel_config: ChannelHandshakeConfig::new(),
+                       peer_channel_config_limits: ChannelHandshakeLimits::new(),
                        channel_options: ChannelConfig::new(),
                }
        }
 }
 
+/// Configuration we set when applicable.
+#[derive(Clone, Debug)]
+pub struct ChannelHandshakeConfig {
+       /// Confirmations we will wait for before considering the channel locked in.
+       /// Applied only for inbound channels (see ChannelHandshakeLimits::max_minimum_depth for the
+       /// equivalent limit applied to outbound channels).
+       pub minimum_depth: u32,
+}
+
+impl ChannelHandshakeConfig {
+       /// Provides sane defaults for `ChannelHandshakeConfig`
+       pub fn new() -> ChannelHandshakeConfig {
+               ChannelHandshakeConfig {
+                       minimum_depth: 6,
+               }
+       }
+}
+
 /// Optional channel limits which are applied during channel creation.
 ///
 /// These limits are only applied to our counterparty's limits, not our own.
index f9ee1bd82effd4737176359e64f21087fd8bf51b..a7c1e6bc6f78a48e15b69cf4081f0b88534b30e3 100644 (file)
@@ -88,6 +88,26 @@ mod tests {
                assert_eq!(&outputs, &vec![(txout1_, "ignore"), (txout2_, "ignore")]);
        }
 
+       #[test]
+       fn sort_output_tie_breaker_test() {
+               let txout1 = TxOut {
+                       value:  100,
+                       script_pubkey: Builder::new().push_int(1).push_int(2).into_script()
+               };
+               let txout1_ = txout1.clone();
+
+               let txout2 = txout1.clone();
+               let txout2_ = txout1.clone();
+
+               let mut outputs = vec![(txout1, 420), (txout2, 69)];
+               sort_outputs(&mut outputs, |a, b| { a.cmp(b) });
+
+               assert_eq!(
+                       &outputs,
+                       &vec![(txout2_, 69), (txout1_, 420)]
+               );
+       }
+
        fn script_from_hex(hex_str: &str) -> Script {
                Script::from(decode(hex_str).unwrap())
        }