Add push_msat to new outbound API
authorYuntai Kyong <yuntai.kyong@gmail.com>
Tue, 14 Aug 2018 15:59:42 +0000 (00:59 +0900)
committerMatt Corallo <git@bluematt.me>
Fri, 17 Aug 2018 17:18:28 +0000 (13:18 -0400)
Also add APIMisuseError to be thrown to the API client

fuzz/fuzz_targets/channel_target.rs
fuzz/fuzz_targets/full_stack_target.rs
src/ln/channel.rs
src/ln/channelmanager.rs

index 38f898c53298d59673c2064fbd928633e91a7d38..903b45fbcf703e5999c91d4d0b085e7c1d12b50e 100644 (file)
@@ -199,7 +199,10 @@ pub fn do_test(data: &[u8]) {
        let mut channel = if get_slice!(1)[0] != 0 {
                let chan_value = slice_to_be24(get_slice!(3));
 
-               let mut chan = Channel::new_outbound(&fee_est, chan_keys!(), their_pubkey, chan_value, get_slice!(1)[0] == 0, slice_to_be64(get_slice!(8)), Arc::clone(&logger));
+               let mut chan = match Channel::new_outbound(&fee_est, chan_keys!(), their_pubkey, chan_value, slice_to_be24(get_slice!(3)), get_slice!(1)[0] == 0, slice_to_be64(get_slice!(8)), Arc::clone(&logger)) {
+                       Ok(chan) => chan,
+                       Err(_) => return,
+               };
                chan.get_open_channel(Sha256dHash::from(get_slice!(32)), &fee_est).unwrap();
                let accept_chan = if get_slice!(1)[0] == 0 {
                        decode_msg_with_len16!(msgs::AcceptChannel, 270, 1)
index e6515b41e7b087911c5796cc5f3caf661adb1c4e..75456127eb2c7e0d195f50425f29bdf601410120 100644 (file)
@@ -257,7 +257,8 @@ pub fn do_test(data: &[u8]) {
                                if !peers.borrow()[peer_id as usize] { return; }
                                let their_key = get_pubkey!();
                                let chan_value = slice_to_be24(get_slice!(3)) as u64;
-                               if channelmanager.create_channel(their_key, chan_value, 0).is_err() { return; }
+                               let push_msat_value = slice_to_be24(get_slice!(3)) as u64;
+                               if channelmanager.create_channel(their_key, chan_value, push_msat_value, 0).is_err() { return; }
                        },
                        6 => {
                                let mut channels = channelmanager.list_channels();
index 1a195d504a117ea6590c4605974568443e8f3275..c88e1d7763125f118c015cb82bc3dbc5914a2c78 100644 (file)
@@ -24,6 +24,7 @@ use chain::transaction::OutPoint;
 use util::{transaction_utils,rng};
 use util::sha2::Sha256;
 use util::logger::{Logger, Record};
+use util::errors::APIError;
 
 use std;
 use std::default::Default;
@@ -372,11 +373,13 @@ impl Channel {
        }
 
        // Constructors:
-
-       /// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`
-       pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, announce_publicly: bool, user_id: u64, logger: Arc<Logger>) -> Channel {
+       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<Logger>) -> Result<Channel, APIError> {
                if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
-                       panic!("funding value > 2^24");
+                       return Err(APIError::APIMisuseError{err: "funding value > 2^24"});
+               }
+
+               if push_msat > channel_value_satoshis * 1000 {
+                       return Err(APIError::APIMisuseError{err: "push value > channel value"});
                }
 
                let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
@@ -390,7 +393,7 @@ impl Channel {
                                                          &chan_keys.htlc_base_key,
                                                          BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script);
 
-               Channel {
+               Ok(Channel {
                        user_id: user_id,
 
                        channel_id: rng::rand_u832(),
@@ -403,7 +406,7 @@ impl Channel {
                        local_keys: chan_keys,
                        cur_local_commitment_transaction_number: (1 << 48) - 1,
                        cur_remote_commitment_transaction_number: (1 << 48) - 1,
-                       value_to_self_msat: channel_value_satoshis * 1000, //TODO: give them something on open? Parameterize it?
+                       value_to_self_msat: channel_value_satoshis * 1000 - push_msat,
                        pending_htlcs: Vec::new(),
                        holding_cell_htlc_updates: Vec::new(),
                        next_local_htlc_id: 0,
@@ -444,7 +447,7 @@ impl Channel {
                        channel_monitor: channel_monitor,
 
                        logger,
-               }
+               })
        }
 
        fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), HandleError> {
@@ -2031,12 +2034,12 @@ impl Channel {
        // Methods to get unprompted messages to send to the remote end (or where we already returned
        // something in the handler for the message that prompted this message):
 
-       pub fn get_open_channel(&self, chain_hash: Sha256dHash, fee_estimator: &FeeEstimator) -> Result<msgs::OpenChannel, HandleError> {
+       pub fn get_open_channel(&self, chain_hash: Sha256dHash, fee_estimator: &FeeEstimator) -> Result<msgs::OpenChannel, APIError> {
                if !self.channel_outbound {
                        panic!("Tried to open a channel for an inbound channel?");
                }
                if self.channel_state != ChannelState::OurInitSent as u32 {
-                       return Err(HandleError{err: "Cannot generate an open_channel after we've moved forward", action: None});
+                       panic!("Cannot generate an open_channel after we've moved forward");
                }
 
                if self.cur_local_commitment_transaction_number != (1 << 48) - 1 {
@@ -2049,7 +2052,7 @@ impl Channel {
                        chain_hash: chain_hash,
                        temporary_channel_id: self.channel_id,
                        funding_satoshis: self.channel_value_satoshis,
-                       push_msat: 0, //TODO: Something about feerate?
+                       push_msat: self.channel_value_satoshis * 1000 - self.value_to_self_msat,
                        dust_limit_satoshis: self.our_dust_limit_satoshis,
                        max_htlc_value_in_flight_msat: Channel::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis),
                        channel_reserve_satoshis: Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis),
@@ -2478,7 +2481,7 @@ mod tests {
                assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan_keys.funding_key).unwrap().serialize()[..],
                                hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]);
 
-               let mut chan = Channel::new_outbound(&feeest, chan_keys, PublicKey::new(), 10000000, false, 42, Arc::clone(&logger)); // Nothing uses their network key in this test
+               let mut chan = Channel::new_outbound(&feeest, chan_keys, PublicKey::new(), 10000000, 100000, false, 42, Arc::clone(&logger)).unwrap(); // Nothing uses their network key in this test
                chan.their_to_self_delay = 144;
                chan.our_dust_limit_satoshis = 546;
 
index e142e8ad5091bb52a9290e1694fbf0e6df6f000f..03cad49ea56af9cf051e1cb2c5e173b3965033b4 100644 (file)
@@ -21,6 +21,7 @@ use util::{byte_utils, events, internal_traits, rng};
 use util::sha2::Sha256;
 use util::chacha20poly1305rfc::ChaCha20;
 use util::logger::{Logger, Record};
+use util::errors::APIError;
 
 use crypto;
 use crypto::mac::{Mac,MacResult};
@@ -254,7 +255,8 @@ impl ChannelManager {
        /// may wish to avoid using 0 for user_id here.
        /// If successful, will generate a SendOpenChannel event, so you should probably poll
        /// PeerManager::process_events afterwards.
-       pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, user_id: u64) -> Result<(), HandleError> {
+       /// Raises APIError::APIMisuseError when channel_value_satoshis > 2**24 or push_msat being greater than channel_value_satoshis * 1k
+       pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64) -> Result<(), APIError> {
                let chan_keys = if cfg!(feature = "fuzztarget") {
                        ChannelKeys {
                                funding_key:               SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
@@ -275,7 +277,7 @@ impl ChannelManager {
                        }
                };
 
-               let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, 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))?;
                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) {
@@ -2192,7 +2194,7 @@ mod tests {
 
        static mut CHAN_COUNT: u32 = 0;
        fn create_chan_between_nodes(node_a: &Node, node_b: &Node) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
-               node_a.node.create_channel(node_b.node.get_our_node_id(), 100000, 42).unwrap();
+               node_a.node.create_channel(node_b.node.get_our_node_id(), 100000, 10001, 42).unwrap();
 
                let events_1 = node_a.node.get_and_clear_pending_events();
                assert_eq!(events_1.len(), 1);