From 0d60b0cbb47351f1ce20144d5bfebc825f8b9062 Mon Sep 17 00:00:00 2001 From: Schalk van Heerden Date: Wed, 12 Sep 2018 12:09:15 +0200 Subject: [PATCH] rebase to new master --- src/ln/channel.rs | 44 ++++++++++++++++++++++++++------------ src/ln/channelmanager.rs | 10 +++++---- src/ln/router.rs | 2 ++ src/util/configurations.rs | 37 ++++++++++++++++++++++++++++++++ src/util/mod.rs | 3 +++ 5 files changed, 78 insertions(+), 18 deletions(-) create mode 100644 src/util/configurations.rs diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 83698f11..e7c395e3 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -26,6 +26,7 @@ use util::ser::Writeable; use util::sha2::Sha256; use util::logger::Logger; use util::errors::APIError; +use util::configurations::UserConfigurations; use std; use std::default::Default; @@ -259,11 +260,14 @@ const BOTH_SIDES_SHUTDOWN_MASK: u32 = (ChannelState::LocalShutdownSent as u32 | const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1; + // TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking // has been completed, and then turn into a Channel to get compiler-time enforcement of things like // calling channel_id() before we're set up or things like get_outbound_funding_signed on an // inbound channel. pub(super) struct Channel { + + config : UserConfigurations, user_id: u64, channel_id: [u8; 32], @@ -403,7 +407,7 @@ impl Channel { } // Constructors: - pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, announce_publicly: bool, user_id: u64, logger: Arc) -> Result { + pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, announce_publicly: bool, user_id: u64, logger: Arc, configurations: &UserConfigurations) -> Result { if channel_value_satoshis >= MAX_FUNDING_SATOSHIS { return Err(APIError::APIMisuseError{err: "funding value > 2^24"}); } @@ -430,7 +434,7 @@ impl Channel { Ok(Channel { user_id: user_id, - + config : configurations.clone(), channel_id: rng::rand_u832(), channel_state: ChannelState::OurInitSent as u32, channel_outbound: true, @@ -500,7 +504,7 @@ impl Channel { /// Assumes chain_hash has already been checked and corresponds with what we expect! /// Generally prefers to take the DisconnectPeer action on failure, as a notice to the sender /// that we're rejecting the new channel. - pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc) -> Result { + pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc, configurations : &UserConfigurations) -> Result { macro_rules! return_error_message { ( $msg: expr ) => { return Err(HandleError{err: $msg, action: Some(msgs::ErrorAction::SendErrorMessage{ msg: msgs::ErrorMessage { channel_id: msg.temporary_channel_id, data: $msg.to_string() }})}); @@ -539,6 +543,26 @@ impl Channel { if msg.max_accepted_htlcs > 483 { return_error_message!("max_accpted_htlcs > 483"); } + //optional parameter checking + // MAY fail the channel if + if msg.funding_satoshis < configurations.channel_limits.funding_satoshis { + return_error_message!("funding satoshis is less than the user specified limit"); + } + if msg.htlc_minimum_msat > configurations.channel_limits.htlc_minimum_msat { + return_error_message!("htlc minimum msat is higher than the user specified limit"); + } + if msg.max_htlc_value_in_flight_msat < configurations.channel_limits.max_htlc_value_in_flight_msat { + return_error_message!("max htlc value in flight msat is less than the user specified limit"); + } + if msg.channel_reserve_satoshis > configurations.channel_limits.channel_reserve_satoshis { + return_error_message!("channel reserve satoshis is higher than the user specified limit"); + } + if msg.max_accepted_htlcs < configurations.channel_limits.max_accepted_htlcs { + return_error_message!("max accepted htlcs is less than the user specified limit"); + } + if msg.dust_limit_satoshis < configurations.channel_limits.dust_limit_satoshis { + return_error_message!("dust limit satoshis is less than the user specified limit"); + } // Convert things into internal flags and prep our state: @@ -589,7 +613,7 @@ impl Channel { let mut chan = Channel { user_id: user_id, - + config: (*configurations).clone(), channel_id: msg.temporary_channel_id, channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32), channel_outbound: false, @@ -1245,15 +1269,6 @@ impl Channel { return_error_message!("max_accpted_htlcs > 483"); } - // TODO: Optional additional constraints mentioned in the spec - // MAY fail the channel if - // funding_satoshi is too small - // htlc_minimum_msat too large - // max_htlc_value_in_flight_msat too small - // channel_reserve_satoshis too large - // max_accepted_htlcs too small - // dust_limit_satoshis too small - self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint); self.their_dust_limit_satoshis = msg.dust_limit_satoshis; @@ -2872,6 +2887,7 @@ mod tests { #[test] fn outbound_commitment_test() { + use util::configurations::UserConfigurations; // Test vectors from BOLT 3 Appendix C: let feeest = TestFeeEstimator{fee_est: 15000}; let logger : Arc = Arc::new(test_utils::TestLogger::new()); @@ -2893,7 +2909,7 @@ mod tests { hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]); let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap()); - let mut chan = Channel::new_outbound(&feeest, chan_keys, their_node_id, 10000000, 100000, false, 42, Arc::clone(&logger)).unwrap(); // Nothing uses their network key in this test + let mut chan = Channel::new_outbound(&feeest, chan_keys, their_node_id, 10000000, 100000, false, 42, Arc::clone(&logger), &UserConfigurations::new()).unwrap(); // Nothing uses their network key in this test chan.their_to_self_delay = 144; chan.our_dust_limit_satoshis = 546; diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index ba535d00..077caa0e 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -27,6 +27,7 @@ use ln::channelmonitor::ManyChannelMonitor; use ln::router::{Route,RouteHop}; use ln::msgs; use ln::msgs::{HandleError,ChannelMessageHandler}; +use util::configurations::UserConfigurations; use util::{byte_utils, events, internal_traits, rng}; use util::sha2::Sha256; use util::ser::{Readable, Writeable}; @@ -229,6 +230,7 @@ const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assum /// Implements ChannelMessageHandler, handling the multi-channel parts and passing things through /// to individual Channels. pub struct ChannelManager { + configuration : UserConfigurations, genesis_hash: Sha256dHash, fee_estimator: Arc, monitor: Arc, @@ -301,6 +303,7 @@ impl ChannelManager { let secp_ctx = Secp256k1::new(); let res = Arc::new(ChannelManager { + configuration : UserConfigurations::new(), genesis_hash: genesis_block(network).header.bitcoin_hash(), fee_estimator: feeest.clone(), monitor: monitor.clone(), @@ -362,7 +365,7 @@ impl ChannelManager { } }; - let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, push_msat, self.announce_channels_publicly, user_id, Arc::clone(&self.logger))?; + let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, push_msat, self.announce_channels_publicly, user_id, Arc::clone(&self.logger), &self.configuration)?; let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator); let mut channel_state = self.channel_state.lock().unwrap(); match channel_state.by_id.insert(channel.channel_id(), channel) { @@ -1457,7 +1460,7 @@ impl ChannelManager { } }; - let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger)).map_err(|e| MsgHandleErrInternal::from_no_close(e))?; + let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger), &self.configuration).map_err(|e| MsgHandleErrInternal::from_no_close(e))?; let accept_msg = channel.get_accept_channel(); channel_state.by_id.insert(channel.channel_id(), channel); Ok(accept_msg) @@ -1483,8 +1486,7 @@ impl ChannelManager { pending_events.push(events::Event::FundingGenerationReady { temporary_channel_id: msg.temporary_channel_id, channel_value_satoshis: value, - output_script: output_script, - user_channel_id: user_id, + output_script: output_script, user_channel_id: user_id, }); Ok(()) } diff --git a/src/ln/router.rs b/src/ln/router.rs index 4a55df88..5d5948dd 100644 --- a/src/ln/router.rs +++ b/src/ln/router.rs @@ -77,6 +77,8 @@ impl std::fmt::Display for ChannelInfo { } } + + struct NodeInfo { #[cfg(feature = "non_bitcoin_chain_hash_routing")] channels: Vec<(u64, Sha256dHash)>, diff --git a/src/util/configurations.rs b/src/util/configurations.rs new file mode 100644 index 00000000..aef81950 --- /dev/null +++ b/src/util/configurations.rs @@ -0,0 +1,37 @@ +#[derive(Copy, Clone)] +pub struct UserConfigurations{ + pub channel_limits : ChannelLimits, +} + +impl UserConfigurations { + pub fn new() -> Self{ + UserConfigurations { + channel_limits : ChannelLimits::new(), + } + } +} + +#[derive(Copy, Clone)] +pub struct ChannelLimits +{ + pub funding_satoshis :u64, + pub htlc_minimum_msat : u64, + pub max_htlc_value_in_flight_msat : u64, + pub channel_reserve_satoshis : u64, + pub max_accepted_htlcs : u16, + pub dust_limit_satoshis : u64, +} + +impl ChannelLimits { + //creating max and min possible values because if they are not set, means we should not check them. + pub fn new() -> Self{ + ChannelLimits { + funding_satoshis : 0, + htlc_minimum_msat : ::max_value(), + max_htlc_value_in_flight_msat : 0, + channel_reserve_satoshis : ::max_value(), + max_accepted_htlcs : 0, + dust_limit_satoshis : 0, + } + } +} \ No newline at end of file diff --git a/src/util/mod.rs b/src/util/mod.rs index b91b4f25..02e873aa 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -28,3 +28,6 @@ pub use self::rng::reset_rng_state; #[cfg(test)] pub(crate) mod test_utils; + +pub use self::configurations::{UserConfigurations, ChannelLimits}; +pub mod configurations; -- 2.30.2