Merge pull request #84 from savil/sort_outputs
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Thu, 26 Jul 2018 15:54:17 +0000 (11:54 -0400)
committerGitHub <noreply@github.com>
Thu, 26 Jul 2018 15:54:17 +0000 (11:54 -0400)
[RFC][Tx Sort] Implement sorting of inputs

24 files changed:
.editorconfig [new file with mode: 0644]
Cargo.toml
build.rs
fuzz/Cargo.toml
fuzz/fuzz_targets/channel_target.rs
fuzz/fuzz_targets/full_stack_target.rs
fuzz/fuzz_targets/msg_targets/gen_target.sh
fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/router_target.rs [new file with mode: 0644]
src/chain/chaininterface.rs
src/chain/transaction.rs
src/ln/channel.rs
src/ln/channelmanager.rs
src/ln/channelmonitor.rs
src/ln/mod.rs
src/ln/msgs.rs
src/ln/peer_channel_encryptor.rs
src/ln/peer_handler.rs
src/ln/router.rs
src/util/events.rs
src/util/mod.rs
src/util/rng.rs
src/util/test_utils.rs

diff --git a/.editorconfig b/.editorconfig
new file mode 100644 (file)
index 0000000..b19ed0f
--- /dev/null
@@ -0,0 +1,4 @@
+# see https://editorconfig.org for more options, and setup instructions for yours editor
+
+[*]
+indent_style = tab
index 5842585acad2a9b7f54ae6073e8fa124e64c09d4..8add037f394bf8ef5d270e06b44d0fad8e2a8f11 100644 (file)
@@ -1,12 +1,13 @@
 [package]
 name = "lightning"
-version = "0.0.3"
+version = "0.0.4"
 authors = ["Matt Corallo"]
 license = "Apache-2.0"
 repository = "https://github.com/rust-bitcoin/rust-lightning/"
 description = """
-A Bitcoin Lightning implementation in Rust.
-Still super-early code-dump quality and is missing large chunks. See README in git repo for suggested projects if you want to contribute. Don't have to bother telling you not to use this for anything serious, because you'd have to finish building it to even try.
+A Bitcoin Lightning library in Rust.
+Does most of the hard work, without implying a specific runtime, requiring clients implement basic network logic, chain interactions and disk storage.
+Still missing tons of error-handling. See GitHub issues for suggested projects if you want to contribute. Don't have to bother telling you not to use this for anything serious, because you'd have to build a client around it to even try.
 """
 build = "build.rs"
 
@@ -22,7 +23,7 @@ rand = "0.4"
 secp256k1 = "0.9"
 
 [build-dependencies]
-gcc = "0.3"
+cc = "1.0"
 
 [dev-dependencies.bitcoin]
 version = "0.13"
index 7dd340397ef5464ddb890ed75404401177fc350d..963075e920e2c87374f10e92ef1367aba9c3298f 100644 (file)
--- a/build.rs
+++ b/build.rs
@@ -1,9 +1,9 @@
-extern crate gcc;
+extern crate cc;
 
 fn main() {
        #[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm")))]
        {
-               let mut cfg = gcc::Build::new();
+               let mut cfg = cc::Build::new();
                cfg.file("src/util/rust_crypto_nonstd_arch.c");
                cfg.compile("lib_rust_crypto_nonstd_arch.a");
        }
index ac5373b7b18036148686dfa0d9bfe9c9a3eab1d6..22f4bdcc181a3706ddbaf6260e16ea5fa026aa55 100644 (file)
@@ -24,7 +24,7 @@ honggfuzz = { version = "0.5", optional = true }
 afl = { version = "0.3", optional = true }
 
 [build-dependencies]
-gcc = "0.3"
+cc = "1.0"
 
 # Prevent this from interfering with workspaces
 [workspace]
@@ -42,6 +42,10 @@ path = "fuzz_targets/channel_target.rs"
 name = "full_stack_target"
 path = "fuzz_targets/full_stack_target.rs"
 
+[[bin]]
+name = "router_target"
+path = "fuzz_targets/router_target.rs"
+
 [[bin]]
 name = "chanmon_deser_target"
 path = "fuzz_targets/chanmon_deser_target.rs"
@@ -110,3 +114,11 @@ path = "fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs"
 [[bin]]
 name = "msg_update_fail_htlc_target"
 path = "fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs"
+
+[[bin]]
+name = "msg_channel_reestablish_target"
+path = "fuzz_targets/msg_targets/msg_channel_reestablish_target.rs"
+
+[[bin]]
+name = "msg_error_message_target"
+path = "fuzz_targets/msg_targets/msg_error_message_target.rs"
index 23c63fee72bd0bb610e3d10acac798969a956889..1bcc3d708c677ecd52421264785146132d6d112e 100644 (file)
@@ -10,7 +10,7 @@ use bitcoin::network::serialize::{serialize, BitcoinHash};
 use lightning::ln::channel::{Channel, ChannelKeys};
 use lightning::ln::channelmanager::{HTLCFailReason, PendingForwardHTLCInfo};
 use lightning::ln::msgs;
-use lightning::ln::msgs::MsgDecodable;
+use lightning::ln::msgs::{MsgDecodable, ErrorAction};
 use lightning::chain::chaininterface::{FeeEstimator, ConfirmationTarget};
 use lightning::chain::transaction::OutPoint;
 use lightning::util::reset_rng_state;
@@ -80,10 +80,10 @@ struct FuzzEstimator<'a> {
        input: &'a InputData<'a>,
 }
 impl<'a> FeeEstimator for FuzzEstimator<'a> {
-       fn get_est_sat_per_vbyte(&self, _: ConfirmationTarget) -> u64 {
+       fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
                //TODO: We should actually be testing at least much more than 64k...
                match self.input.get_slice(2) {
-                       Some(slice) => slice_to_be16(slice) as u64,
+                       Some(slice) => slice_to_be16(slice) as u64 * 250,
                        None => 0
                }
        }
@@ -118,8 +118,10 @@ pub fn do_test(data: &[u8]) {
                                        msgs::DecodeError::UnknownRealmByte => return,
                                        msgs::DecodeError::BadPublicKey => return,
                                        msgs::DecodeError::BadSignature => return,
+                                       msgs::DecodeError::BadText => return,
                                        msgs::DecodeError::ExtraAddressesPerType => return,
-                                       msgs::DecodeError::WrongLength => panic!("We picked the length..."),
+                                       msgs::DecodeError::BadLengthDescriptor => return,
+                                       msgs::DecodeError::ShortRead => panic!("We picked the length..."),
                                }
                        }
                }
@@ -138,8 +140,10 @@ pub fn do_test(data: &[u8]) {
                                                msgs::DecodeError::UnknownRealmByte => return,
                                                msgs::DecodeError::BadPublicKey => return,
                                                msgs::DecodeError::BadSignature => return,
+                                               msgs::DecodeError::BadText => return,
                                                msgs::DecodeError::ExtraAddressesPerType => return,
-                                               msgs::DecodeError::WrongLength => panic!("We picked the length..."),
+                                               msgs::DecodeError::BadLengthDescriptor => return,
+                                               msgs::DecodeError::ShortRead => panic!("We picked the length..."),
                                        }
                                }
                        }
@@ -235,10 +239,25 @@ pub fn do_test(data: &[u8]) {
        let funding_locked = decode_msg!(msgs::FundingLocked, 32+33);
        return_err!(channel.funding_locked(&funding_locked));
 
+       macro_rules! test_err {
+               ($expr: expr) => {
+                       match $expr {
+                               Ok(r) => Some(r),
+                               Err(e) => match e.action {
+                                       None => return,
+                                       Some(ErrorAction::UpdateFailHTLC {..}) => None,
+                                       Some(ErrorAction::DisconnectPeer {..}) => return,
+                                       Some(ErrorAction::IgnoreError) => None,
+                                       Some(ErrorAction::SendErrorMessage {..}) => None,
+                               },
+                       }
+               }
+       }
+
        loop {
                match get_slice!(1)[0] {
                        0 => {
-                               return_err!(channel.send_htlc(slice_to_be64(get_slice!(8)), [42; 32], slice_to_be32(get_slice!(4)), msgs::OnionPacket {
+                               test_err!(channel.send_htlc(slice_to_be64(get_slice!(8)), [42; 32], slice_to_be32(get_slice!(4)), msgs::OnionPacket {
                                        version: get_slice!(1)[0],
                                        public_key: get_pubkey!(),
                                        hop_data: [0; 20*65],
@@ -246,44 +265,45 @@ pub fn do_test(data: &[u8]) {
                                }));
                        },
                        1 => {
-                               return_err!(channel.send_commitment());
+                               test_err!(channel.send_commitment());
                        },
                        2 => {
                                let update_add_htlc = decode_msg!(msgs::UpdateAddHTLC, 32+8+8+32+4+4+33+20*65+32);
-                               return_err!(channel.update_add_htlc(&update_add_htlc, PendingForwardHTLCInfo::dummy()));
+                               test_err!(channel.update_add_htlc(&update_add_htlc, PendingForwardHTLCInfo::dummy()));
                        },
                        3 => {
                                let update_fulfill_htlc = decode_msg!(msgs::UpdateFulfillHTLC, 32 + 8 + 32);
-                               return_err!(channel.update_fulfill_htlc(&update_fulfill_htlc));
+                               test_err!(channel.update_fulfill_htlc(&update_fulfill_htlc));
                        },
                        4 => {
                                let update_fail_htlc = decode_msg_with_len16!(msgs::UpdateFailHTLC, 32 + 8, 1);
-                               return_err!(channel.update_fail_htlc(&update_fail_htlc, HTLCFailReason::dummy()));
+                               test_err!(channel.update_fail_htlc(&update_fail_htlc, HTLCFailReason::dummy()));
                        },
                        5 => {
                                let update_fail_malformed_htlc = decode_msg!(msgs::UpdateFailMalformedHTLC, 32+8+32+2);
-                               return_err!(channel.update_fail_malformed_htlc(&update_fail_malformed_htlc, HTLCFailReason::dummy()));
+                               test_err!(channel.update_fail_malformed_htlc(&update_fail_malformed_htlc, HTLCFailReason::dummy()));
                        },
                        6 => {
                                let commitment_signed = decode_msg_with_len16!(msgs::CommitmentSigned, 32+64, 64);
-                               return_err!(channel.commitment_signed(&commitment_signed));
+                               test_err!(channel.commitment_signed(&commitment_signed));
                        },
                        7 => {
                                let revoke_and_ack = decode_msg!(msgs::RevokeAndACK, 32+32+33);
-                               return_err!(channel.revoke_and_ack(&revoke_and_ack));
+                               test_err!(channel.revoke_and_ack(&revoke_and_ack));
                        },
                        8 => {
                                let update_fee = decode_msg!(msgs::UpdateFee, 32+4);
-                               return_err!(channel.update_fee(&fee_est, &update_fee));
+                               test_err!(channel.update_fee(&fee_est, &update_fee));
                        },
                        9 => {
                                let shutdown = decode_msg_with_len16!(msgs::Shutdown, 32, 1);
-                               return_err!(channel.shutdown(&fee_est, &shutdown));
+                               test_err!(channel.shutdown(&fee_est, &shutdown));
                                if channel.is_shutdown() { return; }
                        },
                        10 => {
                                let closing_signed = decode_msg!(msgs::ClosingSigned, 32+8+64);
-                               if return_err!(channel.closing_signed(&fee_est, &closing_signed)).1.is_some() {
+                               let sign_res = test_err!(channel.closing_signed(&fee_est, &closing_signed));
+                               if sign_res.is_some() && sign_res.unwrap().1.is_some() {
                                        assert!(channel.is_shutdown());
                                        return;
                                }
index 79bc8581c390a4c4cd9c27d703283fa6d00834f2..6fdac8ad24e080034613b3440cba556db3e5b691 100644 (file)
@@ -9,7 +9,6 @@ use bitcoin::blockdata::script::Script;
 use bitcoin::network::constants::Network;
 use bitcoin::network::serialize::{serialize, BitcoinHash};
 use bitcoin::util::hash::Sha256dHash;
-use bitcoin::util::uint::Uint256;
 
 use crypto::sha2::Sha256;
 use crypto::digest::Digest;
@@ -26,7 +25,9 @@ use lightning::util::reset_rng_state;
 use secp256k1::key::{PublicKey,SecretKey};
 use secp256k1::Secp256k1;
 
+use std::cell::RefCell;
 use std::collections::HashMap;
+use std::hash::Hash;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize,Ordering};
 
@@ -83,10 +84,10 @@ struct FuzzEstimator {
        input: Arc<InputData>,
 }
 impl FeeEstimator for FuzzEstimator {
-       fn get_est_sat_per_vbyte(&self, _: ConfirmationTarget) -> u64 {
+       fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
                //TODO: We should actually be testing at least much more than 64k...
                match self.input.get_slice(2) {
-                       Some(slice) => slice_to_be16(slice) as u64,
+                       Some(slice) => slice_to_be16(slice) as u64 * 250,
                        None => 0
                }
        }
@@ -105,15 +106,31 @@ impl BroadcasterInterface for TestBroadcaster {
        fn broadcast_transaction(&self, _tx: &Transaction) {}
 }
 
-#[derive(Clone, PartialEq, Eq, Hash)]
-struct Peer {
+#[derive(Clone)]
+struct Peer<'a> {
        id: u8,
+       peers_connected: &'a RefCell<[bool; 256]>,
 }
-impl SocketDescriptor for Peer {
+impl<'a> SocketDescriptor for Peer<'a> {
        fn send_data(&mut self, data: &Vec<u8>, write_offset: usize, _resume_read: bool) -> usize {
                assert!(write_offset < data.len());
                data.len() - write_offset
        }
+       fn disconnect_socket(&mut self) {
+               assert!(self.peers_connected.borrow()[self.id as usize]);
+               self.peers_connected.borrow_mut()[self.id as usize] = false;
+       }
+}
+impl<'a> PartialEq for Peer<'a> {
+       fn eq(&self, other: &Self) -> bool {
+               self.id == other.id
+       }
+}
+impl<'a> Eq for Peer<'a> {}
+impl<'a> Hash for Peer<'a> {
+       fn hash<H : std::hash::Hasher>(&self, h: &mut H) {
+               self.id.hash(h)
+       }
 }
 
 #[inline]
@@ -159,16 +176,16 @@ pub fn do_test(data: &[u8]) {
        let channelmanager = ChannelManager::new(our_network_key, slice_to_be32(get_slice!(4)), get_slice!(1)[0] != 0, Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone()).unwrap();
        let router = Arc::new(Router::new(PublicKey::from_secret_key(&secp_ctx, &our_network_key).unwrap()));
 
+       let peers = RefCell::new([false; 256]);
        let handler = PeerManager::new(MessageHandler {
                chan_handler: channelmanager.clone(),
                route_handler: router.clone(),
        }, our_network_key);
 
-       let mut peers = [false; 256];
        let mut should_forward = false;
        let mut payments_received = Vec::new();
        let mut payments_sent = 0;
-       let mut pending_funding_generation: Vec<(Uint256, u64, Script)> = Vec::new();
+       let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new();
        let mut pending_funding_signatures = HashMap::new();
        let mut pending_funding_relay = Vec::new();
 
@@ -177,44 +194,44 @@ pub fn do_test(data: &[u8]) {
                        0 => {
                                let mut new_id = 0;
                                for i in 1..256 {
-                                       if !peers[i-1] {
+                                       if !peers.borrow()[i-1] {
                                                new_id = i;
                                                break;
                                        }
                                }
                                if new_id == 0 { return; }
-                               peers[new_id - 1] = true;
-                               handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8}).unwrap();
+                               peers.borrow_mut()[new_id - 1] = true;
+                               handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
                        },
                        1 => {
                                let mut new_id = 0;
                                for i in 1..256 {
-                                       if !peers[i-1] {
+                                       if !peers.borrow()[i-1] {
                                                new_id = i;
                                                break;
                                        }
                                }
                                if new_id == 0 { return; }
-                               peers[new_id - 1] = true;
-                               handler.new_inbound_connection(Peer{id: (new_id - 1) as u8}).unwrap();
+                               peers.borrow_mut()[new_id - 1] = true;
+                               handler.new_inbound_connection(Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
                        },
                        2 => {
                                let peer_id = get_slice!(1)[0];
-                               if !peers[peer_id as usize] { return; }
-                               peers[peer_id as usize] = false;
-                               handler.disconnect_event(&Peer{id: peer_id});
+                               if !peers.borrow()[peer_id as usize] { return; }
+                               peers.borrow_mut()[peer_id as usize] = false;
+                               handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
                        },
                        3 => {
                                let peer_id = get_slice!(1)[0];
-                               if !peers[peer_id as usize] { return; }
-                               match handler.read_event(&mut Peer{id: peer_id}, get_slice!(get_slice!(1)[0]).to_vec()) {
+                               if !peers.borrow()[peer_id as usize] { return; }
+                               match handler.read_event(&mut Peer{id: peer_id, peers_connected: &peers}, get_slice!(get_slice!(1)[0]).to_vec()) {
                                        Ok(res) => assert!(!res),
-                                       Err(_) => { peers[peer_id as usize] = false; }
+                                       Err(_) => { peers.borrow_mut()[peer_id as usize] = false; }
                                }
                        },
                        4 => {
                                let value = slice_to_be24(get_slice!(3)) as u64;
-                               let route = match router.get_route(&get_pubkey!(), &Vec::new(), value, 42) {
+                               let route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) {
                                        Ok(route) => route,
                                        Err(_) => return,
                                };
@@ -232,7 +249,7 @@ pub fn do_test(data: &[u8]) {
                        },
                        5 => {
                                let peer_id = get_slice!(1)[0];
-                               if !peers[peer_id as usize] { return; }
+                               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; }
@@ -246,7 +263,7 @@ pub fn do_test(data: &[u8]) {
                        },
                        7 => {
                                if should_forward {
-                                       channelmanager.process_pending_htlc_forward();
+                                       channelmanager.process_pending_htlc_forwards();
                                        handler.process_events();
                                        should_forward = false;
                                }
index 8e9ed04dac1450769265d89c2ee9abe9107a04e6..37eac67a720e8304c0db54859ccd49651807a292 100755 (executable)
@@ -1,5 +1,5 @@
-for target in CommitmentSigned FundingCreated FundingLocked FundingSigned OpenChannel RevokeAndACK Shutdown UpdateAddHTLC UpdateFailHTLC UpdateFailMalformedHTLC UpdateFee UpdateFulfillHTLC AcceptChannel ClosingSigned; do
-       tn=$(echo $target | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\L\2/g')
+for target in CommitmentSigned FundingCreated FundingLocked FundingSigned OpenChannel RevokeAndACK Shutdown UpdateAddHTLC UpdateFailHTLC UpdateFailMalformedHTLC UpdateFee UpdateFulfillHTLC AcceptChannel ClosingSigned ChannelReestablish ErrorMessage; do
+       tn=$(echo $target | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g')
        fn=msg_$(echo $tn | tr '[:upper:]' '[:lower:]')_target.rs
        cat msg_target_template.txt | sed s/MSG_TARGET/$target/ > $fn
 done
diff --git a/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs b/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs
new file mode 100644 (file)
index 0000000..dc9c2ac
--- /dev/null
@@ -0,0 +1,48 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+use lightning::util::reset_rng_state;
+
+use lightning::ln::msgs::{MsgEncodable, MsgDecodable};
+
+mod utils;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       reset_rng_state();
+       test_msg!(msgs::ChannelReestablish, data);
+}
+
+#[cfg(feature = "afl")]
+extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       afl::read_stdio_bytes(|data| {
+               do_test(&data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       use utils::extend_vec_from_hex;
+       #[test]
+       fn duplicate_crash() {
+               let mut a = Vec::new();
+               extend_vec_from_hex("00", &mut a);
+               super::do_test(&a);
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs b/fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs
new file mode 100644 (file)
index 0000000..7022786
--- /dev/null
@@ -0,0 +1,48 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+use lightning::util::reset_rng_state;
+
+use lightning::ln::msgs::{MsgEncodable, MsgDecodable};
+
+mod utils;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       reset_rng_state();
+       test_msg!(msgs::ErrorMessage, data);
+}
+
+#[cfg(feature = "afl")]
+extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       afl::read_stdio_bytes(|data| {
+               do_test(&data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       use utils::extend_vec_from_hex;
+       #[test]
+       fn duplicate_crash() {
+               let mut a = Vec::new();
+               extend_vec_from_hex("00", &mut a);
+               super::do_test(&a);
+       }
+}
diff --git a/fuzz/fuzz_targets/router_target.rs b/fuzz/fuzz_targets/router_target.rs
new file mode 100644 (file)
index 0000000..13733ad
--- /dev/null
@@ -0,0 +1,219 @@
+extern crate bitcoin;
+extern crate lightning;
+extern crate secp256k1;
+
+use lightning::ln::channelmanager::ChannelDetails;
+use lightning::ln::msgs;
+use lightning::ln::msgs::{MsgDecodable, RoutingMessageHandler};
+use lightning::ln::router::{Router, RouteHint};
+use lightning::util::reset_rng_state;
+
+use secp256k1::key::PublicKey;
+use secp256k1::Secp256k1;
+
+#[inline]
+pub fn slice_to_be16(v: &[u8]) -> u16 {
+       ((v[0] as u16) << 8*1) |
+       ((v[1] as u16) << 8*0)
+}
+
+#[inline]
+pub fn slice_to_be32(v: &[u8]) -> u32 {
+       ((v[0] as u32) << 8*3) |
+       ((v[1] as u32) << 8*2) |
+       ((v[2] as u32) << 8*1) |
+       ((v[3] as u32) << 8*0)
+}
+
+#[inline]
+pub fn slice_to_be64(v: &[u8]) -> u64 {
+       ((v[0] as u64) << 8*7) |
+       ((v[1] as u64) << 8*6) |
+       ((v[2] as u64) << 8*5) |
+       ((v[3] as u64) << 8*4) |
+       ((v[4] as u64) << 8*3) |
+       ((v[5] as u64) << 8*2) |
+       ((v[6] as u64) << 8*1) |
+       ((v[7] as u64) << 8*0)
+}
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       reset_rng_state();
+
+       let mut read_pos = 0;
+       macro_rules! get_slice_nonadvancing {
+               ($len: expr) => {
+                       {
+                               if data.len() < read_pos + $len as usize {
+                                       return;
+                               }
+                               &data[read_pos..read_pos + $len as usize]
+                       }
+               }
+       }
+       macro_rules! get_slice {
+               ($len: expr) => {
+                       {
+                               let res = get_slice_nonadvancing!($len);
+                               read_pos += $len;
+                               res
+                       }
+               }
+       }
+
+       macro_rules! decode_msg {
+               ($MsgType: path, $len: expr) => {
+                       match <($MsgType)>::decode(get_slice!($len)) {
+                               Ok(msg) => msg,
+                               Err(e) => match e {
+                                       msgs::DecodeError::UnknownRealmByte => return,
+                                       msgs::DecodeError::BadPublicKey => return,
+                                       msgs::DecodeError::BadSignature => return,
+                                       msgs::DecodeError::BadText => return,
+                                       msgs::DecodeError::ExtraAddressesPerType => return,
+                                       msgs::DecodeError::BadLengthDescriptor => return,
+                                       msgs::DecodeError::ShortRead => panic!("We picked the length..."),
+                               }
+                       }
+               }
+       }
+
+       macro_rules! decode_msg_with_len16 {
+               ($MsgType: path, $begin_len: expr, $excess: expr) => {
+                       {
+                               let extra_len = slice_to_be16(&get_slice_nonadvancing!($begin_len as usize + 2)[$begin_len..$begin_len + 2]);
+                               decode_msg!($MsgType, $begin_len as usize + 2 + (extra_len as usize) + $excess)
+                       }
+               }
+       }
+
+       let secp_ctx = Secp256k1::new();
+       macro_rules! get_pubkey {
+               () => {
+                       match PublicKey::from_slice(&secp_ctx, get_slice!(33)) {
+                               Ok(key) => key,
+                               Err(_) => return,
+                       }
+               }
+       }
+
+       let our_pubkey = get_pubkey!();
+       let router = Router::new(our_pubkey.clone());
+
+       loop {
+               match get_slice!(1)[0] {
+                       0 => {
+                               let start_len = slice_to_be16(&get_slice_nonadvancing!(64 + 2)[64..64 + 2]) as usize;
+                               let addr_len = slice_to_be16(&get_slice_nonadvancing!(64+start_len+2 + 74)[64+start_len+2 + 72..64+start_len+2 + 74]);
+                               if addr_len > (37+1)*4 {
+                                       return;
+                               }
+                               let _ = router.handle_node_announcement(&decode_msg_with_len16!(msgs::NodeAnnouncement, 64, 288));
+                       },
+                       1 => {
+                               let _ = router.handle_channel_announcement(&decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4));
+                       },
+                       2 => {
+                               let _ = router.handle_channel_update(&decode_msg!(msgs::ChannelUpdate, 128));
+                       },
+                       3 => {
+                               match get_slice!(1)[0] {
+                                       0 => {
+                                               router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {msg: decode_msg!(msgs::ChannelUpdate, 128)});
+                                       },
+                                       1 => {
+                                               let short_channel_id = slice_to_be64(get_slice!(8));
+                                               router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed {short_channel_id});
+                                       },
+                                       _ => return,
+                               }
+                       },
+                       4 => {
+                               let target = get_pubkey!();
+                               let mut first_hops_vec = Vec::new();
+                               let first_hops = match get_slice!(1)[0] {
+                                       0 => None,
+                                       1 => {
+                                               let count = slice_to_be16(get_slice!(2));
+                                               for _ in 0..count {
+                                                       first_hops_vec.push(ChannelDetails {
+                                                               channel_id: [0; 32],
+                                                               short_channel_id: Some(slice_to_be64(get_slice!(8))),
+                                                               remote_network_id: get_pubkey!(),
+                                                               channel_value_satoshis: slice_to_be64(get_slice!(8)),
+                                                               user_id: 0,
+                                                       });
+                                               }
+                                               Some(&first_hops_vec[..])
+                                       },
+                                       _ => return,
+                               };
+                               let mut last_hops_vec = Vec::new();
+                               let last_hops = {
+                                       let count = slice_to_be16(get_slice!(2));
+                                       for _ in 0..count {
+                                               last_hops_vec.push(RouteHint {
+                                                       src_node_id: get_pubkey!(),
+                                                       short_channel_id: slice_to_be64(get_slice!(8)),
+                                                       fee_base_msat: slice_to_be64(get_slice!(8)),
+                                                       fee_proportional_millionths: slice_to_be32(get_slice!(4)),
+                                                       cltv_expiry_delta: slice_to_be16(get_slice!(2)),
+                                                       htlc_minimum_msat: slice_to_be64(get_slice!(8)),
+                                               });
+                                       }
+                                       &last_hops_vec[..]
+                               };
+                               let _ = router.get_route(&target, first_hops, last_hops, slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4)));
+                       },
+                       _ => return,
+               }
+       }
+}
+
+#[cfg(feature = "afl")]
+extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       afl::read_stdio_bytes(|data| {
+               do_test(&data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       fn extend_vec_from_hex(hex: &str, out: &mut Vec<u8>) {
+               let mut b = 0;
+               for (idx, c) in hex.as_bytes().iter().enumerate() {
+                       b <<= 4;
+                       match *c {
+                               b'A'...b'F' => b |= c - b'A' + 10,
+                               b'a'...b'f' => b |= c - b'a' + 10,
+                               b'0'...b'9' => b |= c - b'0',
+                               _ => panic!("Bad hex"),
+                       }
+                       if (idx & 1) == 1 {
+                               out.push(b);
+                               b = 0;
+                       }
+               }
+       }
+
+       #[test]
+       fn duplicate_crash() {
+               let mut a = Vec::new();
+               extend_vec_from_hex("00", &mut a);
+               super::do_test(&a);
+       }
+}
index f99f581f133a4fea18642c152444418d250a25f1..7e9e9aeff05b902923703846337cc5c9b9666edd 100644 (file)
@@ -12,7 +12,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
 /// events).
 pub trait ChainWatchInterface: Sync + Send {
        /// Provides a scriptPubKey which much be watched for.
-       fn install_watch_script(&self, script_pub_key: Script);
+       fn install_watch_script(&self, script_pub_key: &Script);
 
        /// Provides an outpoint which must be watched for, providing any transactions which spend the
        /// given outpoint.
@@ -57,7 +57,12 @@ pub enum ConfirmationTarget {
 /// called from inside the library in response to ChainListener events, P2P events, or timer
 /// events).
 pub trait FeeEstimator: Sync + Send {
-       fn get_est_sat_per_vbyte(&self, confirmation_target: ConfirmationTarget) -> u64;
+       /// Gets estimated satoshis of fee required per 1000 Weight-Units. This translates to:
+       ///  * satoshis-per-byte * 250
+       ///  * ceil(satoshis-per-kbyte / 4)
+       /// Must be no smaller than 253 (ie 1 satoshi-per-byte rounded up to ensure later round-downs
+       /// don't put us below 1 satoshi-per-byte).
+       fn get_est_sat_per_1000_weight(&self, confirmation_target: ConfirmationTarget) -> u64;
 }
 
 /// Utility to capture some common parts of ChainWatchInterface implementors.
@@ -70,9 +75,9 @@ pub struct ChainWatchInterfaceUtil {
 
 /// Register listener
 impl ChainWatchInterface for ChainWatchInterfaceUtil {
-       fn install_watch_script(&self, script_pub_key: Script) {
+       fn install_watch_script(&self, script_pub_key: &Script) {
                let mut watched = self.watched.lock().unwrap();
-               watched.0.push(Script::from(script_pub_key));
+               watched.0.push(script_pub_key.clone());
                self.reentered.fetch_add(1, Ordering::Relaxed);
        }
 
@@ -103,7 +108,7 @@ impl ChainWatchInterfaceUtil {
                }
        }
 
-       /// Notify listeners that a block was connected.
+       /// Notify listeners that a block was connected given a full, unfiltered block.
        /// Handles re-scanning the block and calling block_connected again if listeners register new
        /// watch data during the callbacks for you (see ChainListener::block_connected for more info).
        pub fn block_connected_with_filtering(&self, block: &Block, height: u32) {
@@ -135,7 +140,8 @@ impl ChainWatchInterfaceUtil {
                }
        }
 
-       /// Notify listeners that a block was connected.
+       /// Notify listeners that a block was connected, given pre-filtered list of transactions in the
+       /// block which matched the filter (probably using does_match_tx).
        /// Returns true if notified listeners registered additional watch data (implying that the
        /// block must be re-scanned and this function called again prior to further block_connected
        /// calls, see ChainListener::block_connected for more info).
index 42a4f952e4150550f240c9c59d5d89a9a885c7de..934c772727862c2ebca1b1e73521cdd4fdfadb4b 100644 (file)
@@ -1,5 +1,4 @@
 use bitcoin::util::hash::Sha256dHash;
-use bitcoin::util::uint::Uint256;
 
 /// A reference to a transaction output.
 /// Differs from bitcoin::blockdata::transaction::TxOutRef as the index is a u16 instead of usize
@@ -19,10 +18,33 @@ impl OutPoint {
        }
 
        /// Convert an `OutPoint` to a lightning channel id.
-       pub fn to_channel_id(&self) -> Uint256 {
-               let mut index = [0; 32];
-               index[30] = ((self.index >> 8) & 0xff) as u8;
-               index[31] = ((self.index >> 0) & 0xff) as u8;
-               self.txid.into_le() ^ Sha256dHash::from(&index[..]).into_le()
+       pub fn to_channel_id(&self) -> [u8; 32] {
+               let mut res = [0; 32];
+               res[..].copy_from_slice(&self.txid[..]);
+               res[30] ^= ((self.index >> 8) & 0xff) as u8;
+               res[31] ^= ((self.index >> 0) & 0xff) as u8;
+               res
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       use chain::transaction::OutPoint;
+
+       use bitcoin::blockdata::transaction::Transaction;
+       use bitcoin::network::serialize;
+       use bitcoin::util::misc::hex_bytes;
+
+       #[test]
+       fn test_channel_id_calculation() {
+               let tx: Transaction = serialize::deserialize(&hex_bytes("020000000001010e0adef48412e4361325ac1c6e36411299ab09d4f083b9d8ddb55fbc06e1b0c00000000000feffffff0220a1070000000000220020f81d95e040bd0a493e38bae27bff52fe2bb58b93b293eb579c01c31b05c5af1dc072cfee54a3000016001434b1d6211af5551905dc2642d05f5b04d25a8fe80247304402207f570e3f0de50546aad25a872e3df059d277e776dda4269fa0d2cc8c2ee6ec9a022054e7fae5ca94d47534c86705857c24ceea3ad51c69dd6051c5850304880fc43a012103cb11a1bacc223d98d91f1946c6752e358a5eb1a1c983b3e6fb15378f453b76bd00000000").unwrap()[..]).unwrap();
+               assert_eq!(&OutPoint {
+                       txid: tx.txid(),
+                       index: 0
+               }.to_channel_id(), &hex_bytes("3e88dd7165faf7be58b3c5bb2c9c452aebef682807ea57080f62e6f6e113c25e").unwrap()[..]);
+               assert_eq!(&OutPoint {
+                       txid: tx.txid(),
+                       index: 1
+               }.to_channel_id(), &hex_bytes("3e88dd7165faf7be58b3c5bb2c9c452aebef682807ea57080f62e6f6e113c25f").unwrap()[..]);
        }
 }
index ded81f60c200f23506f3d0df3e48b32233f2aeca..eb5ae008dcda8c411524c97b92bbfb53183692cd 100644 (file)
@@ -2,7 +2,6 @@ use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::script::{Script,Builder};
 use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType};
 use bitcoin::blockdata::opcodes;
-use bitcoin::util::uint::Uint256;
 use bitcoin::util::hash::{Sha256dHash, Hash160};
 use bitcoin::util::bip143;
 use bitcoin::network::serialize::BitcoinHash;
@@ -231,12 +230,12 @@ const BOTH_SIDES_SHUTDOWN_MASK: u32 = (ChannelState::LocalShutdownSent as u32 |
 
 // 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 get_channel_id() before we're set up or things like get_outbound_funding_signed on an
+// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
 // inbound channel.
 pub struct Channel {
        user_id: u64,
 
-       channel_id: Uint256,
+       channel_id: [u8; 32],
        channel_state: u32,
        channel_outbound: bool,
        secp_ctx: Secp256k1,
@@ -329,7 +328,7 @@ macro_rules! secp_call {
                match $res {
                        Ok(key) => key,
                        //TODO: make the error a parameter
-                       Err(_) => return Err(HandleError{err: $err, msg: Some(msgs::ErrorAction::DisconnectPeer{})})
+                       Err(_) => return Err(HandleError{err: $err, action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })})
                }
        };
 }
@@ -351,7 +350,7 @@ impl Channel {
        }
 
        fn derive_our_dust_limit_satoshis(at_open_background_feerate: u64) -> u64 {
-               at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT //TODO
+               at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000 //TODO
        }
 
        fn derive_our_htlc_minimum_msat(_at_open_channel_feerate_per_kw: u64) -> u64 {
@@ -366,8 +365,8 @@ impl Channel {
                        panic!("funding value > 2^24");
                }
 
-               let feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Normal);
-               let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
+               let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
+               let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
 
                let secp_ctx = Secp256k1::new();
                let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
@@ -380,7 +379,7 @@ impl Channel {
                Channel {
                        user_id: user_id,
 
-                       channel_id: rng::rand_uint256(),
+                       channel_id: rng::rand_u832(),
                        channel_state: ChannelState::OurInitSent as u32,
                        channel_outbound: true,
                        secp_ctx: secp_ctx,
@@ -406,13 +405,13 @@ impl Channel {
                        last_block_connected: Default::default(),
                        funding_tx_confirmations: 0,
 
-                       feerate_per_kw: feerate * 250,
+                       feerate_per_kw: feerate,
                        their_dust_limit_satoshis: 0,
                        our_dust_limit_satoshis: Channel::derive_our_dust_limit_satoshis(background_feerate),
                        their_max_htlc_value_in_flight_msat: 0,
                        their_channel_reserve_satoshis: 0,
                        their_htlc_minimum_msat: 0,
-                       our_htlc_minimum_msat: Channel::derive_our_htlc_minimum_msat(feerate * 250),
+                       our_htlc_minimum_msat: Channel::derive_our_htlc_minimum_msat(feerate),
                        their_to_self_delay: 0,
                        their_max_accepted_htlcs: 0,
 
@@ -433,11 +432,11 @@ impl Channel {
        }
 
        fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), HandleError> {
-               if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background) * 250 {
-                       return Err(HandleError{err: "Peer's feerate much too low", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+               if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) {
+                       return Err(HandleError{err: "Peer's feerate much too low", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
-               if (feerate_per_kw as u64) > fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::HighPriority) * 375 { // 375 = 250 * 1.5x
-                       return Err(HandleError{err: "Peer's feerate much too high", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+               if (feerate_per_kw as u64) > fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * 2 {
+                       return Err(HandleError{err: "Peer's feerate much too high", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                Ok(())
        }
@@ -449,36 +448,36 @@ impl Channel {
        pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> {
                // Check sanity of message fields:
                if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
-                       return Err(HandleError{err: "funding value > 2^24", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "funding value > 2^24", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                if msg.channel_reserve_satoshis > msg.funding_satoshis {
-                       return Err(HandleError{err: "Bogus channel_reserve_satoshis", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "Bogus channel_reserve_satoshis", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                if msg.push_msat > (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
-                       return Err(HandleError{err: "push_msat more than highest possible value", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "push_msat more than highest possible value", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                if msg.dust_limit_satoshis > msg.funding_satoshis {
-                       return Err(HandleError{err: "Peer never wants payout outputs?", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "Peer never wants payout outputs?", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                if msg.htlc_minimum_msat >= (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
-                       return Err(HandleError{err: "Minimum htlc value is full channel value", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "Minimum htlc value is full channel value", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
                if msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT {
-                       return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                if msg.max_accepted_htlcs < 1 {
-                       return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                if (msg.channel_flags & 254) != 0 {
-                       return Err(HandleError{err: "unknown channel_flags", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "unknown channel_flags", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
 
                // Convert things into internal flags and prep our state:
 
                let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false };
 
-               let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
+               let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
 
                let secp_ctx = Secp256k1::new();
                let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
@@ -661,8 +660,13 @@ impl Channel {
                                                        value_to_self_msat_offset -= htlc.amount_msat as i64;
                                                }
                                        },
+                                       HTLCState::RemoteRemoved => {
+                                               if !generated_by_local && htlc.fail_reason.is_none() {
+                                                       value_to_self_msat_offset -= htlc.amount_msat as i64;
+                                               }
+                                       },
                                        HTLCState::LocalRemoved => {
-                                               if !generated_by_local && htlc.local_removed_fulfilled {
+                                               if generated_by_local && htlc.local_removed_fulfilled {
                                                        value_to_self_msat_offset += htlc.amount_msat as i64;
                                                }
                                        },
@@ -943,7 +947,7 @@ impl Channel {
                                        },
                                        &HTLCUpdateAwaitingACK::FailHTLC { ref payment_hash, .. } => {
                                                if payment_hash_calc == *payment_hash {
-                                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
+                                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
                                                }
                                        },
                                        _ => {}
@@ -970,14 +974,14 @@ impl Channel {
                                } else if htlc.state == HTLCState::RemoteAnnounced {
                                        panic!("Somehow forwarded HTLC prior to remote revocation!");
                                } else if htlc.state == HTLCState::LocalRemoved || htlc.state == HTLCState::LocalRemovedAwaitingCommitment {
-                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
+                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
                                } else {
                                        panic!("Have an inbound HTLC when not awaiting remote revoke that had a garbage state");
                                }
                        }
                }
                if htlc_amount_msat == 0 {
-                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
+                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
                }
                self.channel_monitor.provide_payment_preimage(&payment_hash_calc, &payment_preimage_arg);
 
@@ -1000,7 +1004,7 @@ impl Channel {
 
        pub fn get_update_fail_htlc(&mut self, payment_hash_arg: &[u8; 32], err_packet: msgs::OnionErrorPacket) -> Result<Option<msgs::UpdateFailHTLC>, HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Was asked to fail an HTLC when channel was not in an operational state", msg: None});
+                       return Err(HandleError{err: "Was asked to fail an HTLC when channel was not in an operational state", action: None});
                }
                assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
 
@@ -1010,7 +1014,7 @@ impl Channel {
                                match pending_update {
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_hash, .. } => {
                                                if *payment_hash_arg == *payment_hash {
-                                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
+                                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
                                                }
                                        },
                                        &HTLCUpdateAwaitingACK::FailHTLC { ref payment_hash, .. } => {
@@ -1042,14 +1046,14 @@ impl Channel {
                                } else if htlc.state == HTLCState::RemoteAnnounced {
                                        panic!("Somehow forwarded HTLC prior to remote revocation!");
                                } else if htlc.state == HTLCState::LocalRemoved || htlc.state == HTLCState::LocalRemovedAwaitingCommitment {
-                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
+                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
                                } else {
                                        panic!("Have an inbound HTLC when not awaiting remote revoke that had a garbage state");
                                }
                        }
                }
                if htlc_amount_msat == 0 {
-                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
+                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
                }
 
                Ok(Some(msgs::UpdateFailHTLC {
@@ -1074,26 +1078,26 @@ impl Channel {
        pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel) -> Result<(), HandleError> {
                // Check sanity of message fields:
                if !self.channel_outbound {
-                       return Err(HandleError{err: "Got an accept_channel message from an inbound peer", msg: None});
+                       return Err(HandleError{err: "Got an accept_channel message from an inbound peer", action: None});
                }
                if self.channel_state != ChannelState::OurInitSent as u32 {
-                       return Err(HandleError{err: "Got an accept_channel message at a strange time", msg: None});
+                       return Err(HandleError{err: "Got an accept_channel message at a strange time", action: None});
                }
                if msg.dust_limit_satoshis > 21000000 * 100000000 {
-                       return Err(HandleError{err: "Peer never wants payout outputs?", msg: None});
+                       return Err(HandleError{err: "Peer never wants payout outputs?", action: None});
                }
                if msg.channel_reserve_satoshis > self.channel_value_satoshis {
-                       return Err(HandleError{err: "Bogus channel_reserve_satoshis", msg: None});
+                       return Err(HandleError{err: "Bogus channel_reserve_satoshis", action: None});
                }
                if msg.htlc_minimum_msat >= (self.channel_value_satoshis - msg.channel_reserve_satoshis) * 1000 {
-                       return Err(HandleError{err: "Minimum htlc value is full channel value", msg: None});
+                       return Err(HandleError{err: "Minimum htlc value is full channel value", action: None});
                }
                //TODO do something with minimum_depth
                if msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT {
-                       return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", msg: None});
+                       return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", action: None});
                }
                if msg.max_accepted_htlcs < 1 {
-                       return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", msg: None});
+                       return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", action: None});
                }
 
                self.channel_monitor.set_their_htlc_base_key(&msg.htlc_basepoint);
@@ -1140,10 +1144,10 @@ impl Channel {
 
        pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), HandleError> {
                if self.channel_outbound {
-                       return Err(HandleError{err: "Received funding_created for an outbound channel?", msg: None});
+                       return Err(HandleError{err: "Received funding_created for an outbound channel?", action: None});
                }
                if self.channel_state != (ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32) {
-                       return Err(HandleError{err: "Received funding_created after we got the channel!", msg: None});
+                       return Err(HandleError{err: "Received funding_created after we got the channel!", action: None});
                }
                if self.channel_monitor.get_min_seen_secret() != (1 << 48) || self.cur_remote_commitment_transaction_number != (1 << 48) - 1 || self.cur_local_commitment_transaction_number != (1 << 48) - 1 {
                        panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
@@ -1179,10 +1183,10 @@ impl Channel {
        /// If this call is successful, broadcast the funding transaction (and not before!)
        pub fn funding_signed(&mut self, msg: &msgs::FundingSigned) -> Result<ChannelMonitor, HandleError> {
                if !self.channel_outbound {
-                       return Err(HandleError{err: "Received funding_signed for an inbound channel?", msg: None});
+                       return Err(HandleError{err: "Received funding_signed for an inbound channel?", action: None});
                }
                if self.channel_state != ChannelState::FundingCreated as u32 {
-                       return Err(HandleError{err: "Received funding_signed in strange state!", msg: None});
+                       return Err(HandleError{err: "Received funding_signed in strange state!", action: None});
                }
                if self.channel_monitor.get_min_seen_secret() != (1 << 48) || self.cur_remote_commitment_transaction_number != (1 << 48) - 2 || self.cur_local_commitment_transaction_number != (1 << 48) - 1 {
                        panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
@@ -1214,7 +1218,7 @@ impl Channel {
                        self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & BOTH_SIDES_SHUTDOWN_MASK);
                        self.channel_update_count += 1;
                } else {
-                       return Err(HandleError{err: "Peer sent a funding_locked at a strange time", msg: None});
+                       return Err(HandleError{err: "Peer sent a funding_locked at a strange time", action: None});
                }
 
                self.their_prev_commitment_point = Some(self.their_cur_commitment_point);
@@ -1259,35 +1263,35 @@ impl Channel {
 
        pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_state: PendingForwardHTLCInfo) -> Result<(), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", msg: None});
+                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None});
                }
                if msg.amount_msat > self.channel_value_satoshis * 1000 {
-                       return Err(HandleError{err: "Remote side tried to send more than the total value of the channel", msg: None});
+                       return Err(HandleError{err: "Remote side tried to send more than the total value of the channel", action: None});
                }
                if msg.amount_msat < self.our_htlc_minimum_msat {
-                       return Err(HandleError{err: "Remote side tried to send less than our minimum HTLC value", msg: None});
+                       return Err(HandleError{err: "Remote side tried to send less than our minimum HTLC value", action: None});
                }
 
                let (inbound_htlc_count, _, htlc_outbound_value_msat, htlc_inbound_value_msat) = self.get_pending_htlc_stats(true);
                if inbound_htlc_count + 1 > OUR_MAX_HTLCS as u32 {
-                       return Err(HandleError{err: "Remote tried to push more than our max accepted HTLCs", msg: None});
+                       return Err(HandleError{err: "Remote tried to push more than our max accepted HTLCs", action: None});
                }
                //TODO: Spec is unclear if this is per-direction or in total (I assume per direction):
                // Check our_max_htlc_value_in_flight_msat
                if htlc_inbound_value_msat + msg.amount_msat > Channel::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis) {
-                       return Err(HandleError{err: "Remote HTLC add would put them over their max HTLC value in flight", msg: None});
+                       return Err(HandleError{err: "Remote HTLC add would put them over their max HTLC value in flight", action: None});
                }
                // Check our_channel_reserve_satoshis (we're getting paid, so they have to at least meet
                // the reserve_satoshis we told them to always have as direct payment so that they lose
                // something if we punish them for broadcasting an old state).
                if htlc_inbound_value_msat + htlc_outbound_value_msat + msg.amount_msat + self.value_to_self_msat > (self.channel_value_satoshis - Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) * 1000 {
-                       return Err(HandleError{err: "Remote HTLC add would put them over their reserve value", msg: None});
+                       return Err(HandleError{err: "Remote HTLC add would put them over their reserve value", action: None});
                }
                if self.next_remote_htlc_id != msg.htlc_id {
-                       return Err(HandleError{err: "Remote skipped HTLC ID", msg: None});
+                       return Err(HandleError{err: "Remote skipped HTLC ID", action: None});
                }
                if msg.cltv_expiry >= 500000000 {
-                       return Err(HandleError{err: "Remote provided CLTV expiry in seconds instead of block height", msg: None});
+                       return Err(HandleError{err: "Remote provided CLTV expiry in seconds instead of block height", action: None});
                }
 
                //TODO: Check msg.cltv_expiry further? Do this in channel manager?
@@ -1318,28 +1322,28 @@ impl Channel {
                                        None => {},
                                        Some(payment_hash) =>
                                                if payment_hash != htlc.payment_hash {
-                                                       return Err(HandleError{err: "Remote tried to fulfill HTLC with an incorrect preimage", msg: None});
+                                                       return Err(HandleError{err: "Remote tried to fulfill HTLC with an incorrect preimage", action: None});
                                                }
                                };
                                if htlc.state == HTLCState::LocalAnnounced {
-                                       return Err(HandleError{err: "Remote tried to fulfill HTLC before it had been committed", msg: None});
+                                       return Err(HandleError{err: "Remote tried to fulfill HTLC before it had been committed", action: None});
                                } else if htlc.state == HTLCState::Committed {
                                        htlc.state = HTLCState::RemoteRemoved;
                                        htlc.fail_reason = fail_reason;
                                } else if htlc.state == HTLCState::AwaitingRemoteRevokeToRemove || htlc.state == HTLCState::AwaitingRemovedRemoteRevoke || htlc.state == HTLCState::RemoteRemoved {
-                                       return Err(HandleError{err: "Remote tried to fulfill HTLC that they'd already fulfilled", msg: None});
+                                       return Err(HandleError{err: "Remote tried to fulfill HTLC that they'd already fulfilled", action: None});
                                } else {
                                        panic!("Got a non-outbound state on an outbound HTLC");
                                }
                                return Ok(htlc.payment_hash.clone());
                        }
                }
-               Err(HandleError{err: "Remote tried to fulfill/fail an HTLC we couldn't find", msg: None})
+               Err(HandleError{err: "Remote tried to fulfill/fail an HTLC we couldn't find", action: None})
        }
 
        pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<ChannelMonitor, HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", msg: None});
+                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None});
                }
 
                let mut sha = Sha256::new();
@@ -1354,7 +1358,7 @@ impl Channel {
 
        pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<[u8; 32], HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", msg: None});
+                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None});
                }
 
                self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason))
@@ -1362,7 +1366,7 @@ impl Channel {
 
        pub fn update_fail_malformed_htlc(&mut self, msg: &msgs::UpdateFailMalformedHTLC, fail_reason: HTLCFailReason) -> Result<(), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", msg: None});
+                       return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None});
                }
 
                self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason))?;
@@ -1371,7 +1375,7 @@ impl Channel {
 
        pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option<msgs::CommitmentSigned>, ChannelMonitor), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Got commitment signed message when channel was not in an operational state", msg: None});
+                       return Err(HandleError{err: "Got commitment signed message when channel was not in an operational state", action: None});
                }
 
                let funding_script = self.get_funding_redeemscript();
@@ -1383,7 +1387,7 @@ impl Channel {
                secp_call!(self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey), "Invalid commitment tx signature from peer");
 
                if msg.htlc_signatures.len() != local_commitment_tx.1.len() {
-                       return Err(HandleError{err: "Got wrong number of HTLC signatures from remote", msg: None});
+                       return Err(HandleError{err: "Got wrong number of HTLC signatures from remote", action: None});
                }
 
                let mut new_local_commitment_txn = Vec::with_capacity(local_commitment_tx.1.len() + 1);
@@ -1527,11 +1531,11 @@ impl Channel {
        /// revoke_and_ack message.
        pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK) -> Result<(Option<msgs::CommitmentUpdate>, Vec<PendingForwardHTLCInfo>, Vec<([u8; 32], HTLCFailReason)>, ChannelMonitor), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Got revoke/ACK message when channel was not in an operational state", msg: None});
+                       return Err(HandleError{err: "Got revoke/ACK message when channel was not in an operational state", action: None});
                }
                if let Some(their_prev_commitment_point) = self.their_prev_commitment_point {
                        if PublicKey::from_secret_key(&self.secp_ctx, &secp_call!(SecretKey::from_slice(&self.secp_ctx, &msg.per_commitment_secret), "Peer provided an invalid per_commitment_secret")).unwrap() != their_prev_commitment_point {
-                               return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", msg: None});
+                               return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", action: None});
                        }
                }
                self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret, Some((self.cur_remote_commitment_transaction_number - 1, msg.next_per_commitment_point)))?;
@@ -1604,7 +1608,7 @@ impl Channel {
 
        pub fn update_fee(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::UpdateFee) -> Result<(), HandleError> {
                if self.channel_outbound {
-                       return Err(HandleError{err: "Non-funding remote tried to update channel fee", msg: None});
+                       return Err(HandleError{err: "Non-funding remote tried to update channel fee", action: None});
                }
                Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
                self.channel_update_count += 1;
@@ -1620,24 +1624,24 @@ impl Channel {
                }
                for htlc in self.pending_htlcs.iter() {
                        if htlc.state == HTLCState::RemoteAnnounced {
-                               return Err(HandleError{err: "Got shutdown with remote pending HTLCs", msg: None});
+                               return Err(HandleError{err: "Got shutdown with remote pending HTLCs", action: None});
                        }
                }
                if (self.channel_state & ChannelState::RemoteShutdownSent as u32) == ChannelState::RemoteShutdownSent as u32 {
-                       return Err(HandleError{err: "Remote peer sent duplicate shutdown message", msg: None});
+                       return Err(HandleError{err: "Remote peer sent duplicate shutdown message", action: None});
                }
                assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
 
                // BOLT 2 says we must only send a scriptpubkey of certain standard forms, which are up to
                // 34 bytes in length, so dont let the remote peer feed us some super fee-heavy script.
                if self.channel_outbound && msg.scriptpubkey.len() > 34 {
-                       return Err(HandleError{err: "Got shutdown_scriptpubkey of absurd length from remote peer", msg: None});
+                       return Err(HandleError{err: "Got shutdown_scriptpubkey of absurd length from remote peer", action: None});
                }
                //TODO: Check shutdown_scriptpubkey form as BOLT says we must? WHYYY
 
                if self.their_shutdown_scriptpubkey.is_some() {
                        if Some(&msg.scriptpubkey) != self.their_shutdown_scriptpubkey.as_ref() {
-                               return Err(HandleError{err: "Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey", msg: None});
+                               return Err(HandleError{err: "Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey", action: None});
                        }
                } else {
                        self.their_shutdown_scriptpubkey = Some(msg.scriptpubkey.clone());
@@ -1646,12 +1650,12 @@ impl Channel {
                let our_closing_script = self.get_closing_scriptpubkey();
 
                let (proposed_feerate, proposed_fee, our_sig) = if self.channel_outbound && self.pending_htlcs.is_empty() {
-                       let mut proposed_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
-                       if self.feerate_per_kw > proposed_feerate * 250 {
-                               proposed_feerate = self.feerate_per_kw / 250;
+                       let mut proposed_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
+                       if self.feerate_per_kw > proposed_feerate {
+                               proposed_feerate = self.feerate_per_kw;
                        }
                        let tx_weight = Self::get_closing_transaction_weight(&our_closing_script, &msg.scriptpubkey);
-                       let proposed_total_fee_satoshis = proposed_feerate * tx_weight / 4;
+                       let proposed_total_fee_satoshis = proposed_feerate * tx_weight / 1000;
 
                        let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(proposed_total_fee_satoshis, false);
                        let funding_redeemscript = self.get_funding_redeemscript();
@@ -1711,19 +1715,19 @@ impl Channel {
 
        pub fn closing_signed(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::ClosingSigned) -> Result<(Option<msgs::ClosingSigned>, Option<Transaction>), HandleError> {
                if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != BOTH_SIDES_SHUTDOWN_MASK {
-                       return Err(HandleError{err: "Remote end sent us a closing_signed before both sides provided a shutdown", msg: None});
+                       return Err(HandleError{err: "Remote end sent us a closing_signed before both sides provided a shutdown", action: None});
                }
                if !self.pending_htlcs.is_empty() {
-                       return Err(HandleError{err: "Remote end sent us a closing_signed while there were still pending HTLCs", msg: None});
+                       return Err(HandleError{err: "Remote end sent us a closing_signed while there were still pending HTLCs", action: None});
                }
                if msg.fee_satoshis > 21000000 * 10000000 {
-                       return Err(HandleError{err: "Remote tried to send us a closing tx with > 21 million BTC fee", msg: None});
+                       return Err(HandleError{err: "Remote tried to send us a closing tx with > 21 million BTC fee", action: None});
                }
 
                let funding_redeemscript = self.get_funding_redeemscript();
                let (mut closing_tx, used_total_fee) = self.build_closing_transaction(msg.fee_satoshis, false);
                if used_total_fee != msg.fee_satoshis {
-                       return Err(HandleError{err: "Remote sent us a closing_signed with a fee greater than the value they can claim", msg: None});
+                       return Err(HandleError{err: "Remote sent us a closing_signed with a fee greater than the value they can claim", action: None});
                }
                let mut sighash = Message::from_slice(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]).unwrap();
 
@@ -1750,7 +1754,7 @@ impl Channel {
                macro_rules! propose_new_feerate {
                        ($new_feerate: expr) => {
                                let closing_tx_max_weight = Self::get_closing_transaction_weight(&self.get_closing_scriptpubkey(), self.their_shutdown_scriptpubkey.as_ref().unwrap());
-                               let (closing_tx, used_total_fee) = self.build_closing_transaction($new_feerate * closing_tx_max_weight / 4, false);
+                               let (closing_tx, used_total_fee) = self.build_closing_transaction($new_feerate * closing_tx_max_weight / 1000, false);
                                sighash = Message::from_slice(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]).unwrap();
                                let our_sig = self.secp_ctx.sign(&sighash, &self.local_keys.funding_key).unwrap();
                                self.last_sent_closing_fee = Some(($new_feerate, used_total_fee));
@@ -1762,23 +1766,23 @@ impl Channel {
                        }
                }
 
-               let proposed_sat_per_vbyte = msg.fee_satoshis * 4 / closing_tx.get_weight();
+               let proposed_sat_per_kw = msg.fee_satoshis * 1000 / closing_tx.get_weight();
                if self.channel_outbound {
-                       let our_max_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Normal);
-                       if proposed_sat_per_vbyte > our_max_feerate {
+                       let our_max_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
+                       if proposed_sat_per_kw > our_max_feerate {
                                if let Some((last_feerate, _)) = self.last_sent_closing_fee {
                                        if our_max_feerate <= last_feerate {
-                                               return Err(HandleError{err: "Unable to come to consensus about closing feerate, remote wanted something higher than our Normal feerate", msg: None});
+                                               return Err(HandleError{err: "Unable to come to consensus about closing feerate, remote wanted something higher than our Normal feerate", action: None});
                                        }
                                }
                                propose_new_feerate!(our_max_feerate);
                        }
                } else {
-                       let our_min_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
-                       if proposed_sat_per_vbyte < our_min_feerate {
+                       let our_min_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
+                       if proposed_sat_per_kw < our_min_feerate {
                                if let Some((last_feerate, _)) = self.last_sent_closing_fee {
                                        if our_min_feerate >= last_feerate {
-                                               return Err(HandleError{err: "Unable to come to consensus about closing feerate, remote wanted something lower than our Background feerate", msg: None});
+                                               return Err(HandleError{err: "Unable to come to consensus about closing feerate, remote wanted something lower than our Background feerate", action: None});
                                        }
                                }
                                propose_new_feerate!(our_min_feerate);
@@ -1798,7 +1802,7 @@ impl Channel {
 
        // Public utilities:
 
-       pub fn channel_id(&self) -> Uint256 {
+       pub fn channel_id(&self) -> [u8; 32] {
                self.channel_id
        }
 
@@ -1843,21 +1847,25 @@ impl Channel {
                self.channel_update_count
        }
 
+       pub fn should_announce(&self) -> bool {
+               self.announce_publicly
+       }
+
        /// Gets the fee we'd want to charge for adding an HTLC output to this Channel
        pub fn get_our_fee_base_msat(&self, fee_estimator: &FeeEstimator) -> u32 {
                // For lack of a better metric, we calculate what it would cost to consolidate the new HTLC
                // output value back into a transaction with the regular channel output:
 
                // the fee cost of the HTLC-Success/HTLC-Timeout transaction:
-               let mut res = self.feerate_per_kw * cmp::max(HTLC_TIMEOUT_TX_WEIGHT, HTLC_SUCCESS_TX_WEIGHT);
+               let mut res = self.feerate_per_kw * cmp::max(HTLC_TIMEOUT_TX_WEIGHT, HTLC_SUCCESS_TX_WEIGHT) / 1000;
 
                if self.channel_outbound {
                        // + the marginal fee increase cost to us in the commitment transaction:
-                       res += self.feerate_per_kw * COMMITMENT_TX_WEIGHT_PER_HTLC;
+                       res += self.feerate_per_kw * COMMITMENT_TX_WEIGHT_PER_HTLC / 1000;
                }
 
                // + the marginal cost of an input which spends the HTLC-Success/HTLC-Timeout output:
-               res += fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Normal) * SPENDING_INPUT_FOR_A_OUTPUT_WEIGHT * 250;
+               res += fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal) * SPENDING_INPUT_FOR_A_OUTPUT_WEIGHT / 1000;
 
                res as u32
        }
@@ -1962,7 +1970,7 @@ impl Channel {
                        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", msg: None});
+                       return Err(HandleError{err: "Cannot generate an open_channel after we've moved forward", action: None});
                }
 
                if self.cur_local_commitment_transaction_number != (1 << 48) - 1 {
@@ -1980,7 +1988,7 @@ impl Channel {
                        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),
                        htlc_minimum_msat: self.our_htlc_minimum_msat,
-                       feerate_per_kw: fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background) as u32 * 250,
+                       feerate_per_kw: fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) as u32,
                        to_self_delay: BREAKDOWN_TIMEOUT,
                        max_accepted_htlcs: OUR_MAX_HTLCS,
                        funding_pubkey: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.funding_key).unwrap(),
@@ -2090,10 +2098,10 @@ impl Channel {
        /// message can mark the channel disabled.
        pub fn get_channel_announcement(&self, our_node_id: PublicKey, chain_hash: Sha256dHash) -> Result<(msgs::UnsignedChannelAnnouncement, Signature), HandleError> {
                if !self.announce_publicly {
-                       return Err(HandleError{err: "Channel is not available for public announcements", msg: None});
+                       return Err(HandleError{err: "Channel is not available for public announcements", action: None});
                }
                if self.channel_state & (ChannelState::ChannelFunded as u32) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Cannot get a ChannelAnnouncement until the channel funding has been locked", msg: None});
+                       return Err(HandleError{err: "Cannot get a ChannelAnnouncement until the channel funding has been locked", action: None});
                }
 
                let were_node_one = our_node_id.serialize()[..] < self.their_node_id.serialize()[..];
@@ -2125,28 +2133,28 @@ impl Channel {
        /// HTLCs on the wire or we wouldn't be able to determine what they actually ACK'ed.
        pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: [u8; 32], cltv_expiry: u32, onion_routing_packet: msgs::OnionPacket) -> Result<Option<msgs::UpdateAddHTLC>, HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Cannot send HTLC until channel is fully established and we haven't started shutting down", msg: None});
+                       return Err(HandleError{err: "Cannot send HTLC until channel is fully established and we haven't started shutting down", action: None});
                }
 
                if amount_msat > self.channel_value_satoshis * 1000 {
-                       return Err(HandleError{err: "Cannot send more than the total value of the channel", msg: None});
+                       return Err(HandleError{err: "Cannot send more than the total value of the channel", action: None});
                }
                if amount_msat < self.their_htlc_minimum_msat {
-                       return Err(HandleError{err: "Cannot send less than their minimum HTLC value", msg: None});
+                       return Err(HandleError{err: "Cannot send less than their minimum HTLC value", action: None});
                }
 
                let (_, outbound_htlc_count, htlc_outbound_value_msat, htlc_inbound_value_msat) = self.get_pending_htlc_stats(false);
                if outbound_htlc_count + 1 > self.their_max_accepted_htlcs as u32 {
-                       return Err(HandleError{err: "Cannot push more than their max accepted HTLCs", msg: None});
+                       return Err(HandleError{err: "Cannot push more than their max accepted HTLCs", action: None});
                }
                //TODO: Spec is unclear if this is per-direction or in total (I assume per direction):
                // Check their_max_htlc_value_in_flight_msat
                if htlc_outbound_value_msat + amount_msat > self.their_max_htlc_value_in_flight_msat {
-                       return Err(HandleError{err: "Cannot send value that would put us over our max HTLC value in flight", msg: None});
+                       return Err(HandleError{err: "Cannot send value that would put us over our max HTLC value in flight", action: None});
                }
                // Check their_channel_reserve_satoshis:
                if htlc_inbound_value_msat + htlc_outbound_value_msat + amount_msat + (self.channel_value_satoshis * 1000 - self.value_to_self_msat) > (self.channel_value_satoshis - self.their_channel_reserve_satoshis) * 1000 {
-                       return Err(HandleError{err: "Cannot send value that would put us over our reserve value", msg: None});
+                       return Err(HandleError{err: "Cannot send value that would put us over our reserve value", action: None});
                }
 
                //TODO: Check cltv_expiry? Do this in channel manager?
@@ -2192,10 +2200,10 @@ impl Channel {
        /// Creates a signed commitment transaction to send to the remote peer.
        pub fn send_commitment(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitor), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
-                       return Err(HandleError{err: "Cannot create commitment tx until channel is fully established", msg: None});
+                       return Err(HandleError{err: "Cannot create commitment tx until channel is fully established", action: None});
                }
                if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) {
-                       return Err(HandleError{err: "Cannot create commitment tx until remote revokes their previous commitment", msg: None});
+                       return Err(HandleError{err: "Cannot create commitment tx until remote revokes their previous commitment", action: None});
                }
                let mut have_updates = false; // TODO initialize with "have we sent a fee update?"
                for htlc in self.pending_htlcs.iter() {
@@ -2205,7 +2213,7 @@ impl Channel {
                        if have_updates { break; }
                }
                if !have_updates {
-                       return Err(HandleError{err: "Cannot create commitment tx until we have some updates to send", msg: None});
+                       return Err(HandleError{err: "Cannot create commitment tx until we have some updates to send", action: None});
                }
                self.send_commitment_no_status_check()
        }
@@ -2270,11 +2278,11 @@ impl Channel {
        pub fn get_shutdown(&mut self) -> Result<(msgs::Shutdown, Vec<[u8; 32]>), HandleError> {
                for htlc in self.pending_htlcs.iter() {
                        if htlc.state == HTLCState::LocalAnnounced {
-                               return Err(HandleError{err: "Cannot begin shutdown with pending HTLCs, call send_commitment first", msg: None});
+                               return Err(HandleError{err: "Cannot begin shutdown with pending HTLCs, call send_commitment first", action: None});
                        }
                }
                if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != 0 {
-                       return Err(HandleError{err: "Shutdown already in progress", msg: None});
+                       return Err(HandleError{err: "Shutdown already in progress", action: None});
                }
                assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
 
@@ -2342,7 +2350,7 @@ mod tests {
                fee_est: u64
        }
        impl FeeEstimator for TestFeeEstimator {
-               fn get_est_sat_per_vbyte(&self, _: ConfirmationTarget) -> u64 {
+               fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
                        self.fee_est
                }
        }
@@ -2356,7 +2364,7 @@ mod tests {
        #[test]
        fn outbound_commitment_test() {
                // Test vectors from BOLT 3 Appendix C:
-               let feeest = TestFeeEstimator{fee_est: 15000/250};
+               let feeest = TestFeeEstimator{fee_est: 15000};
                let secp_ctx = Secp256k1::new();
 
                let chan_keys = ChannelKeys {
index f5af09a71a084f62568321010e52c33e20c8134a..c674c269616febc6ad97f95c301ef72462f0d126 100644 (file)
@@ -4,7 +4,6 @@ use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::network::constants::Network;
 use bitcoin::network::serialize::BitcoinHash;
 use bitcoin::util::hash::Sha256dHash;
-use bitcoin::util::uint::Uint256;
 
 use secp256k1::key::{SecretKey,PublicKey};
 use secp256k1::{Secp256k1,Message};
@@ -28,10 +27,11 @@ use crypto::digest::Digest;
 use crypto::symmetriccipher::SynchronousStreamCipher;
 use crypto::chacha20::ChaCha20;
 
-use std::sync::{Mutex,MutexGuard,Arc};
+use std::{ptr, mem};
 use std::collections::HashMap;
 use std::collections::hash_map;
-use std::{ptr, mem};
+use std::sync::{Mutex,MutexGuard,Arc};
+use std::sync::atomic::{AtomicUsize, Ordering};
 use std::time::{Instant,Duration};
 
 mod channel_held_info {
@@ -111,16 +111,16 @@ enum PendingOutboundHTLC {
 const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u32 = 50;
 
 struct ChannelHolder {
-       by_id: HashMap<Uint256, Channel>,
-       short_to_id: HashMap<u64, Uint256>,
+       by_id: HashMap<[u8; 32], Channel>,
+       short_to_id: HashMap<u64, [u8; 32]>,
        next_forward: Instant,
        /// short channel id -> forward infos. Key of 0 means payments received
        forward_htlcs: HashMap<u64, Vec<PendingForwardHTLCInfo>>,
        claimable_htlcs: HashMap<[u8; 32], PendingOutboundHTLC>,
 }
 struct MutChannelHolder<'a> {
-       by_id: &'a mut HashMap<Uint256, Channel>,
-       short_to_id: &'a mut HashMap<u64, Uint256>,
+       by_id: &'a mut HashMap<[u8; 32], Channel>,
+       short_to_id: &'a mut HashMap<u64, [u8; 32]>,
        next_forward: &'a mut Instant,
        /// short channel id -> forward infos. Key of 0 means payments received
        forward_htlcs: &'a mut HashMap<u64, Vec<PendingForwardHTLCInfo>>,
@@ -152,6 +152,7 @@ pub struct ChannelManager {
 
        announce_channels_publicly: bool,
        fee_proportional_millionths: u32,
+       latest_block_height: AtomicUsize, //TODO: Compile-time assert this is at least 32-bits long
        secp_ctx: Secp256k1,
 
        channel_state: Mutex<ChannelHolder>,
@@ -167,7 +168,7 @@ macro_rules! secp_call {
                match $res {
                        Ok(key) => key,
                        //TODO: Make the err a parameter!
-                       Err(_) => return Err(HandleError{err: "Key error", msg: None})
+                       Err(_) => return Err(HandleError{err: "Key error", action: None})
                }
        };
 }
@@ -187,7 +188,7 @@ pub struct ChannelDetails {
        /// thereafter this is the txid of the funding transaction xor the funding transaction output).
        /// Note that this means this value is *not* persistent - it can change once during the
        /// lifetime of the channel.
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        /// The position of the funding transaction in the chain. None if the funding transaction has
        /// not yet been confirmed and the channel fully opened.
        pub short_channel_id: Option<u64>,
@@ -215,6 +216,7 @@ impl ChannelManager {
 
                        announce_channels_publicly,
                        fee_proportional_millionths,
+                       latest_block_height: AtomicUsize::new(0), //TODO: Get an init value (generally need to replay recent chain on chain_monitor registration)
                        secp_ctx,
 
                        channel_state: Mutex::new(ChannelHolder{
@@ -294,11 +296,31 @@ impl ChannelManager {
                res
        }
 
+       /// Gets the list of usable channels, in random order. Useful as an argument to
+       /// Router::get_route to ensure non-announced channels are used.
+       pub fn list_usable_channels(&self) -> Vec<ChannelDetails> {
+               let channel_state = self.channel_state.lock().unwrap();
+               let mut res = Vec::with_capacity(channel_state.by_id.len());
+               for (channel_id, channel) in channel_state.by_id.iter() {
+                       if channel.is_usable() {
+                               res.push(ChannelDetails {
+                                       channel_id: (*channel_id).clone(),
+                                       short_channel_id: channel.get_short_channel_id(),
+                                       remote_network_id: channel.get_their_node_id(),
+                                       channel_value_satoshis: channel.get_value_satoshis(),
+                                       user_id: channel.get_user_id(),
+                               });
+                       }
+               }
+               res
+       }
+
        /// Begins the process of closing a channel. After this call (plus some timeout), no new HTLCs
        /// will be accepted on the given channel, and after additional timeout/the closing of all
        /// pending HTLCs, the channel will be closed on chain.
-       pub fn close_channel(&self, channel_id: &Uint256) -> Result<msgs::Shutdown, HandleError> {
-               let (res, chan_option) = {
+       /// May generate a SendShutdown event on success, which should be relayed.
+       pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), HandleError> {
+               let (res, node_id, chan_option) = {
                        let mut channel_state_lock = self.channel_state.lock().unwrap();
                        let channel_state = channel_state_lock.borrow_parts();
                        match channel_state.by_id.entry(channel_id.clone()) {
@@ -308,25 +330,34 @@ impl ChannelManager {
                                                if let Some(short_id) = chan_entry.get().get_short_channel_id() {
                                                        channel_state.short_to_id.remove(&short_id);
                                                }
-                                               (res, Some(chan_entry.remove_entry().1))
-                                       } else { (res, None) }
+                                               (res, chan_entry.get().get_their_node_id(), Some(chan_entry.remove_entry().1))
+                                       } else { (res, chan_entry.get().get_their_node_id(), None) }
                                },
-                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "No such channel", msg: None})
+                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "No such channel", action: None})
                        }
                };
                for payment_hash in res.1 {
                        // unknown_next_peer...I dunno who that is anymore....
                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() });
                }
-               if let Some(chan) = chan_option {
+               let chan_update = if let Some(chan) = chan_option {
                        if let Ok(update) = self.get_channel_update(&chan) {
-                               let mut events = self.pending_events.lock().unwrap();
-                               events.push(events::Event::BroadcastChannelUpdate {
-                                       msg: update
-                               });
-                       }
+                               Some(update)
+                       } else { None }
+               } else { None };
+
+               let mut events = self.pending_events.lock().unwrap();
+               if let Some(update) = chan_update {
+                       events.push(events::Event::BroadcastChannelUpdate {
+                               msg: update
+                       });
                }
-               Ok(res.0)
+               events.push(events::Event::SendShutdown {
+                       node_id,
+                       msg: res.0
+               });
+
+               Ok(())
        }
 
        #[inline]
@@ -418,9 +449,9 @@ impl ChannelManager {
        }
 
        /// returns the hop data, as well as the first-hop value_msat and CLTV value we should send.
-       fn build_onion_payloads(route: &Route) -> Result<(Vec<msgs::OnionHopData>, u64, u32), HandleError> {
+       fn build_onion_payloads(route: &Route, starting_htlc_offset: u32) -> Result<(Vec<msgs::OnionHopData>, u64, u32), HandleError> {
                let mut cur_value_msat = 0u64;
-               let mut cur_cltv = 0u32;
+               let mut cur_cltv = starting_htlc_offset;
                let mut last_short_channel_id = 0;
                let mut res: Vec<msgs::OnionHopData> = Vec::with_capacity(route.hops.len());
                internal_traits::test_no_dealloc::<msgs::OnionHopData>(None);
@@ -431,7 +462,7 @@ impl ChannelManager {
                        // exactly as it should be (and the next hop isn't trying to probe to find out if we're
                        // the intended recipient).
                        let value_msat = if cur_value_msat == 0 { hop.fee_msat } else { cur_value_msat };
-                       let cltv = if cur_cltv == 0 { hop.cltv_expiry_delta } else { cur_cltv };
+                       let cltv = if cur_cltv == starting_htlc_offset { hop.cltv_expiry_delta + starting_htlc_offset } else { cur_cltv };
                        res[idx] = msgs::OnionHopData {
                                realm: 0,
                                data: msgs::OnionRealm0HopData {
@@ -443,11 +474,11 @@ impl ChannelManager {
                        };
                        cur_value_msat += hop.fee_msat;
                        if cur_value_msat >= 21000000 * 100000000 * 1000 {
-                               return Err(HandleError{err: "Channel fees overflowed?!", msg: None});
+                               return Err(HandleError{err: "Channel fees overflowed?!", action: None});
                        }
                        cur_cltv += hop.cltv_expiry_delta as u32;
                        if cur_cltv >= 500000000 {
-                               return Err(HandleError{err: "Channel CLTV overflowed?!", msg: None});
+                               return Err(HandleError{err: "Channel CLTV overflowed?!", action: None});
                        }
                        last_short_channel_id = hop.short_channel_id;
                }
@@ -474,7 +505,7 @@ impl ChannelManager {
        }
 
        const ZERO:[u8; 21*65] = [0; 21*65];
-       fn construct_onion_packet(mut payloads: Vec<msgs::OnionHopData>, onion_keys: Vec<OnionKeys>, associated_data: Vec<u8>) -> Result<msgs::OnionPacket, HandleError> {
+       fn construct_onion_packet(mut payloads: Vec<msgs::OnionHopData>, onion_keys: Vec<OnionKeys>, associated_data: &[u8; 32]) -> Result<msgs::OnionPacket, HandleError> {
                let mut buf = Vec::with_capacity(21*65);
                buf.resize(21*65, 0);
 
@@ -576,7 +607,7 @@ impl ChannelManager {
        /// only fails if the channel does not yet have an assigned short_id
        fn get_channel_update(&self, chan: &Channel) -> Result<msgs::ChannelUpdate, HandleError> {
                let short_channel_id = match chan.get_short_channel_id() {
-                       None => return Err(HandleError{err: "Channel not yet established", msg: None}),
+                       None => return Err(HandleError{err: "Channel not yet established", action: None}),
                        Some(id) => id,
                };
 
@@ -609,12 +640,12 @@ impl ChannelManager {
        /// May generate a SendHTLCs event on success, which should be relayed.
        pub fn send_payment(&self, route: Route, payment_hash: [u8; 32]) -> Result<(), HandleError> {
                if route.hops.len() < 1 || route.hops.len() > 20 {
-                       return Err(HandleError{err: "Route didn't go anywhere/had bogus size", msg: None});
+                       return Err(HandleError{err: "Route didn't go anywhere/had bogus size", action: None});
                }
                let our_node_id = self.get_our_node_id();
                for (idx, hop) in route.hops.iter().enumerate() {
                        if idx != route.hops.len() - 1 && hop.pubkey == our_node_id {
-                               return Err(HandleError{err: "Route went through us but wasn't a simple rebalance loop to us", msg: None});
+                               return Err(HandleError{err: "Route went through us but wasn't a simple rebalance loop to us", action: None});
                        }
                }
 
@@ -624,22 +655,22 @@ impl ChannelManager {
                        session_key
                }));
 
-               let associated_data = Vec::new(); //TODO: What to put here?
+               let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
 
                let onion_keys = ChannelManager::construct_onion_keys(&self.secp_ctx, &route, &session_priv)?;
-               let (onion_payloads, htlc_msat, htlc_cltv) = ChannelManager::build_onion_payloads(&route)?;
-               let onion_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, associated_data)?;
+               let (onion_payloads, htlc_msat, htlc_cltv) = ChannelManager::build_onion_payloads(&route, cur_height)?;
+               let onion_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, &payment_hash)?;
 
                let (first_hop_node_id, (update_add, commitment_signed, chan_monitor)) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        let id = match channel_state.short_to_id.get(&route.hops.first().unwrap().short_channel_id) {
-                               None => return Err(HandleError{err: "No channel available with first hop!", msg: None}),
+                               None => return Err(HandleError{err: "No channel available with first hop!", action: None}),
                                Some(id) => id.clone()
                        };
                        let res = {
                                let chan = channel_state.by_id.get_mut(&id).unwrap();
                                if chan.get_their_node_id() != route.hops.first().unwrap().pubkey {
-                                       return Err(HandleError{err: "Node ID mismatch on first hop!", msg: None});
+                                       return Err(HandleError{err: "Node ID mismatch on first hop!", action: None});
                                }
                                chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, onion_packet)?
                        };
@@ -676,19 +707,33 @@ impl ChannelManager {
 
        /// Call this upon creation of a funding transaction for the given channel.
        /// Panics if a funding transaction has already been provided for this channel.
-       pub fn funding_transaction_generated(&self, temporary_channel_id: &Uint256, funding_txo: OutPoint) {
+       pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
+               macro_rules! add_pending_event {
+                       ($event: expr) => {
+                               {
+                                       let mut pending_events = self.pending_events.lock().unwrap();
+                                       pending_events.push($event);
+                               }
+                       }
+               }
+
                let (chan, msg, chan_monitor) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
-                       match channel_state.by_id.remove(&temporary_channel_id) {
+                       match channel_state.by_id.remove(temporary_channel_id) {
                                Some(mut chan) => {
                                        match chan.get_outbound_funding_created(funding_txo) {
                                                Ok(funding_msg) => {
                                                        (chan, funding_msg.0, funding_msg.1)
                                                },
-                                               Err(_e) => {
-                                                       //TODO: Push e to pendingevents
+                                               Err(e) => {
+                                                       mem::drop(channel_state);
+                                                       add_pending_event!(events::Event::DisconnectPeer {
+                                                               node_id: chan.get_their_node_id(),
+                                                               msg: if let Some(msgs::ErrorAction::DisconnectPeer { msg } ) = e.action { msg } else { None },
+                                                       });
+
                                                        return;
-                                               }
+                                               },
                                        }
                                },
                                None => return
@@ -697,20 +742,17 @@ impl ChannelManager {
                if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
                        unimplemented!(); // maybe remove from claimable_htlcs?
                }
-               {
-                       let mut pending_events = self.pending_events.lock().unwrap();
-                       pending_events.push(events::Event::SendFundingCreated {
-                               node_id: chan.get_their_node_id(),
-                               msg: msg,
-                       });
-               }
+               add_pending_event!(events::Event::SendFundingCreated {
+                       node_id: chan.get_their_node_id(),
+                       msg: msg,
+               });
 
                let mut channel_state = self.channel_state.lock().unwrap();
                channel_state.by_id.insert(chan.channel_id(), chan);
        }
 
        fn get_announcement_sigs(&self, chan: &Channel) -> Result<Option<msgs::AnnouncementSignatures>, HandleError> {
-               if !chan.is_usable() { return Ok(None) }
+               if !chan.is_usable() || !chan.should_announce() { return Ok(None) }
 
                let (announcement, our_bitcoin_sig) = chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone())?;
                let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap();
@@ -724,7 +766,10 @@ impl ChannelManager {
                }))
        }
 
-       pub fn process_pending_htlc_forward(&self) {
+       /// Processes HTLCs which are pending waiting on random forward delay.
+       /// Should only really ever be called in response to an PendingHTLCsForwardable event.
+       /// Will likely generate further events.
+       pub fn process_pending_htlc_forwards(&self) {
                let mut new_events = Vec::new();
                let mut failed_forwards = Vec::new();
                {
@@ -916,7 +961,7 @@ impl ChannelManager {
        pub fn claim_funds(&self, payment_preimage: [u8; 32]) -> bool {
                self.claim_funds_internal(payment_preimage, true)
        }
-       pub fn claim_funds_internal(&self, payment_preimage: [u8; 32], from_user: bool) -> bool {
+       fn claim_funds_internal(&self, payment_preimage: [u8; 32], from_user: bool) -> bool {
                let mut sha = Sha256::new();
                sha.input(&payment_preimage);
                let mut payment_hash = [0; 32];
@@ -1083,15 +1128,29 @@ impl ChainListener for ChannelManager {
                for funding_locked in new_events.drain(..) {
                        pending_events.push(funding_locked);
                }
+               self.latest_block_height.store(height as usize, Ordering::Release);
        }
 
+       /// We force-close the channel without letting our counterparty participate in the shutdown
        fn block_disconnected(&self, header: &BlockHeader) {
-               let mut channel_state = self.channel_state.lock().unwrap();
-               for channel in channel_state.by_id.values_mut() {
-                       if channel.block_disconnected(header) {
-                               //TODO Close channel here
+               let mut channel_lock = self.channel_state.lock().unwrap();
+               let channel_state = channel_lock.borrow_parts();
+               let short_to_id = channel_state.short_to_id;
+               channel_state.by_id.retain(|_,  v| {
+                       if v.block_disconnected(header) {
+                               let tx = v.force_shutdown();
+                               for broadcast_tx in tx {
+                                       self.tx_broadcaster.broadcast_transaction(&broadcast_tx);
+                               }
+                               if let Some(short_id) = v.get_short_channel_id() {
+                                       short_to_id.remove(&short_id);
+                               }
+                               false
+                       } else {
+                               true
                        }
-               }
+               });
+               self.latest_block_height.fetch_sub(1, Ordering::AcqRel);
        }
 }
 
@@ -1099,11 +1158,11 @@ impl ChannelMessageHandler for ChannelManager {
        //TODO: Handle errors and close channel (or so)
        fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<msgs::AcceptChannel, HandleError> {
                if msg.chain_hash != self.genesis_hash {
-                       return Err(HandleError{err: "Unknown genesis block hash", msg: None});
+                       return Err(HandleError{err: "Unknown genesis block hash", action: None});
                }
                let mut channel_state = self.channel_state.lock().unwrap();
                if channel_state.by_id.contains_key(&msg.temporary_channel_id) {
-                       return Err(HandleError{err: "temporary_channel_id collision!", msg: None});
+                       return Err(HandleError{err: "temporary_channel_id collision!", action: None});
                }
 
                let chan_keys = if cfg!(feature = "fuzztarget") {
@@ -1138,12 +1197,12 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.temporary_channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.accept_channel(&msg)?;
                                        (chan.get_value_satoshis(), chan.get_funding_redeemscript().to_v0_p2wsh(), chan.get_user_id())
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                let mut pending_events = self.pending_events.lock().unwrap();
@@ -1165,7 +1224,7 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.remove(&msg.temporary_channel_id) {
                                Some(mut chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        match chan.funding_created(msg) {
                                                Ok((funding_msg, monitor_update)) => {
@@ -1176,7 +1235,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                }
                                        }
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                }; // Release channel lock for install_watch_outpoint call,
                   // note that this means if the remote end is misbehaving and sends a message for the same
@@ -1196,12 +1255,12 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        let chan_monitor = chan.funding_signed(&msg)?;
                                        (chan.get_funding_txo().unwrap(), chan.get_user_id(), chan_monitor)
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
@@ -1220,12 +1279,12 @@ impl ChannelMessageHandler for ChannelManager {
                match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.funding_locked(&msg)?;
                                return Ok(self.get_announcement_sigs(chan)?);
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                };
        }
 
@@ -1237,7 +1296,7 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
                                        if chan_entry.get().get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        let res = chan_entry.get_mut().shutdown(&*self.fee_estimator, &msg)?;
                                        if chan_entry.get().is_shutdown() {
@@ -1247,7 +1306,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                (res, Some(chan_entry.remove_entry().1))
                                        } else { (res, None) }
                                },
-                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                for payment_hash in res.2 {
@@ -1272,7 +1331,7 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
                                        if chan_entry.get().get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        let res = chan_entry.get_mut().closing_signed(&*self.fee_estimator, &msg)?;
                                        if res.1.is_some() {
@@ -1287,7 +1346,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                (res, Some(chan_entry.remove_entry().1))
                                        } else { (res, None) }
                                },
-                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Some(broadcast_tx) = res.1 {
@@ -1317,8 +1376,6 @@ impl ChannelMessageHandler for ChannelManager {
                let shared_secret = SharedSecret::new(&self.secp_ctx, &msg.onion_routing_packet.public_key, &self.our_network_key);
                let (rho, mu) = ChannelManager::gen_rho_mu_from_shared_secret(&shared_secret);
 
-               let associated_data = Vec::new(); //TODO: What to put here?
-
                macro_rules! get_onion_hash {
                        () => {
                                {
@@ -1335,7 +1392,7 @@ impl ChannelMessageHandler for ChannelManager {
                        ($msg: expr, $err_code: expr, $data: expr) => {
                                return Err(msgs::HandleError {
                                        err: $msg,
-                                       msg: Some(msgs::ErrorAction::UpdateFailHTLC {
+                                       action: Some(msgs::ErrorAction::UpdateFailHTLC {
                                                msg: msgs::UpdateFailHTLC {
                                                        channel_id: msg.channel_id,
                                                        htlc_id: msg.htlc_id,
@@ -1358,7 +1415,7 @@ impl ChannelMessageHandler for ChannelManager {
 
                let mut hmac = Hmac::new(Sha256::new(), &mu);
                hmac.input(&msg.onion_routing_packet.hop_data);
-               hmac.input(&associated_data[..]);
+               hmac.input(&msg.payment_hash);
                if hmac.result() != MacResult::new(&msg.onion_routing_packet.hmac) {
                        return_err!("HMAC Check failed", 0x8000 | 0x4000 | 5, &get_onion_hash!());
                }
@@ -1379,6 +1436,8 @@ impl ChannelMessageHandler for ChannelManager {
                        }
                };
 
+               //TODO: Check that msg.cltv_expiry is within acceptable bounds!
+
                let mut pending_forward_info = if next_hop_data.hmac == [0; 32] {
                                // OUR PAYMENT!
                                if next_hop_data.data.amt_to_forward != msg.amount_msat {
@@ -1494,16 +1553,16 @@ impl ChannelMessageHandler for ChannelManager {
                let (source_short_channel_id, res) = match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                if !chan.is_usable() {
-                                       return Err(HandleError{err: "Channel not yet available for receiving HTLCs", msg: None});
+                                       return Err(HandleError{err: "Channel not yet available for receiving HTLCs", action: None});
                                }
                                let short_channel_id = chan.get_short_channel_id().unwrap();
                                pending_forward_info.prev_short_channel_id = short_channel_id;
                                (short_channel_id, chan.update_add_htlc(&msg, pending_forward_info)?)
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None}), //TODO: panic?
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None}), //TODO: panic?
                };
 
                match claimable_htlcs_entry {
@@ -1544,11 +1603,11 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.update_fulfill_htlc(&msg)?
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
@@ -1562,11 +1621,11 @@ impl ChannelMessageHandler for ChannelManager {
                let payment_hash = match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.update_fail_htlc(&msg, HTLCFailReason::ErrorPacket { err: msg.reason.clone() })
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                }?;
 
                if let Some(pending_htlc) = channel_state.claimable_htlcs.get(&payment_hash) {
@@ -1637,11 +1696,11 @@ impl ChannelMessageHandler for ChannelManager {
                match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.update_fail_malformed_htlc(&msg, HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() })
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                }
        }
 
@@ -1651,11 +1710,11 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.commitment_signed(&msg)?
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
@@ -1671,11 +1730,11 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.revoke_and_ack(&msg)?
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
@@ -1721,11 +1780,11 @@ impl ChannelMessageHandler for ChannelManager {
                match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.update_fee(&*self.fee_estimator, &msg)
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                }
        }
 
@@ -1735,10 +1794,10 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        if !chan.is_usable() {
-                                               return Err(HandleError{err: "Got an announcement_signatures before we were ready for it", msg: None });
+                                               return Err(HandleError{err: "Got an announcement_signatures before we were ready for it", action: None });
                                        }
 
                                        let our_node_id = self.get_our_node_id();
@@ -1759,7 +1818,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                contents: announcement,
                                        }, self.get_channel_update(chan).unwrap()) // can only fail if we're not in a ready state
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                let mut pending_events = self.pending_events.lock().unwrap();
@@ -1816,6 +1875,7 @@ impl ChannelMessageHandler for ChannelManager {
 mod tests {
        use chain::chaininterface;
        use chain::transaction::OutPoint;
+       use chain::chaininterface::ChainListener;
        use ln::channelmanager::{ChannelManager,OnionKeys};
        use ln::router::{Route, RouteHop, Router};
        use ln::msgs;
@@ -1825,8 +1885,7 @@ mod tests {
 
        use bitcoin::util::misc::hex_bytes;
        use bitcoin::util::hash::Sha256dHash;
-       use bitcoin::util::uint::Uint256;
-       use bitcoin::blockdata::block::BlockHeader;
+       use bitcoin::blockdata::block::{Block, BlockHeader};
        use bitcoin::blockdata::transaction::{Transaction, TxOut};
        use bitcoin::network::constants::Network;
        use bitcoin::network::serialize::serialize;
@@ -1966,7 +2025,7 @@ mod tests {
                        },
                );
 
-               let packet = ChannelManager::construct_onion_packet(payloads, onion_keys, hex_bytes("4242424242424242424242424242424242424242424242424242424242424242").unwrap()).unwrap();
+               let packet = ChannelManager::construct_onion_packet(payloads, onion_keys, &[0x42; 32]).unwrap();
                // Just check the final packet encoding, as it includes all the per-hop vectors in it
                // anyway...
                assert_eq!(packet.encode(), hex_bytes("0002eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619e5f14350c2a76fc232b5e46d421e9615471ab9e0bc887beff8c95fdb878f7b3a716a996c7845c93d90e4ecbb9bde4ece2f69425c99e4bc820e44485455f135edc0d10f7d61ab590531cf08000179a333a347f8b4072f216400406bdf3bf038659793d4a1fd7b246979e3150a0a4cb052c9ec69acf0f48c3d39cd55675fe717cb7d80ce721caad69320c3a469a202f1e468c67eaf7a7cd8226d0fd32f7b48084dca885d56047694762b67021713ca673929c163ec36e04e40ca8e1c6d17569419d3039d9a1ec866abe044a9ad635778b961fc0776dc832b3a451bd5d35072d2269cf9b040f6b7a7dad84fb114ed413b1426cb96ceaf83825665ed5a1d002c1687f92465b49ed4c7f0218ff8c6c7dd7221d589c65b3b9aaa71a41484b122846c7c7b57e02e679ea8469b70e14fe4f70fee4d87b910cf144be6fe48eef24da475c0b0bcc6565ae82cd3f4e3b24c76eaa5616c6111343306ab35c1fe5ca4a77c0e314ed7dba39d6f1e0de791719c241a939cc493bea2bae1c1e932679ea94d29084278513c77b899cc98059d06a27d171b0dbdf6bee13ddc4fc17a0c4d2827d488436b57baa167544138ca2e64a11b43ac8a06cd0c2fba2d4d900ed2d9205305e2d7383cc98dacb078133de5f6fb6bed2ef26ba92cea28aafc3b9948dd9ae5559e8bd6920b8cea462aa445ca6a95e0e7ba52961b181c79e73bd581821df2b10173727a810c92b83b5ba4a0403eb710d2ca10689a35bec6c3a708e9e92f7d78ff3c5d9989574b00c6736f84c199256e76e19e78f0c98a9d580b4a658c84fc8f2096c2fbea8f5f8c59d0fdacb3be2802ef802abbecb3aba4acaac69a0e965abd8981e9896b1f6ef9d60f7a164b371af869fd0e48073742825e9434fc54da837e120266d53302954843538ea7c6c3dbfb4ff3b2fdbe244437f2a153ccf7bdb4c92aa08102d4f3cff2ae5ef86fab4653595e6a5837fa2f3e29f27a9cde5966843fb847a4a61f1e76c281fe8bb2b0a181d096100db5a1a5ce7a910238251a43ca556712eaadea167fb4d7d75825e440f3ecd782036d7574df8bceacb397abefc5f5254d2722215c53ff54af8299aaaad642c6d72a14d27882d9bbd539e1cc7a527526ba89b8c037ad09120e98ab042d3e8652b31ae0e478516bfaf88efca9f3676ffe99d2819dcaeb7610a626695f53117665d267d3f7abebd6bbd6733f645c72c389f03855bdf1e4b8075b516569b118233a0f0971d24b83113c0b096f5216a207ca99a7cddc81c130923fe3d91e7508c9ac5f2e914ff5dccab9e558566fa14efb34ac98d878580814b94b73acbfde9072f30b881f7f0fff42d4045d1ace6322d86a97d164aa84d93a60498065cc7c20e636f5862dc81531a88c60305a2e59a985be327a6902e4bed986dbf4a0b50c217af0ea7fdf9ab37f9ea1a1aaa72f54cf40154ea9b269f1a7c09f9f43245109431a175d50e2db0132337baa0ef97eed0fcf20489da36b79a1172faccc2f7ded7c60e00694282d93359c4682135642bc81f433574aa8ef0c97b4ade7ca372c5ffc23c7eddd839bab4e0f14d6df15c9dbeab176bec8b5701cf054eb3072f6dadc98f88819042bf10c407516ee58bce33fbe3b3d86a54255e577db4598e30a135361528c101683a5fcde7e8ba53f3456254be8f45fe3a56120ae96ea3773631fcb3873aa3abd91bcff00bd38bd43697a2e789e00da6077482e7b1b1a677b5afae4c54e6cbdf7377b694eb7d7a5b913476a5be923322d3de06060fd5e819635232a2cf4f0731da13b8546d1d6d4f8d75b9fce6c2341a71b0ea6f780df54bfdb0dd5cd9855179f602f9172307c7268724c3618e6817abd793adc214a0dc0bc616816632f27ea336fb56dfd").unwrap());
@@ -1997,6 +2056,7 @@ mod tests {
        }
 
        fn confirm_transaction(chain: &chaininterface::ChainWatchInterfaceUtil, tx: &Transaction, chan_id: u32) {
+               assert!(chain.does_match_tx(tx));
                let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
                chain.block_connected_checked(&header, 1, &[tx; 1], &[chan_id; 1]);
                for i in 2..100 {
@@ -2016,7 +2076,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, Uint256, Transaction) {
+       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();
 
                let events_1 = node_a.node.get_and_clear_pending_events();
@@ -2144,7 +2204,7 @@ mod tests {
                ((*announcement).clone(), (*as_update).clone(), (*bs_update).clone(), channel_id, tx)
        }
 
-       fn create_announced_chan_between_nodes(nodes: &Vec<Node>, a: usize, b: usize) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, Uint256, Transaction) {
+       fn create_announced_chan_between_nodes(nodes: &Vec<Node>, a: usize, b: usize) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
                let chan_announcement = create_chan_between_nodes(&nodes[a], &nodes[b]);
                for node in nodes {
                        assert!(node.router.handle_channel_announcement(&chan_announcement.0).unwrap());
@@ -2154,12 +2214,22 @@ mod tests {
                (chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
        }
 
-       fn close_channel(outbound_node: &Node, inbound_node: &Node, channel_id: &Uint256, funding_tx: Transaction, close_inbound_first: bool) -> (msgs::ChannelUpdate, msgs::ChannelUpdate) {
+       fn close_channel(outbound_node: &Node, inbound_node: &Node, channel_id: &[u8; 32], funding_tx: Transaction, close_inbound_first: bool) -> (msgs::ChannelUpdate, msgs::ChannelUpdate) {
                let (node_a, broadcaster_a) = if close_inbound_first { (&inbound_node.node, &inbound_node.tx_broadcaster) } else { (&outbound_node.node, &outbound_node.tx_broadcaster) };
                let (node_b, broadcaster_b) = if close_inbound_first { (&outbound_node.node, &outbound_node.tx_broadcaster) } else { (&inbound_node.node, &inbound_node.tx_broadcaster) };
                let (tx_a, tx_b);
 
-               let shutdown_a = node_a.close_channel(channel_id).unwrap();
+               node_a.close_channel(channel_id).unwrap();
+               let events_1 = node_a.get_and_clear_pending_events();
+               assert_eq!(events_1.len(), 1);
+               let shutdown_a = match events_1[0] {
+                       Event::SendShutdown { ref node_id, ref msg } => {
+                               assert_eq!(node_id, &node_b.get_our_node_id());
+                               msg.clone()
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+
                let (shutdown_b, mut closing_signed_b) = node_b.handle_shutdown(&node_a.get_our_node_id(), &shutdown_a).unwrap();
                if !close_inbound_first {
                        assert!(closing_signed_b.is_none());
@@ -2191,18 +2261,18 @@ mod tests {
                funding_tx_map.insert(funding_tx.txid(), funding_tx);
                tx_a.verify(&funding_tx_map).unwrap();
 
-               let events_1 = node_a.get_and_clear_pending_events();
-               assert_eq!(events_1.len(), 1);
-               let as_update = match events_1[0] {
+               let events_2 = node_a.get_and_clear_pending_events();
+               assert_eq!(events_2.len(), 1);
+               let as_update = match events_2[0] {
                        Event::BroadcastChannelUpdate { ref msg } => {
                                msg.clone()
                        },
                        _ => panic!("Unexpected event"),
                };
 
-               let events_2 = node_b.get_and_clear_pending_events();
-               assert_eq!(events_2.len(), 1);
-               let bs_update = match events_2[0] {
+               let events_3 = node_b.get_and_clear_pending_events();
+               assert_eq!(events_3.len(), 1);
+               let bs_update = match events_3[0] {
                        Event::BroadcastChannelUpdate { ref msg } => {
                                msg.clone()
                        },
@@ -2292,7 +2362,7 @@ mod tests {
                        };
 
                        node.node.channel_state.lock().unwrap().next_forward = Instant::now();
-                       node.node.process_pending_htlc_forward();
+                       node.node.process_pending_htlc_forwards();
 
                        let mut events_2 = node.node.get_and_clear_pending_events();
                        assert_eq!(events_2.len(), 1);
@@ -2404,7 +2474,7 @@ mod tests {
        const TEST_FINAL_CLTV: u32 = 32;
 
        fn route_payment(origin_node: &Node, expected_route: &[&Node], recv_value: u64) -> ([u8; 32], [u8; 32]) {
-               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
+               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), None, &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
                assert_eq!(route.hops.len(), expected_route.len());
                for (node, hop) in expected_route.iter().zip(route.hops.iter()) {
                        assert_eq!(hop.pubkey, node.node.get_our_node_id());
@@ -2414,7 +2484,7 @@ mod tests {
        }
 
        fn route_over_limit(origin_node: &Node, expected_route: &[&Node], recv_value: u64) {
-               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
+               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), None, &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
                assert_eq!(route.hops.len(), expected_route.len());
                for (node, hop) in expected_route.iter().zip(route.hops.iter()) {
                        assert_eq!(hop.pubkey, node.node.get_our_node_id());
@@ -2528,7 +2598,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
 
                for _ in 0..node_count {
-                       let feeest = Arc::new(test_utils::TestFeeEstimator { sat_per_vbyte: 1 });
+                       let feeest = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 });
                        let chain_monitor = Arc::new(chaininterface::ChainWatchInterfaceUtil::new());
                        let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())});
                        let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone()));
@@ -2665,7 +2735,7 @@ mod tests {
 
        #[derive(PartialEq)]
        enum HTLCType { NONE, TIMEOUT, SUCCESS }
-       fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, Uint256, Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
+       fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
                let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
                assert!(node_txn.len() >= if commitment_tx.is_some() { 0 } else { 1 } + if has_htlc_tx == HTLCType::NONE { 0 } else { 1 });
 
@@ -2779,9 +2849,9 @@ mod tests {
                // Simple case with no pending HTLCs:
                nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true);
                {
-                       let node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
+                       let mut node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
                        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
                        assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
                }
                get_announce_close_broadcast_events(&nodes, 0, 1);
@@ -2794,9 +2864,9 @@ mod tests {
                // Simple case of one pending HTLC to HTLC-Timeout
                nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true);
                {
-                       let node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
+                       let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
                        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[2].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
                        assert_eq!(nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
                }
                get_announce_close_broadcast_events(&nodes, 1, 2);
@@ -2835,7 +2905,7 @@ mod tests {
                        claim_funds!(nodes[3], nodes[2], payment_preimage_1);
 
                        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[3].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[3].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, 1);
 
                        check_preimage_claim(&nodes[3], &node_txn);
                }
@@ -2849,7 +2919,7 @@ mod tests {
                {
                        let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
                        nodes[3].chain_monitor.block_connected_checked(&header, 1, &Vec::new()[..], &[0; 0]);
-                       for i in 2..TEST_FINAL_CLTV - 5 {
+                       for i in 2..TEST_FINAL_CLTV - 3 {
                                header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
                                nodes[3].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
                        }
@@ -2861,7 +2931,7 @@ mod tests {
 
                        header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
                        nodes[4].chain_monitor.block_connected_checked(&header, 1, &Vec::new()[..], &[0; 0]);
-                       for i in 2..TEST_FINAL_CLTV - 5 {
+                       for i in 2..TEST_FINAL_CLTV - 3 {
                                header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
                                nodes[4].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
                        }
@@ -2869,7 +2939,7 @@ mod tests {
                        test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS);
 
                        header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[4].chain_monitor.block_connected_checked(&header, TEST_FINAL_CLTV - 5, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[4].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, TEST_FINAL_CLTV - 5);
 
                        check_preimage_claim(&nodes[4], &node_txn);
                }
@@ -2889,7 +2959,7 @@ mod tests {
 
                {
                        let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[1].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 1]);
+                       nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
                        {
                                let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
                                assert_eq!(node_txn.len(), 1);
@@ -2901,10 +2971,10 @@ mod tests {
                                node_txn.clear();
                        }
 
-                       nodes[0].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 0]);
+                       nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
                        let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT);
                        header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[1]; 1], &[4; 1]);
+                       nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[1].clone()] }, 1);
 
                        //TODO: At this point nodes[1] should claim the revoked HTLC-Timeout output, but that's
                        //not yet implemented in ChannelMonitor
@@ -2919,4 +2989,30 @@ mod tests {
                        assert_eq!(node.chan_monitor.added_monitors.lock().unwrap().len(), 0);
                }
        }
+
+       #[test]
+       fn test_unconf_chan() {
+               // After creating a chan between nodes, we disconnect all blocks previously seen to force a channel close on nodes[0] side
+               let nodes = create_network(2);
+               create_announced_chan_between_nodes(&nodes, 0, 1);
+
+               let channel_state = nodes[0].node.channel_state.lock().unwrap();
+               assert_eq!(channel_state.by_id.len(), 1);
+               assert_eq!(channel_state.short_to_id.len(), 1);
+               mem::drop(channel_state);
+
+               let mut headers = Vec::new();
+               let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+               headers.push(header.clone());
+               for _i in 2..100 {
+                       header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       headers.push(header.clone());
+               }
+               while !headers.is_empty() {
+                       nodes[0].node.block_disconnected(&headers.pop().unwrap());
+               }
+               let channel_state = nodes[0].node.channel_state.lock().unwrap();
+               assert_eq!(channel_state.by_id.len(), 0);
+               assert_eq!(channel_state.short_to_id.len(), 0);
+       }
 }
index 1e8f8038c4c1846ff5c5108606ba6a5c62c83ba1..3fb1d8ad836e590dd54c6c5f09e34f9c767fdea9 100644 (file)
@@ -94,7 +94,10 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key>
                };
                match &monitor.funding_txo {
                        &None => self.chain_monitor.watch_all_txn(),
-                       &Some((ref outpoint, ref script)) => self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script),
+                       &Some((ref outpoint, ref script)) => {
+                               self.chain_monitor.install_watch_script(script);
+                               self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script);
+                       },
                }
                monitors.insert(key, monitor);
                Ok(())
@@ -316,7 +319,7 @@ impl ChannelMonitor {
                for i in 0..pos {
                        let (old_secret, old_idx) = self.old_secrets[i as usize];
                        if ChannelMonitor::derive_secret(secret, pos, old_idx) != old_secret {
-                               return Err(HandleError{err: "Previous secret did not match new one", msg: None})
+                               return Err(HandleError{err: "Previous secret did not match new one", action: None})
                        }
                }
                self.old_secrets[pos as usize] = (secret, idx);
@@ -421,7 +424,7 @@ impl ChannelMonitor {
        pub fn insert_combine(&mut self, mut other: ChannelMonitor) -> Result<(), HandleError> {
                if self.funding_txo.is_some() {
                        if other.funding_txo.is_some() && other.funding_txo.as_ref().unwrap() != self.funding_txo.as_ref().unwrap() {
-                               return Err(HandleError{err: "Funding transaction outputs are not identical!", msg: None});
+                               return Err(HandleError{err: "Funding transaction outputs are not identical!", action: None});
                        }
                } else {
                        self.funding_txo = other.funding_txo.take();
@@ -740,7 +743,7 @@ impl ChannelMonitor {
                for _ in 0..remote_claimable_outpoints_len {
                        let txid = Sha256dHash::from(read_bytes!(32));
                        let outputs_count = byte_utils::slice_to_be64(read_bytes!(8));
-                       if outputs_count > data.len() as u64 * 32 { return None; }
+                       if outputs_count > data.len() as u64 / 32 { return None; }
                        let mut outputs = Vec::with_capacity(outputs_count as usize);
                        for _ in 0..outputs_count {
                                outputs.push(read_htlc_in_commitment!());
@@ -882,7 +885,7 @@ impl ChannelMonitor {
                        }
                }
                assert!(idx < self.get_min_seen_secret());
-               Err(HandleError{err: "idx too low", msg: None})
+               Err(HandleError{err: "idx too low", action: None})
        }
 
        pub fn get_min_seen_secret(&self) -> u64 {
index 7cd4272e13c1013e5e4abe1d38380aa0bd4e76dd..add8b4df1aa2e722dbac5ce577a840c74d2ff5a0 100644 (file)
@@ -2,9 +2,13 @@ pub mod channelmanager;
 pub mod channelmonitor;
 pub mod msgs;
 pub mod router;
-pub mod peer_channel_encryptor;
 pub mod peer_handler;
 
+#[cfg(feature = "fuzztarget")]
+pub mod peer_channel_encryptor;
+#[cfg(not(feature = "fuzztarget"))]
+pub(crate) mod peer_channel_encryptor;
+
 #[cfg(feature = "fuzztarget")]
 pub mod channel;
 #[cfg(not(feature = "fuzztarget"))]
index bc7c0ed98b3c38052df2fa06f8eccb9078a2bd1f..7f502530a9db55f5177aad787380645d8d72fcf0 100644 (file)
@@ -1,6 +1,5 @@
 use secp256k1::key::PublicKey;
 use secp256k1::{Secp256k1, Signature};
-use bitcoin::util::uint::Uint256;
 use bitcoin::util::hash::Sha256dHash;
 use bitcoin::network::serialize::{deserialize,serialize};
 use bitcoin::blockdata::script::Script;
@@ -32,10 +31,15 @@ pub enum DecodeError {
        BadPublicKey,
        /// Failed to decode a signature (ie it's invalid)
        BadSignature,
-       /// Buffer not of right length (either too short or too long)
-       WrongLength,
+       /// Value expected to be text wasn't decodable as text
+       BadText,
+       /// Buffer too short
+       ShortRead,
        /// node_announcement included more than one address of a given type!
        ExtraAddressesPerType,
+       /// A length descriptor in the packet didn't describe the later data correctly
+       /// (currently only generated in node_announcement)
+       BadLengthDescriptor,
 }
 pub trait MsgDecodable: Sized {
        fn decode(v: &[u8]) -> Result<Self, DecodeError>;
@@ -139,6 +143,11 @@ pub struct Init {
        pub local_features: LocalFeatures,
 }
 
+pub struct ErrorMessage {
+       pub channel_id: [u8; 32],
+       pub data: String,
+}
+
 pub struct Ping {
        pub ponglen: u16,
        pub byteslen: u16,
@@ -150,7 +159,7 @@ pub struct Pong {
 
 pub struct OpenChannel {
        pub chain_hash: Sha256dHash,
-       pub temporary_channel_id: Uint256,
+       pub temporary_channel_id: [u8; 32],
        pub funding_satoshis: u64,
        pub push_msat: u64,
        pub dust_limit_satoshis: u64,
@@ -171,7 +180,7 @@ pub struct OpenChannel {
 }
 
 pub struct AcceptChannel {
-       pub temporary_channel_id: Uint256,
+       pub temporary_channel_id: [u8; 32],
        pub dust_limit_satoshis: u64,
        pub max_htlc_value_in_flight_msat: u64,
        pub channel_reserve_satoshis: u64,
@@ -189,36 +198,36 @@ pub struct AcceptChannel {
 }
 
 pub struct FundingCreated {
-       pub temporary_channel_id: Uint256,
+       pub temporary_channel_id: [u8; 32],
        pub funding_txid: Sha256dHash,
        pub funding_output_index: u16,
        pub signature: Signature,
 }
 
 pub struct FundingSigned {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub signature: Signature,
 }
 
 pub struct FundingLocked {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub next_per_commitment_point: PublicKey,
 }
 
 pub struct Shutdown {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub scriptpubkey: Script,
 }
 
 pub struct ClosingSigned {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub fee_satoshis: u64,
        pub signature: Signature,
 }
 
 #[derive(Clone)]
 pub struct UpdateAddHTLC {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub htlc_id: u64,
        pub amount_msat: u64,
        pub payment_hash: [u8; 32],
@@ -228,21 +237,21 @@ pub struct UpdateAddHTLC {
 
 #[derive(Clone)]
 pub struct UpdateFulfillHTLC {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub htlc_id: u64,
        pub payment_preimage: [u8; 32],
 }
 
 #[derive(Clone)]
 pub struct UpdateFailHTLC {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub htlc_id: u64,
        pub reason: OnionErrorPacket,
 }
 
 #[derive(Clone)]
 pub struct UpdateFailMalformedHTLC {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub htlc_id: u64,
        pub sha256_of_onion: [u8; 32],
        pub failure_code: u16,
@@ -250,24 +259,24 @@ pub struct UpdateFailMalformedHTLC {
 
 #[derive(Clone)]
 pub struct CommitmentSigned {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub signature: Signature,
        pub htlc_signatures: Vec<Signature>,
 }
 
 pub struct RevokeAndACK {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub per_commitment_secret: [u8; 32],
        pub next_per_commitment_point: PublicKey,
 }
 
 pub struct UpdateFee {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub feerate_per_kw: u32,
 }
 
 pub struct ChannelReestablish {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub next_local_commitment_number: u64,
        pub next_remote_commitment_number: u64,
        pub your_last_per_commitment_secret: Option<[u8; 32]>,
@@ -276,7 +285,7 @@ pub struct ChannelReestablish {
 
 #[derive(Clone)]
 pub struct AnnouncementSignatures {
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        pub short_channel_id: u64,
        pub node_signature: Signature,
        pub bitcoin_signature: Signature,
@@ -373,14 +382,20 @@ pub enum ErrorAction {
                msg: UpdateFailHTLC
        },
        /// The peer took some action which made us think they were useless. Disconnect them.
-       DisconnectPeer,
+       DisconnectPeer {
+               msg: Option<ErrorMessage>
+       },
        /// The peer did something harmless that we weren't able to process, just log and ignore
        IgnoreError,
+       /// The peer did something incorrect. Tell them.
+       SendErrorMessage {
+               msg: ErrorMessage
+       },
 }
 
 pub struct HandleError { //TODO: rename me
        pub err: &'static str,
-       pub msg: Option<ErrorAction>, //TODO: Make this required and rename it
+       pub action: Option<ErrorAction>, //TODO: Make this required
 }
 
 /// Struct used to return values from revoke_and_ack messages, containing a bunch of commitment
@@ -487,8 +502,10 @@ impl Error for DecodeError {
                        DecodeError::UnknownRealmByte => "Unknown realm byte in Onion packet",
                        DecodeError::BadPublicKey => "Invalid public key in packet",
                        DecodeError::BadSignature => "Invalid signature in packet",
-                       DecodeError::WrongLength => "Data was wrong length for packet",
+                       DecodeError::BadText => "Invalid text in packet",
+                       DecodeError::ShortRead => "Packet extended beyond the provided bytes",
                        DecodeError::ExtraAddressesPerType => "More than one address of a single type",
+                       DecodeError::BadLengthDescriptor => "A length descriptor in the packet didn't describe the later data correctly",
                }
        }
 }
@@ -524,9 +541,9 @@ macro_rules! secp_signature {
 
 impl MsgDecodable for LocalFeatures {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
-               if v.len() < 2 { return Err(DecodeError::WrongLength); }
+               if v.len() < 2 { return Err(DecodeError::ShortRead); }
                let len = byte_utils::slice_to_be16(&v[0..2]) as usize;
-               if v.len() < len + 2 { return Err(DecodeError::WrongLength); }
+               if v.len() < len + 2 { return Err(DecodeError::ShortRead); }
                let mut flags = Vec::with_capacity(len);
                flags.extend_from_slice(&v[2..2 + len]);
                Ok(Self {
@@ -546,9 +563,9 @@ impl MsgEncodable for LocalFeatures {
 
 impl MsgDecodable for GlobalFeatures {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
-               if v.len() < 2 { return Err(DecodeError::WrongLength); }
+               if v.len() < 2 { return Err(DecodeError::ShortRead); }
                let len = byte_utils::slice_to_be16(&v[0..2]) as usize;
-               if v.len() < len + 2 { return Err(DecodeError::WrongLength); }
+               if v.len() < len + 2 { return Err(DecodeError::ShortRead); }
                let mut flags = Vec::with_capacity(len);
                flags.extend_from_slice(&v[2..2 + len]);
                Ok(Self {
@@ -570,7 +587,7 @@ impl MsgDecodable for Init {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                let global_features = GlobalFeatures::decode(v)?;
                if v.len() < global_features.flags.len() + 4 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let local_features = LocalFeatures::decode(&v[global_features.flags.len() + 2..])?;
                Ok(Self {
@@ -591,12 +608,12 @@ impl MsgEncodable for Init {
 impl MsgDecodable for Ping {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 4 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let ponglen = byte_utils::slice_to_be16(&v[0..2]);
                let byteslen = byte_utils::slice_to_be16(&v[2..4]);
                if v.len() < 4 + byteslen as usize {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                Ok(Self {
                        ponglen,
@@ -616,11 +633,11 @@ impl MsgEncodable for Ping {
 impl MsgDecodable for Pong {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 2 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let byteslen = byte_utils::slice_to_be16(&v[0..2]);
                if v.len() < 2 + byteslen as usize {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                Ok(Self {
                        byteslen
@@ -639,7 +656,7 @@ impl MsgEncodable for Pong {
 impl MsgDecodable for OpenChannel {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 2*32+6*8+4+2*2+6*33+1 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let ctx = Secp256k1::without_caps();
 
@@ -647,11 +664,9 @@ impl MsgDecodable for OpenChannel {
                if v.len() >= 321 {
                        let len = byte_utils::slice_to_be16(&v[319..321]) as usize;
                        if v.len() < 321+len {
-                               return Err(DecodeError::WrongLength);
+                               return Err(DecodeError::ShortRead);
                        }
                        shutdown_scriptpubkey = Some(Script::from(v[321..321+len].to_vec()));
-               } else if v.len() != 2*32+6*8+4+2*2+6*33+1 { // Message cant have 1 extra byte
-                       return Err(DecodeError::WrongLength);
                }
 
                Ok(OpenChannel {
@@ -712,7 +727,7 @@ impl MsgEncodable for OpenChannel {
 impl MsgDecodable for AcceptChannel {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+4*8+4+2*2+6*33 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let ctx = Secp256k1::without_caps();
 
@@ -720,15 +735,15 @@ impl MsgDecodable for AcceptChannel {
                if v.len() >= 272 {
                        let len = byte_utils::slice_to_be16(&v[270..272]) as usize;
                        if v.len() < 272+len {
-                               return Err(DecodeError::WrongLength);
+                               return Err(DecodeError::ShortRead);
                        }
                        shutdown_scriptpubkey = Some(Script::from(v[272..272+len].to_vec()));
-               } else if v.len() != 32+4*8+4+2*2+6*33 { // Message cant have 1 extra byte
-                       return Err(DecodeError::WrongLength);
                }
 
+               let mut temporary_channel_id = [0; 32];
+               temporary_channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       temporary_channel_id: deserialize(&v[0..32]).unwrap(),
+                       temporary_channel_id,
                        dust_limit_satoshis: byte_utils::slice_to_be64(&v[32..40]),
                        max_htlc_value_in_flight_msat: byte_utils::slice_to_be64(&v[40..48]),
                        channel_reserve_satoshis: byte_utils::slice_to_be64(&v[48..56]),
@@ -752,7 +767,7 @@ impl MsgEncodable for AcceptChannel {
                        &Some(ref script) => Vec::with_capacity(270 + 2 + script.len()),
                        &None => Vec::with_capacity(270),
                };
-               res.extend_from_slice(&serialize(&self.temporary_channel_id).unwrap()[..]);
+               res.extend_from_slice(&self.temporary_channel_id);
                res.extend_from_slice(&byte_utils::be64_to_array(self.dust_limit_satoshis));
                res.extend_from_slice(&byte_utils::be64_to_array(self.max_htlc_value_in_flight_msat));
                res.extend_from_slice(&byte_utils::be64_to_array(self.channel_reserve_satoshis));
@@ -777,11 +792,13 @@ impl MsgEncodable for AcceptChannel {
 impl MsgDecodable for FundingCreated {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+32+2+64 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let ctx = Secp256k1::without_caps();
+               let mut temporary_channel_id = [0; 32];
+               temporary_channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       temporary_channel_id: deserialize(&v[0..32]).unwrap(),
+                       temporary_channel_id,
                        funding_txid: deserialize(&v[32..64]).unwrap(),
                        funding_output_index: byte_utils::slice_to_be16(&v[64..66]),
                        signature: secp_signature!(&ctx, &v[66..130]),
@@ -791,7 +808,7 @@ impl MsgDecodable for FundingCreated {
 impl MsgEncodable for FundingCreated {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+32+2+64);
-               res.extend_from_slice(&serialize(&self.temporary_channel_id).unwrap()[..]);
+               res.extend_from_slice(&self.temporary_channel_id);
                res.extend_from_slice(&serialize(&self.funding_txid).unwrap()[..]);
                res.extend_from_slice(&byte_utils::be16_to_array(self.funding_output_index));
                let secp_ctx = Secp256k1::without_caps();
@@ -803,11 +820,13 @@ impl MsgEncodable for FundingCreated {
 impl MsgDecodable for FundingSigned {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+64 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let ctx = Secp256k1::without_caps();
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        signature: secp_signature!(&ctx, &v[32..96]),
                })
        }
@@ -815,7 +834,7 @@ impl MsgDecodable for FundingSigned {
 impl MsgEncodable for FundingSigned {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+64);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&self.signature.serialize_compact(&Secp256k1::without_caps()));
                res
        }
@@ -824,11 +843,13 @@ impl MsgEncodable for FundingSigned {
 impl MsgDecodable for FundingLocked {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+33 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let ctx = Secp256k1::without_caps();
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        next_per_commitment_point: secp_pubkey!(&ctx, &v[32..65]),
                })
        }
@@ -836,7 +857,7 @@ impl MsgDecodable for FundingLocked {
 impl MsgEncodable for FundingLocked {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+33);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&self.next_per_commitment_point.serialize());
                res
        }
@@ -845,14 +866,16 @@ impl MsgEncodable for FundingLocked {
 impl MsgDecodable for Shutdown {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32 + 2 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let scriptlen = byte_utils::slice_to_be16(&v[32..34]) as usize;
                if v.len() < 32 + 2 + scriptlen {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        scriptpubkey: Script::from(v[34..34 + scriptlen].to_vec()),
                })
        }
@@ -860,7 +883,7 @@ impl MsgDecodable for Shutdown {
 impl MsgEncodable for Shutdown {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32 + 2 + self.scriptpubkey.len());
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be16_to_array(self.scriptpubkey.len() as u16));
                res.extend_from_slice(&self.scriptpubkey[..]);
                res
@@ -870,11 +893,13 @@ impl MsgEncodable for Shutdown {
 impl MsgDecodable for ClosingSigned {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32 + 8 + 64 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let secp_ctx = Secp256k1::without_caps();
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        fee_satoshis: byte_utils::slice_to_be64(&v[32..40]),
                        signature: secp_signature!(&secp_ctx, &v[40..104]),
                })
@@ -883,7 +908,7 @@ impl MsgDecodable for ClosingSigned {
 impl MsgEncodable for ClosingSigned {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+8+64);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be64_to_array(self.fee_satoshis));
                let secp_ctx = Secp256k1::without_caps();
                res.extend_from_slice(&self.signature.serialize_compact(&secp_ctx));
@@ -894,12 +919,14 @@ impl MsgEncodable for ClosingSigned {
 impl MsgDecodable for UpdateAddHTLC {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+8+8+32+4+1+33+20*65+32 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                let mut payment_hash = [0; 32];
                payment_hash.copy_from_slice(&v[48..80]);
                Ok(Self{
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        htlc_id: byte_utils::slice_to_be64(&v[32..40]),
                        amount_msat: byte_utils::slice_to_be64(&v[40..48]),
                        payment_hash,
@@ -911,7 +938,7 @@ impl MsgDecodable for UpdateAddHTLC {
 impl MsgEncodable for UpdateAddHTLC {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+8+8+32+4+1+1366);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id));
                res.extend_from_slice(&byte_utils::be64_to_array(self.amount_msat));
                res.extend_from_slice(&self.payment_hash);
@@ -924,12 +951,14 @@ impl MsgEncodable for UpdateAddHTLC {
 impl MsgDecodable for UpdateFulfillHTLC {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+8+32 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                let mut payment_preimage = [0; 32];
                payment_preimage.copy_from_slice(&v[40..72]);
                Ok(Self{
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        htlc_id: byte_utils::slice_to_be64(&v[32..40]),
                        payment_preimage,
                })
@@ -938,7 +967,7 @@ impl MsgDecodable for UpdateFulfillHTLC {
 impl MsgEncodable for UpdateFulfillHTLC {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+8+32);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id));
                res.extend_from_slice(&self.payment_preimage);
                res
@@ -948,10 +977,12 @@ impl MsgEncodable for UpdateFulfillHTLC {
 impl MsgDecodable for UpdateFailHTLC {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+8 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self{
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        htlc_id: byte_utils::slice_to_be64(&v[32..40]),
                        reason: OnionErrorPacket::decode(&v[40..])?,
                })
@@ -961,7 +992,7 @@ impl MsgEncodable for UpdateFailHTLC {
        fn encode(&self) -> Vec<u8> {
                let reason = self.reason.encode();
                let mut res = Vec::with_capacity(32+8+reason.len());
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id));
                res.extend_from_slice(&reason[..]);
                res
@@ -971,12 +1002,14 @@ impl MsgEncodable for UpdateFailHTLC {
 impl MsgDecodable for UpdateFailMalformedHTLC {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+8+32+2 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                let mut sha256_of_onion = [0; 32];
                sha256_of_onion.copy_from_slice(&v[40..72]);
                Ok(Self{
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        htlc_id: byte_utils::slice_to_be64(&v[32..40]),
                        sha256_of_onion,
                        failure_code: byte_utils::slice_to_be16(&v[72..74]),
@@ -986,7 +1019,7 @@ impl MsgDecodable for UpdateFailMalformedHTLC {
 impl MsgEncodable for UpdateFailMalformedHTLC {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+8+32+2);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id));
                res.extend_from_slice(&self.sha256_of_onion);
                res.extend_from_slice(&byte_utils::be16_to_array(self.failure_code));
@@ -997,11 +1030,14 @@ impl MsgEncodable for UpdateFailMalformedHTLC {
 impl MsgDecodable for CommitmentSigned {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+64+2 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
+
                let htlcs = byte_utils::slice_to_be16(&v[96..98]) as usize;
                if v.len() < 32+64+2+htlcs*64 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let mut htlc_signatures = Vec::with_capacity(htlcs);
                let secp_ctx = Secp256k1::without_caps();
@@ -1009,7 +1045,7 @@ impl MsgDecodable for CommitmentSigned {
                        htlc_signatures.push(secp_signature!(&secp_ctx, &v[98+i*64..98+(i+1)*64]));
                }
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        signature: secp_signature!(&secp_ctx, &v[32..96]),
                        htlc_signatures,
                })
@@ -1018,7 +1054,7 @@ impl MsgDecodable for CommitmentSigned {
 impl MsgEncodable for CommitmentSigned {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+64+2+self.htlc_signatures.len()*64);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                let secp_ctx = Secp256k1::without_caps();
                res.extend_from_slice(&self.signature.serialize_compact(&secp_ctx));
                res.extend_from_slice(&byte_utils::be16_to_array(self.htlc_signatures.len() as u16));
@@ -1032,13 +1068,15 @@ impl MsgEncodable for CommitmentSigned {
 impl MsgDecodable for RevokeAndACK {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+32+33 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                let mut per_commitment_secret = [0; 32];
                per_commitment_secret.copy_from_slice(&v[32..64]);
                let secp_ctx = Secp256k1::without_caps();
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        per_commitment_secret,
                        next_per_commitment_point: secp_pubkey!(&secp_ctx, &v[64..97]),
                })
@@ -1047,7 +1085,7 @@ impl MsgDecodable for RevokeAndACK {
 impl MsgEncodable for RevokeAndACK {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+32+33);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&self.per_commitment_secret);
                res.extend_from_slice(&self.next_per_commitment_point.serialize());
                res
@@ -1057,10 +1095,12 @@ impl MsgEncodable for RevokeAndACK {
 impl MsgDecodable for UpdateFee {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+4 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        feerate_per_kw: byte_utils::slice_to_be32(&v[32..36]),
                })
        }
@@ -1068,31 +1108,70 @@ impl MsgDecodable for UpdateFee {
 impl MsgEncodable for UpdateFee {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+4);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be32_to_array(self.feerate_per_kw));
                res
        }
 }
 
 impl MsgDecodable for ChannelReestablish {
-       fn decode(_v: &[u8]) -> Result<Self, DecodeError> {
-               unimplemented!();
+       fn decode(v: &[u8]) -> Result<Self, DecodeError> {
+               if v.len() < 32+2*8+33 {
+                       return Err(DecodeError::ShortRead);
+               }
+
+               let your_last_per_commitment_secret = if v.len() > 32+2*8+33 {
+                       if v.len() < 32+2*8+33 + 32 {
+                               return Err(DecodeError::ShortRead);
+                       }
+                       let mut inner_array = [0; 32];
+                       inner_array.copy_from_slice(&v[48..48+32]);
+                       Some(inner_array)
+               } else { None };
+
+               let option_size = match &your_last_per_commitment_secret {
+                       &Some(ref _ary) => 32,
+                       &None => 0,
+               };
+               Ok(Self {
+                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       next_local_commitment_number: byte_utils::slice_to_be64(&v[32..40]),
+                       next_remote_commitment_number: byte_utils::slice_to_be64(&v[40..48]),
+                       your_last_per_commitment_secret: your_last_per_commitment_secret,
+                       my_current_per_commitment_point: {
+                               let ctx = Secp256k1::without_caps();
+                               secp_pubkey!(&ctx, &v[48+option_size..48+option_size+33])
+                       }
+               })
        }
 }
 impl MsgEncodable for ChannelReestablish {
        fn encode(&self) -> Vec<u8> {
-               unimplemented!();
+               let mut res = Vec::with_capacity(if self.your_last_per_commitment_secret.is_some() { 32+2*3+33 + 32 } else { 32+2*8+33 });
+
+               res.extend_from_slice(&serialize(&self.channel_id).unwrap()[..]);
+               res.extend_from_slice(&byte_utils::be64_to_array(self.next_local_commitment_number));
+               res.extend_from_slice(&byte_utils::be64_to_array(self.next_remote_commitment_number));
+
+               if let &Some(ref ary) = &self.your_last_per_commitment_secret {
+                       res.extend_from_slice(&ary[..]);
+               }
+
+               res.extend_from_slice(&self.my_current_per_commitment_point.serialize());
+               res
        }
 }
 
 impl MsgDecodable for AnnouncementSignatures {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+8+64*2 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let secp_ctx = Secp256k1::without_caps();
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
                Ok(Self {
-                       channel_id: deserialize(&v[0..32]).unwrap(),
+                       channel_id,
                        short_channel_id: byte_utils::slice_to_be64(&v[32..40]),
                        node_signature: secp_signature!(&secp_ctx, &v[40..104]),
                        bitcoin_signature: secp_signature!(&secp_ctx, &v[104..168]),
@@ -1102,7 +1181,7 @@ impl MsgDecodable for AnnouncementSignatures {
 impl MsgEncodable for AnnouncementSignatures {
        fn encode(&self) -> Vec<u8> {
                let mut res = Vec::with_capacity(32+8+64*2);
-               res.extend_from_slice(&serialize(&self.channel_id).unwrap());
+               res.extend_from_slice(&self.channel_id);
                res.extend_from_slice(&byte_utils::be64_to_array(self.short_channel_id));
                let secp_ctx = Secp256k1::without_caps();
                res.extend_from_slice(&self.node_signature.serialize_compact(&secp_ctx));
@@ -1115,7 +1194,7 @@ impl MsgDecodable for UnsignedNodeAnnouncement {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                let features = GlobalFeatures::decode(&v[..])?;
                if v.len() < features.encoded_len() + 4 + 33 + 3 + 32 + 2 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let start = features.encoded_len();
 
@@ -1127,22 +1206,23 @@ impl MsgDecodable for UnsignedNodeAnnouncement {
 
                let addrlen = byte_utils::slice_to_be16(&v[start + 72..start + 74]) as usize;
                if v.len() < start + 74 + addrlen {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
+               let addr_read_limit = start + 74 + addrlen;
 
                let mut addresses = Vec::with_capacity(4);
                let mut read_pos = start + 74;
                loop {
-                       if v.len() <= read_pos { break; }
+                       if addr_read_limit <= read_pos { break; }
                        match v[read_pos] {
                                0 => { read_pos += 1; },
                                1 => {
-                                       if v.len() < read_pos + 1 + 6 {
-                                               return Err(DecodeError::WrongLength);
-                                       }
                                        if addresses.len() > 0 {
                                                return Err(DecodeError::ExtraAddressesPerType);
                                        }
+                                       if addr_read_limit < read_pos + 1 + 6 {
+                                               return Err(DecodeError::BadLengthDescriptor);
+                                       }
                                        let mut addr = [0; 4];
                                        addr.copy_from_slice(&v[read_pos + 1..read_pos + 5]);
                                        addresses.push(NetAddress::IPv4 {
@@ -1152,12 +1232,12 @@ impl MsgDecodable for UnsignedNodeAnnouncement {
                                        read_pos += 1 + 6;
                                },
                                2 => {
-                                       if v.len() < read_pos + 1 + 18 {
-                                               return Err(DecodeError::WrongLength);
-                                       }
                                        if addresses.len() > 1 || (addresses.len() == 1 && addresses[0].get_id() != 1) {
                                                return Err(DecodeError::ExtraAddressesPerType);
                                        }
+                                       if addr_read_limit < read_pos + 1 + 18 {
+                                               return Err(DecodeError::BadLengthDescriptor);
+                                       }
                                        let mut addr = [0; 16];
                                        addr.copy_from_slice(&v[read_pos + 1..read_pos + 17]);
                                        addresses.push(NetAddress::IPv6 {
@@ -1167,12 +1247,12 @@ impl MsgDecodable for UnsignedNodeAnnouncement {
                                        read_pos += 1 + 18;
                                },
                                3 => {
-                                       if v.len() < read_pos + 1 + 12 {
-                                               return Err(DecodeError::WrongLength);
-                                       }
                                        if addresses.len() > 2 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 2) {
                                                return Err(DecodeError::ExtraAddressesPerType);
                                        }
+                                       if addr_read_limit < read_pos + 1 + 12 {
+                                               return Err(DecodeError::BadLengthDescriptor);
+                                       }
                                        let mut addr = [0; 10];
                                        addr.copy_from_slice(&v[read_pos + 1..read_pos + 11]);
                                        addresses.push(NetAddress::OnionV2 {
@@ -1182,12 +1262,12 @@ impl MsgDecodable for UnsignedNodeAnnouncement {
                                        read_pos += 1 + 12;
                                },
                                4 => {
-                                       if v.len() < read_pos + 1 + 37 {
-                                               return Err(DecodeError::WrongLength);
-                                       }
                                        if addresses.len() > 3 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 3) {
                                                return Err(DecodeError::ExtraAddressesPerType);
                                        }
+                                       if addr_read_limit < read_pos + 1 + 37 {
+                                               return Err(DecodeError::BadLengthDescriptor);
+                                       }
                                        let mut ed25519_pubkey = [0; 32];
                                        ed25519_pubkey.copy_from_slice(&v[read_pos + 1..read_pos + 33]);
                                        addresses.push(NetAddress::OnionV3 {
@@ -1261,7 +1341,7 @@ impl MsgEncodable for UnsignedNodeAnnouncement {
 impl MsgDecodable for NodeAnnouncement {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 64 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let secp_ctx = Secp256k1::without_caps();
                Ok(Self {
@@ -1285,7 +1365,7 @@ impl MsgDecodable for UnsignedChannelAnnouncement {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                let features = GlobalFeatures::decode(&v[..])?;
                if v.len() < features.encoded_len() + 32 + 8 + 33*4 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let start = features.encoded_len();
                let secp_ctx = Secp256k1::without_caps();
@@ -1318,7 +1398,7 @@ impl MsgEncodable for UnsignedChannelAnnouncement {
 impl MsgDecodable for ChannelAnnouncement {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 64*4 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let secp_ctx = Secp256k1::without_caps();
                Ok(Self {
@@ -1347,7 +1427,7 @@ impl MsgEncodable for ChannelAnnouncement {
 impl MsgDecodable for UnsignedChannelUpdate {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32+8+4+2+2+8+4+4 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                Ok(Self {
                        chain_hash: deserialize(&v[0..32]).unwrap(),
@@ -1379,7 +1459,7 @@ impl MsgEncodable for UnsignedChannelUpdate {
 impl MsgDecodable for ChannelUpdate {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 128 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let secp_ctx = Secp256k1::without_caps();
                Ok(Self {
@@ -1400,7 +1480,7 @@ impl MsgEncodable for ChannelUpdate {
 impl MsgDecodable for OnionRealm0HopData {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                Ok(OnionRealm0HopData {
                        short_channel_id: byte_utils::slice_to_be64(&v[0..8]),
@@ -1423,7 +1503,7 @@ impl MsgEncodable for OnionRealm0HopData {
 impl MsgDecodable for OnionHopData {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 65 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let realm = v[0];
                if realm != 0 {
@@ -1451,7 +1531,7 @@ impl MsgEncodable for OnionHopData {
 impl MsgDecodable for OnionPacket {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 1+33+20*65+32 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let mut hop_data = [0; 20*65];
                hop_data.copy_from_slice(&v[34..1334]);
@@ -1480,15 +1560,15 @@ impl MsgEncodable for OnionPacket {
 impl MsgDecodable for DecodedOnionErrorPacket {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 32 + 4 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let failuremsg_len = byte_utils::slice_to_be16(&v[32..34]) as usize;
                if v.len() < 32 + 4 + failuremsg_len {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let padding_len = byte_utils::slice_to_be16(&v[34 + failuremsg_len..]) as usize;
                if v.len() < 32 + 4 + failuremsg_len + padding_len {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
 
                let mut hmac = [0; 32];
@@ -1515,11 +1595,11 @@ impl MsgEncodable for DecodedOnionErrorPacket {
 impl MsgDecodable for OnionErrorPacket {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                if v.len() < 2 {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                let len = byte_utils::slice_to_be16(&v[0..2]) as usize;
                if v.len() < 2 + len {
-                       return Err(DecodeError::WrongLength);
+                       return Err(DecodeError::ShortRead);
                }
                Ok(Self {
                        data: v[2..len+2].to_vec(),
@@ -1534,3 +1614,87 @@ impl MsgEncodable for OnionErrorPacket {
                res
        }
 }
+
+impl MsgEncodable for ErrorMessage {
+       fn encode(&self) -> Vec<u8> {
+               let mut res = Vec::with_capacity(34 + self.data.len());
+               res.extend_from_slice(&self.channel_id);
+               res.extend_from_slice(&byte_utils::be16_to_array(self.data.len() as u16));
+               res.extend_from_slice(&self.data.as_bytes());
+               res
+       }
+}
+impl MsgDecodable for ErrorMessage {
+       fn decode(v: &[u8]) -> Result<Self,DecodeError> {
+               if v.len() < 34 {
+                       return Err(DecodeError::ShortRead);
+               }
+               let len = byte_utils::slice_to_be16(&v[32..34]);
+               if v.len() < 34 + len as usize {
+                       return Err(DecodeError::ShortRead);
+               }
+               let data = match String::from_utf8(v[34..34 + len as usize].to_vec()) {
+                       Ok(s) => s,
+                       Err(_) => return Err(DecodeError::BadText),
+               };
+               let mut channel_id = [0; 32];
+               channel_id[..].copy_from_slice(&v[0..32]);
+               Ok(Self {
+                       channel_id,
+                       data,
+               })
+       }
+}
+
+#[cfg(test)]
+mod tests {
+       use bitcoin::util::misc::hex_bytes;
+       use ln::msgs::MsgEncodable;
+       use ln::msgs;
+       use secp256k1::key::{PublicKey,SecretKey};
+       use secp256k1::Secp256k1;
+
+       #[test]
+       fn encoding_channel_reestablish_no_secret() {
+               let public_key = {
+                       let secp_ctx = Secp256k1::new();
+                       PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()).unwrap()
+               };
+
+               let cr = msgs::ChannelReestablish {
+                       channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
+                       next_local_commitment_number: 3,
+                       next_remote_commitment_number: 4,
+                       your_last_per_commitment_secret: None,
+                       my_current_per_commitment_point: public_key,
+               };
+
+               let encoded_value = cr.encode();
+               assert_eq!(
+                       encoded_value,
+                       vec![4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 3, 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143]
+               );
+       }
+
+       #[test]
+       fn encoding_channel_reestablish_with_secret() {
+               let public_key = {
+                       let secp_ctx = Secp256k1::new();
+                       PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()).unwrap()
+               };
+
+               let cr = msgs::ChannelReestablish {
+                       channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
+                       next_local_commitment_number: 3,
+                       next_remote_commitment_number: 4,
+                       your_last_per_commitment_secret: Some([9; 32]),
+                       my_current_per_commitment_point: public_key,
+               };
+
+               let encoded_value = cr.encode();
+               assert_eq!(
+                       encoded_value,
+                       vec![4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143]
+               );
+       }
+}
index 3ec6241fb373fd58b415fbec2f548912a0cf9b96..f72c0dbe6b3f530c209739984923aa91814e60c2 100644 (file)
@@ -147,7 +147,7 @@ impl PeerChannelEncryptor {
 
                let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce, h);
                if !chacha.decrypt(&cyphertext[0..cyphertext.len() - 16], res, &cyphertext[cyphertext.len() - 16..]) {
-                       return Err(HandleError{err: "Bad MAC", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "Bad MAC", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
                Ok(())
        }
@@ -195,11 +195,11 @@ impl PeerChannelEncryptor {
                assert_eq!(act.len(), 50);
 
                if act[0] != 0 {
-                       return Err(HandleError{err: "Unknown handshake version number", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                       return Err(HandleError{err: "Unknown handshake version number", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                }
 
                let their_pub = match PublicKey::from_slice(secp_ctx, &act[1..34]) {
-                       Err(_) => return Err(HandleError{err: "Invalid public key", msg: Some(msgs::ErrorAction::DisconnectPeer{})}),
+                       Err(_) => return Err(HandleError{err: "Invalid public key", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}),
                        Ok(key) => key,
                };
 
@@ -349,14 +349,14 @@ impl PeerChannelEncryptor {
                                                        panic!("Requested act at wrong step");
                                                }
                                                if act_three[0] != 0 {
-                                                       return Err(HandleError{err: "Unknown handshake version number", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
+                                                       return Err(HandleError{err: "Unknown handshake version number", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
                                                }
 
                                                let mut their_node_id = [0; 33];
                                                PeerChannelEncryptor::decrypt_with_ad(&mut their_node_id, 1, &temp_k2.unwrap(), &bidirectional_state.h, &act_three[1..50])?;
                                                self.their_node_id = Some(match PublicKey::from_slice(&self.secp_ctx, &their_node_id) {
                                                        Ok(key) => key,
-                                                       Err(_) => return Err(HandleError{err: "Bad node_id from peer", msg: Some(msgs::ErrorAction::DisconnectPeer{})}),
+                                                       Err(_) => return Err(HandleError{err: "Bad node_id from peer", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}),
                                                });
 
                                                let mut sha = Sha256::new();
index 2472518d613a4199678a6dbe0c811d9fe42e38ea..bf0052d0236cdb69a469b0fa53a456c3bde8c55c 100644 (file)
@@ -37,6 +37,12 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
        /// indicating that read events on this descriptor should resume. A resume_read of false does
        /// *not* imply that further read events should be paused.
        fn send_data(&mut self, data: &Vec<u8>, write_offset: usize, resume_read: bool) -> usize;
+       /// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
+       /// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
+       /// No disconnect_event should be generated as a result of this call, though obviously races
+       /// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
+       /// that event completing.
+       fn disconnect_socket(&mut self);
 }
 
 /// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
@@ -121,6 +127,15 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                }
        }
 
+       /// Get the list of node ids for peers which have completed the initial handshake.
+       /// For outbound connections, this will be the same as the their_node_id parameter passed in to
+       /// new_outbound_connection, however entries will only appear once the initial handshake has
+       /// completed and we are sure the remote peer has the private key for the given node_id.
+       pub fn get_peer_node_ids(&self) -> Vec<PublicKey> {
+               let peers = self.peers.lock().unwrap();
+               peers.peers.values().filter_map(|p| p.their_node_id).collect()
+       }
+
        /// Indicates a new outbound connection has been established to a node with the given node_id.
        /// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
        /// descriptor but must disconnect the connection immediately.
@@ -281,18 +296,22 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                                                Ok(x) => x,
                                                                                Err(e) => {
                                                                                        println!("Got error handling message: {}!", e.err);
-                                                                                       if let Some(action) = e.msg {
+                                                                                       if let Some(action) = e.action {
                                                                                                match action {
                                                                                                        msgs::ErrorAction::UpdateFailHTLC { msg } => {
                                                                                                                encode_and_send_msg!(msg, 131);
                                                                                                                continue;
                                                                                                        },
-                                                                                                       msgs::ErrorAction::DisconnectPeer => {
+                                                                                                       msgs::ErrorAction::DisconnectPeer { msg: _ } => {
                                                                                                                return Err(PeerHandleError{ no_connection_possible: false });
                                                                                                        },
                                                                                                        msgs::ErrorAction::IgnoreError => {
                                                                                                                continue;
                                                                                                        },
+                                                                                                       msgs::ErrorAction::SendErrorMessage { msg } => {
+                                                                                                               encode_and_send_msg!(msg, 17);
+                                                                                                               continue;
+                                                                                                       },
                                                                                                }
                                                                                        } else {
                                                                                                return Err(PeerHandleError{ no_connection_possible: false });
@@ -609,11 +628,8 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                        Event::PaymentReceived {..} => { /* Hand upstream */ },
                                        Event::PaymentSent {..} => { /* Hand upstream */ },
                                        Event::PaymentFailed {..} => { /* Hand upstream */ },
+                                       Event::PendingHTLCsForwardable {..} => { /* Hand upstream */ },
 
-                                       Event::PendingHTLCsForwardable {..} => {
-                                               //TODO: Handle upstream in some confused form so that upstream just knows
-                                               //to call us somehow?
-                                       },
                                        Event::SendOpenChannel { ref node_id, ref msg } => {
                                                let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, {
                                                                //TODO: Drop the pending channel? (or just let it timeout, but that sucks)
@@ -672,6 +688,14 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                Self::do_attempt_write_data(&mut descriptor, peer);
                                                continue;
                                        },
+                                       Event::SendShutdown { ref node_id, ref msg } => {
+                                               let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, {
+                                                               //TODO: Do whatever we're gonna do for handling dropped messages
+                                                       });
+                                               peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 38)));
+                                               Self::do_attempt_write_data(&mut descriptor, peer);
+                                               continue;
+                                       },
                                        Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                                                if self.message_handler.route_handler.handle_channel_announcement(msg).is_ok() && self.message_handler.route_handler.handle_channel_update(update_msg).is_ok() {
                                                        let encoded_msg = encode_msg!(msg, 256);
@@ -710,6 +734,21 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                }
                                                continue;
                                        },
+                                       Event::DisconnectPeer { ref node_id, ref msg } => {
+                                               if let Some(mut descriptor) = peers.node_id_to_descriptor.remove(node_id) {
+                                                       if let Some(mut peer) = peers.peers.remove(&descriptor) {
+                                                               if let Some(ref msg) = *msg {
+                                                                       peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 17)));
+                                                                       // This isn't guaranteed to work, but if there is enough free
+                                                                       // room in the send buffer, put the error message there...
+                                                                       Self::do_attempt_write_data(&mut descriptor, &mut peer);
+                                                               }
+                                                       }
+                                                       descriptor.disconnect_socket();
+                                                       self.message_handler.chan_handler.peer_disconnected(&node_id, false);
+                                               }
+                                               continue;
+                                       },
                                }
 
                                upstream_events.push(event);
@@ -756,3 +795,83 @@ impl<Descriptor: SocketDescriptor> EventsProvider for PeerManager<Descriptor> {
                ret
        }
 }
+
+#[cfg(test)]
+mod tests {
+       use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor};
+       use util::events;
+       use util::test_utils;
+
+       use secp256k1::Secp256k1;
+       use secp256k1::key::{SecretKey, PublicKey};
+
+       use rand::{thread_rng, Rng};
+
+       use std::sync::{Arc};
+
+       #[derive(PartialEq, Eq, Clone, Hash)]
+       struct FileDescriptor {
+               fd: u16,
+       }
+
+       impl SocketDescriptor for FileDescriptor {
+               fn send_data(&mut self, data: &Vec<u8>, write_offset: usize, _resume_read: bool) -> usize {
+                       assert!(write_offset < data.len());
+                       data.len() - write_offset
+               }
+
+               fn disconnect_socket(&mut self) {}
+       }
+
+       fn create_network(peer_count: usize) -> Vec<PeerManager<FileDescriptor>> {
+               let secp_ctx = Secp256k1::new();
+               let mut peers = Vec::new();
+               let mut rng = thread_rng();
+
+               for _ in 0..peer_count {
+                       let chan_handler = test_utils::TestChannelMessageHandler::new();
+                       let router = test_utils::TestRoutingMessageHandler::new();
+                       let node_id = {
+                               let mut key_slice = [0;32];
+                               rng.fill_bytes(&mut key_slice);
+                               SecretKey::from_slice(&secp_ctx, &key_slice).unwrap()
+                       };
+                       let msg_handler = MessageHandler { chan_handler: Arc::new(chan_handler), route_handler: Arc::new(router) };
+                       let peer = PeerManager::new(msg_handler, node_id);
+                       peers.push(peer);
+               }
+
+               peers
+       }
+
+       fn establish_connection(peer_a: &PeerManager<FileDescriptor>, peer_b: &PeerManager<FileDescriptor>) {
+               let secp_ctx = Secp256k1::new();
+               let their_id = PublicKey::from_secret_key(&secp_ctx, &peer_b.our_node_secret).unwrap();
+               let fd = FileDescriptor { fd: 1};
+               peer_a.new_inbound_connection(fd.clone()).unwrap();
+               peer_a.peers.lock().unwrap().node_id_to_descriptor.insert(their_id, fd.clone());
+       }
+
+       #[test]
+       fn test_disconnect_peer() {
+               // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and
+               // push an DisconnectPeer event to remove the node flagged by id
+               let mut peers = create_network(2);
+               establish_connection(&peers[0], &peers[1]);
+               assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);
+
+               let secp_ctx = Secp256k1::new();
+               let their_id = PublicKey::from_secret_key(&secp_ctx, &peers[1].our_node_secret).unwrap();
+
+               let chan_handler = test_utils::TestChannelMessageHandler::new();
+               chan_handler.pending_events.lock().unwrap().push(events::Event::DisconnectPeer {
+                       node_id: their_id,
+                       msg: None,
+               });
+               assert_eq!(chan_handler.pending_events.lock().unwrap().len(), 1);
+               peers[0].message_handler.chan_handler = Arc::new(chan_handler);
+
+               peers[0].process_events();
+               assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 0);
+       }
+}
index e4473fa41838d87072d87cb13747c24f984cc442..bbd9cdadaf33279617b3173e383c220cbea2c800 100644 (file)
@@ -3,6 +3,7 @@ use secp256k1::{Secp256k1,Message};
 
 use bitcoin::util::hash::Sha256dHash;
 
+use ln::channelmanager;
 use ln::msgs::{ErrorAction,HandleError,RoutingMessageHandler,MsgEncodable,NetAddress,GlobalFeatures};
 use ln::msgs;
 
@@ -20,7 +21,7 @@ pub struct RouteHop {
        /// The fee taken on this hop. For the last hop, this should be the full value of the payment.
        pub fee_msat: u64,
        /// The CLTV delta added for this hop. For the last hop, this should be the full CLTV value
-       /// expected at the destination, NOT a delta.
+       /// expected at the destination, in excess of the current block height.
        pub cltv_expiry_delta: u32,
 }
 
@@ -110,7 +111,7 @@ macro_rules! secp_verify_sig {
        ( $secp_ctx: expr, $msg: expr, $sig: expr, $pubkey: expr ) => {
                match $secp_ctx.verify($msg, $sig, $pubkey) {
                        Ok(_) => {},
-                       Err(_) => return Err(HandleError{err: "Invalid signature from remote node", msg: None}),
+                       Err(_) => return Err(HandleError{err: "Invalid signature from remote node", action: None}),
                }
        };
 }
@@ -122,10 +123,10 @@ impl RoutingMessageHandler for Router {
 
                let mut network = self.network_map.write().unwrap();
                match network.nodes.get_mut(&msg.contents.node_id) {
-                       None => Err(HandleError{err: "No existing channels for node_announcement", msg: Some(ErrorAction::IgnoreError)}),
+                       None => Err(HandleError{err: "No existing channels for node_announcement", action: Some(ErrorAction::IgnoreError)}),
                        Some(node) => {
                                if node.last_update >= msg.contents.timestamp {
-                                       return Err(HandleError{err: "Update older than last processed update", msg: Some(ErrorAction::IgnoreError)});
+                                       return Err(HandleError{err: "Update older than last processed update", action: Some(ErrorAction::IgnoreError)});
                                }
 
                                node.features = msg.contents.features.clone();
@@ -149,7 +150,7 @@ impl RoutingMessageHandler for Router {
                //TODO: Only allow bitcoin chain_hash
 
                if msg.contents.features.requires_unknown_bits() {
-                       return Err(HandleError{err: "Channel announcement required unknown feature flags", msg: None});
+                       return Err(HandleError{err: "Channel announcement required unknown feature flags", action: None});
                }
 
                let mut network = self.network_map.write().unwrap();
@@ -159,7 +160,7 @@ impl RoutingMessageHandler for Router {
                                //TODO: because asking the blockchain if short_channel_id is valid is only optional
                                //in the blockchain API, we need to handle it smartly here, though its unclear
                                //exactly how...
-                               return Err(HandleError{err: "Already have knowledge of channel", msg: Some(ErrorAction::IgnoreError)})
+                               return Err(HandleError{err: "Already have knowledge of channel", action: Some(ErrorAction::IgnoreError)})
                        },
                        Entry::Vacant(entry) => {
                                entry.insert(ChannelInfo {
@@ -233,12 +234,12 @@ impl RoutingMessageHandler for Router {
                let chan_was_enabled;
 
                match network.channels.get_mut(&NetworkMap::get_key(msg.contents.short_channel_id, msg.contents.chain_hash)) {
-                       None => return Err(HandleError{err: "Couldn't find channel for update", msg: Some(ErrorAction::IgnoreError)}),
+                       None => return Err(HandleError{err: "Couldn't find channel for update", action: Some(ErrorAction::IgnoreError)}),
                        Some(channel) => {
                                macro_rules! maybe_update_channel_info {
                                        ( $target: expr) => {
                                                if $target.last_update >= msg.contents.timestamp {
-                                                       return Err(HandleError{err: "Update older than last processed update", msg: Some(ErrorAction::IgnoreError)});
+                                                       return Err(HandleError{err: "Update older than last processed update", action: Some(ErrorAction::IgnoreError)});
                                                }
                                                chan_was_enabled = $target.enabled;
                                                $target.last_update = msg.contents.timestamp;
@@ -315,6 +316,14 @@ impl cmp::PartialOrd for RouteGraphNode {
        }
 }
 
+struct DummyDirectionalChannelInfo {
+       src_node_id: PublicKey,
+       cltv_expiry_delta: u32,
+       htlc_minimum_msat: u64,
+       fee_base_msat: u32,
+       fee_proportional_millionths: u32,
+}
+
 impl Router {
        pub fn new(our_pubkey: PublicKey) -> Router {
                let mut nodes = HashMap::new();
@@ -338,6 +347,12 @@ impl Router {
                }
        }
 
+       /// Get network addresses by node id
+       pub fn get_addresses(&self, pubkey: &PublicKey) -> Option<Vec<NetAddress>> {
+               let network = self.network_map.read().unwrap();
+               network.nodes.get(pubkey).map(|n| n.addresses.clone())
+       }
+
        /// Marks a node as having failed a route. This will avoid re-using the node in routes for now,
        /// with an expotnential decay in node "badness". Note that there is deliberately no
        /// mark_channel_bad as a node may simply lie and suggest that an upstream channel from it is
@@ -351,16 +366,21 @@ impl Router {
        /// Gets a route from us to the given target node.
        /// Extra routing hops between known nodes and the target will be used if they are included in
        /// last_hops.
+       /// If some channels aren't announced, it may be useful to fill in a first_hops with the
+       /// results from a local ChannelManager::list_usable_channels() call. If it is filled in, our
+       /// (this Router's) view of our local channels will be ignored, and only those in first_hops
+       /// will be used. Panics if first_hops contains channels without short_channel_ids
+       /// (ChannelManager::list_usable_channels will never include such channels).
        /// The fees on channels from us to next-hops are ignored (as they are assumed to all be
        /// equal), however the enabled/disabled bit on such channels as well as the htlc_minimum_msat
        /// *is* checked as they may change based on the receiving node.
-       pub fn get_route(&self, target: &PublicKey, last_hops: &Vec<RouteHint>, final_value_msat: u64, final_cltv: u32) -> Result<Route, HandleError> {
+       pub fn get_route(&self, target: &PublicKey, first_hops: Option<&[channelmanager::ChannelDetails]>, last_hops: &[RouteHint], final_value_msat: u64, final_cltv: u32) -> Result<Route, HandleError> {
                // TODO: Obviously *only* using total fee cost sucks. We should consider weighting by
                // uptime/success in using a node in the past.
                let network = self.network_map.read().unwrap();
 
                if *target == network.our_node_id {
-                       return Err(HandleError{err: "Cannot generate a route to ourselves", msg: None});
+                       return Err(HandleError{err: "Cannot generate a route to ourselves", action: None});
                }
 
                // We do a dest-to-source Dijkstra's sorting by each node's distance from the destination
@@ -369,18 +389,36 @@ impl Router {
                // to use as the A* heuristic beyond just the cost to get one node further than the current
                // one.
 
+               let dummy_directional_info = DummyDirectionalChannelInfo { // used for first_hops routes
+                       src_node_id: network.our_node_id.clone(),
+                       cltv_expiry_delta: 0,
+                       htlc_minimum_msat: 0,
+                       fee_base_msat: 0,
+                       fee_proportional_millionths: 0,
+               };
+
                let mut targets = BinaryHeap::new(); //TODO: Do we care about switching to eg Fibbonaci heap?
                let mut dist = HashMap::with_capacity(network.nodes.len());
-               for (key, node) in network.nodes.iter() {
-                       dist.insert(key.clone(), (u64::max_value(),
-                               node.lowest_inbound_channel_fee_base_msat as u64,
-                               node.lowest_inbound_channel_fee_proportional_millionths as u64,
-                               RouteHop {
-                                       pubkey: PublicKey::new(),
-                                       short_channel_id: 0,
-                                       fee_msat: 0,
-                                       cltv_expiry_delta: 0,
-                       }));
+
+               let mut first_hop_targets = HashMap::with_capacity(if first_hops.is_some() { first_hops.as_ref().unwrap().len() } else { 0 });
+               if let Some(hops) = first_hops {
+                       for chan in hops {
+                               let short_channel_id = chan.short_channel_id.expect("first_hops should be filled in with usable channels, not pending ones");
+                               if chan.remote_network_id == *target {
+                                       return Ok(Route {
+                                               hops: vec![RouteHop {
+                                                       pubkey: chan.remote_network_id,
+                                                       short_channel_id,
+                                                       fee_msat: final_value_msat,
+                                                       cltv_expiry_delta: final_cltv,
+                                               }],
+                                       });
+                               }
+                               first_hop_targets.insert(chan.remote_network_id, short_channel_id);
+                       }
+                       if first_hop_targets.is_empty() {
+                               return Err(HandleError{err: "Cannot route when there are no outbound routes away from us", action: None});
+                       }
                }
 
                macro_rules! add_entry {
@@ -390,27 +428,43 @@ impl Router {
                        ( $chan_id: expr, $dest_node_id: expr, $directional_info: expr, $starting_fee_msat: expr ) => {
                                //TODO: Explore simply adding fee to hit htlc_minimum_msat
                                if $starting_fee_msat as u64 + final_value_msat > $directional_info.htlc_minimum_msat {
-                                       let new_fee = $directional_info.fee_base_msat as u64 + ($starting_fee_msat + final_value_msat) * ($directional_info.fee_proportional_millionths as u64) / 1000000;
-                                       let mut total_fee = $starting_fee_msat as u64;
-                                       let old_entry = dist.get_mut(&$directional_info.src_node_id).unwrap();
-                                       if $directional_info.src_node_id != network.our_node_id {
-                                               // Ignore new_fee for channel-from-us as we assume all channels-from-us
-                                               // will have the same effective-fee
-                                               total_fee += new_fee;
-                                               total_fee += old_entry.2 * (final_value_msat + total_fee) / 1000000 + old_entry.1;
-                                       }
-                                       let new_graph_node = RouteGraphNode {
-                                               pubkey: $directional_info.src_node_id,
-                                               lowest_fee_to_peer_through_node: total_fee,
-                                       };
-                                       if old_entry.0 > total_fee {
-                                               targets.push(new_graph_node);
-                                               old_entry.0 = total_fee;
-                                               old_entry.3 = RouteHop {
-                                                       pubkey: $dest_node_id.clone(),
-                                                       short_channel_id: $chan_id.clone(),
-                                                       fee_msat: new_fee, // This field is ignored on the last-hop anyway
-                                                       cltv_expiry_delta: $directional_info.cltv_expiry_delta as u32,
+                                       let proportional_fee_millions = ($starting_fee_msat + final_value_msat).checked_mul($directional_info.fee_proportional_millionths as u64);
+                                       if let Some(new_fee) = proportional_fee_millions.and_then(|part| {
+                                                       ($directional_info.fee_base_msat as u64).checked_add(part / 1000000) })
+                                       {
+                                               let mut total_fee = $starting_fee_msat as u64;
+                                               let mut hm_entry = dist.entry(&$directional_info.src_node_id);
+                                               let old_entry = hm_entry.or_insert_with(|| {
+                                                       let node = network.nodes.get(&$directional_info.src_node_id).unwrap();
+                                                       (u64::max_value(),
+                                                               node.lowest_inbound_channel_fee_base_msat as u64,
+                                                               node.lowest_inbound_channel_fee_proportional_millionths as u64,
+                                                               RouteHop {
+                                                                       pubkey: PublicKey::new(),
+                                                                       short_channel_id: 0,
+                                                                       fee_msat: 0,
+                                                                       cltv_expiry_delta: 0,
+                                                       })
+                                               });
+                                               if $directional_info.src_node_id != network.our_node_id {
+                                                       // Ignore new_fee for channel-from-us as we assume all channels-from-us
+                                                       // will have the same effective-fee
+                                                       total_fee += new_fee;
+                                                       total_fee += old_entry.2 * (final_value_msat + total_fee) / 1000000 + old_entry.1;
+                                               }
+                                               let new_graph_node = RouteGraphNode {
+                                                       pubkey: $directional_info.src_node_id,
+                                                       lowest_fee_to_peer_through_node: total_fee,
+                                               };
+                                               if old_entry.0 > total_fee {
+                                                       targets.push(new_graph_node);
+                                                       old_entry.0 = total_fee;
+                                                       old_entry.3 = RouteHop {
+                                                               pubkey: $dest_node_id.clone(),
+                                                               short_channel_id: $chan_id.clone(),
+                                                               fee_msat: new_fee, // This field is ignored on the last-hop anyway
+                                                               cltv_expiry_delta: $directional_info.cltv_expiry_delta as u32,
+                                                       }
                                                }
                                        }
                                }
@@ -419,16 +473,26 @@ impl Router {
 
                macro_rules! add_entries_to_cheapest_to_target_node {
                        ( $node: expr, $node_id: expr, $fee_to_target_msat: expr ) => {
+                               if first_hops.is_some() {
+                                       if let Some(first_hop) = first_hop_targets.get(&$node_id) {
+                                               add_entry!(first_hop, $node_id, dummy_directional_info, $fee_to_target_msat);
+                                       }
+                               }
+
                                for chan_id in $node.channels.iter() {
                                        let chan = network.channels.get(chan_id).unwrap();
                                        if chan.one_to_two.src_node_id == *$node_id {
                                                // ie $node is one, ie next hop in A* is two, via the two_to_one channel
-                                               if chan.two_to_one.enabled {
-                                                       add_entry!(chan_id, chan.one_to_two.src_node_id, chan.two_to_one, $fee_to_target_msat);
+                                               if first_hops.is_none() || chan.two_to_one.src_node_id != network.our_node_id {
+                                                       if chan.two_to_one.enabled {
+                                                               add_entry!(chan_id, chan.one_to_two.src_node_id, chan.two_to_one, $fee_to_target_msat);
+                                                       }
                                                }
                                        } else {
-                                               if chan.one_to_two.enabled {
-                                                       add_entry!(chan_id, chan.two_to_one.src_node_id, chan.one_to_two, $fee_to_target_msat);
+                                               if first_hops.is_none() || chan.one_to_two.src_node_id != network.our_node_id {
+                                                       if chan.one_to_two.enabled {
+                                                               add_entry!(chan_id, chan.two_to_one.src_node_id, chan.one_to_two, $fee_to_target_msat);
+                                                       }
                                                }
                                        }
                                }
@@ -443,8 +507,15 @@ impl Router {
                }
 
                for hop in last_hops.iter() {
-                       if network.nodes.get(&hop.src_node_id).is_some() {
-                               add_entry!(hop.short_channel_id, target, hop, 0);
+                       if first_hops.is_none() || hop.src_node_id != network.our_node_id { // first_hop overrules last_hops
+                               if network.nodes.get(&hop.src_node_id).is_some() {
+                                       if first_hops.is_some() {
+                                               if let Some(first_hop) = first_hop_targets.get(&hop.src_node_id) {
+                                                       add_entry!(first_hop, hop.src_node_id, dummy_directional_info, 0);
+                                               }
+                                       }
+                                       add_entry!(hop.short_channel_id, target, hop, 0);
+                               }
                        }
                }
 
@@ -474,12 +545,13 @@ impl Router {
                        }
                }
 
-               Err(HandleError{err: "Failed to find a path to the given destination", msg: None})
+               Err(HandleError{err: "Failed to find a path to the given destination", action: None})
        }
 }
 
 #[cfg(test)]
 mod tests {
+       use ln::channelmanager;
        use ln::router::{Router,NodeInfo,NetworkMap,ChannelInfo,DirectionalChannelInfo,RouteHint};
        use ln::msgs::GlobalFeatures;
 
@@ -497,25 +569,30 @@ mod tests {
 
                // Build network from our_id to node8:
                //
-               //        -1(1)2- node1 -1(3)2-
-               //       /                     \
-               // our_id                       - node3
-               //       \                     /
-               //        -1(2)2- node2 -1(4)2-
+               //        -1(1)2-  node1  -1(3)2-
+               //       /                       \
+               // our_id -1(12)2- node8 -1(13)2--- node3
+               //       \                       /
+               //        -1(2)2-  node2  -1(4)2-
+               //
                //
+               // chan1  1-to-2: disabled
+               // chan1  2-to-1: enabled, 0 fee
                //
-               // chan1 1-to-2: disabled
-               // chan1 2-to-1: enabled, 0 fee
+               // chan2  1-to-2: enabled, ignored fee
+               // chan 2-to-1: enabled, 0 fee
                //
-               // chan2 1-to-2: enabled, ignored fee
-               // chan2 2-to-1: enabled, 0 fee
+               // chan3  1-to-2: enabled, 0 fee
+               // chan3  2-to-1: enabled, 100 msat fee
                //
-               // chan3 1-to-2: enabled, 0 fee
-               // chan3 2-to-1: enabled, 100 msat fee
+               // chan4  1-to-2: enabled, 100% fee
+               // chan4  2-to-1: enabled, 0 fee
                //
-               // chan4 1-to-2: enabled, 100% fee
-               // chan4 2-to-1: enabled, 0 fee
+               // chan12 1-to-2: enabled, ignored fee
+               // chan12 2-to-1: enabled, 0 fee
                //
+               // chan13 1-to-2: enabled, 200% fee
+               // chan13 2-to-1: enabled, 0 fee
                //
                //
                //       -1(5)2- node4 -1(8)2--
@@ -554,6 +631,7 @@ mod tests {
                let node5 = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0606060606060606060606060606060606060606060606060606060606060606").unwrap()[..]).unwrap()).unwrap();
                let node6 = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0707070707070707070707070707070707070707070707070707070707070707").unwrap()[..]).unwrap()).unwrap();
                let node7 = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0808080808080808080808080808080808080808080808080808080808080808").unwrap()[..]).unwrap()).unwrap();
+               let node8 = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0909090909090909090909090909090909090909090909090909090909090909").unwrap()[..]).unwrap()).unwrap();
 
                let zero_hash = Sha256dHash::from_data(&[0; 32]);
 
@@ -620,10 +698,41 @@ mod tests {
                                        fee_proportional_millionths: 0,
                                },
                        });
+                       network.nodes.insert(node8.clone(), NodeInfo {
+                               channels: vec!(NetworkMap::get_key(12, zero_hash.clone()), NetworkMap::get_key(13, zero_hash.clone())),
+                               lowest_inbound_channel_fee_base_msat: 0,
+                               lowest_inbound_channel_fee_proportional_millionths: 0,
+                               features: GlobalFeatures::new(),
+                               last_update: 1,
+                               rgb: [0; 3],
+                               alias: [0; 32],
+                               addresses: Vec::new(),
+                       });
+                       network.channels.insert(NetworkMap::get_key(12, zero_hash.clone()), ChannelInfo {
+                               features: GlobalFeatures::new(),
+                               one_to_two: DirectionalChannelInfo {
+                                       src_node_id: our_id.clone(),
+                                       last_update: 0,
+                                       enabled: true,
+                                       cltv_expiry_delta: u16::max_value(), // This value should be ignored
+                                       htlc_minimum_msat: 0,
+                                       fee_base_msat: u32::max_value(), // This value should be ignored
+                                       fee_proportional_millionths: u32::max_value(), // This value should be ignored
+                               }, two_to_one: DirectionalChannelInfo {
+                                       src_node_id: node8.clone(),
+                                       last_update: 0,
+                                       enabled: true,
+                                       cltv_expiry_delta: 0,
+                                       htlc_minimum_msat: 0,
+                                       fee_base_msat: 0,
+                                       fee_proportional_millionths: 0,
+                               },
+                       });
                        network.nodes.insert(node3.clone(), NodeInfo {
                                channels: vec!(
                                        NetworkMap::get_key(3, zero_hash.clone()),
                                        NetworkMap::get_key(4, zero_hash.clone()),
+                                       NetworkMap::get_key(13, zero_hash.clone()),
                                        NetworkMap::get_key(5, zero_hash.clone()),
                                        NetworkMap::get_key(6, zero_hash.clone()),
                                        NetworkMap::get_key(7, zero_hash.clone())),
@@ -675,6 +784,26 @@ mod tests {
                                        fee_proportional_millionths: 0,
                                },
                        });
+                       network.channels.insert(NetworkMap::get_key(13, zero_hash.clone()), ChannelInfo {
+                               features: GlobalFeatures::new(),
+                               one_to_two: DirectionalChannelInfo {
+                                       src_node_id: node8.clone(),
+                                       last_update: 0,
+                                       enabled: true,
+                                       cltv_expiry_delta: (13 << 8) | 1,
+                                       htlc_minimum_msat: 0,
+                                       fee_base_msat: 0,
+                                       fee_proportional_millionths: 2000000,
+                               }, two_to_one: DirectionalChannelInfo {
+                                       src_node_id: node3.clone(),
+                                       last_update: 0,
+                                       enabled: true,
+                                       cltv_expiry_delta: (13 << 8) | 2,
+                                       htlc_minimum_msat: 0,
+                                       fee_base_msat: 0,
+                                       fee_proportional_millionths: 0,
+                               },
+                       });
                        network.nodes.insert(node4.clone(), NodeInfo {
                                channels: vec!(NetworkMap::get_key(5, zero_hash.clone()), NetworkMap::get_key(11, zero_hash.clone())),
                                lowest_inbound_channel_fee_base_msat: 0,
@@ -788,7 +917,7 @@ mod tests {
                }
 
                { // Simple route to 3 via 2
-                       let route = router.get_route(&node3, &Vec::new(), 100, 42).unwrap();
+                       let route = router.get_route(&node3, None, &Vec::new(), 100, 42).unwrap();
                        assert_eq!(route.hops.len(), 2);
 
                        assert_eq!(route.hops[0].pubkey, node2);
@@ -803,7 +932,7 @@ mod tests {
                }
 
                { // Route to 1 via 2 and 3 because our channel to 1 is disabled
-                       let route = router.get_route(&node1, &Vec::new(), 100, 42).unwrap();
+                       let route = router.get_route(&node1, None, &Vec::new(), 100, 42).unwrap();
                        assert_eq!(route.hops.len(), 3);
 
                        assert_eq!(route.hops[0].pubkey, node2);
@@ -822,6 +951,28 @@ mod tests {
                        assert_eq!(route.hops[2].cltv_expiry_delta, 42);
                }
 
+               { // If we specify a channel to node8, that overrides our local channel view and that gets used
+                       let our_chans = vec![channelmanager::ChannelDetails {
+                               channel_id: [0; 32],
+                               short_channel_id: Some(42),
+                               remote_network_id: node8.clone(),
+                               channel_value_satoshis: 0,
+                               user_id: 0,
+                       }];
+                       let route = router.get_route(&node3, Some(&our_chans), &Vec::new(), 100, 42).unwrap();
+                       assert_eq!(route.hops.len(), 2);
+
+                       assert_eq!(route.hops[0].pubkey, node8);
+                       assert_eq!(route.hops[0].short_channel_id, 42);
+                       assert_eq!(route.hops[0].fee_msat, 200);
+                       assert_eq!(route.hops[0].cltv_expiry_delta, (13 << 8) | 1);
+
+                       assert_eq!(route.hops[1].pubkey, node3);
+                       assert_eq!(route.hops[1].short_channel_id, 13);
+                       assert_eq!(route.hops[1].fee_msat, 100);
+                       assert_eq!(route.hops[1].cltv_expiry_delta, 42);
+               }
+
                let mut last_hops = vec!(RouteHint {
                                src_node_id: node4.clone(),
                                short_channel_id: 8,
@@ -846,7 +997,7 @@ mod tests {
                        });
 
                { // Simple test across 2, 3, 5, and 4 via a last_hop channel
-                       let route = router.get_route(&node7, &last_hops, 100, 42).unwrap();
+                       let route = router.get_route(&node7, None, &last_hops, 100, 42).unwrap();
                        assert_eq!(route.hops.len(), 5);
 
                        assert_eq!(route.hops[0].pubkey, node2);
@@ -875,10 +1026,32 @@ mod tests {
                        assert_eq!(route.hops[4].cltv_expiry_delta, 42);
                }
 
+               { // Simple test with outbound channel to 4 to test that last_hops and first_hops connect
+                       let our_chans = vec![channelmanager::ChannelDetails {
+                               channel_id: [0; 32],
+                               short_channel_id: Some(42),
+                               remote_network_id: node4.clone(),
+                               channel_value_satoshis: 0,
+                               user_id: 0,
+                       }];
+                       let route = router.get_route(&node7, Some(&our_chans), &last_hops, 100, 42).unwrap();
+                       assert_eq!(route.hops.len(), 2);
+
+                       assert_eq!(route.hops[0].pubkey, node4);
+                       assert_eq!(route.hops[0].short_channel_id, 42);
+                       assert_eq!(route.hops[0].fee_msat, 0);
+                       assert_eq!(route.hops[0].cltv_expiry_delta, (8 << 8) | 1);
+
+                       assert_eq!(route.hops[1].pubkey, node7);
+                       assert_eq!(route.hops[1].short_channel_id, 8);
+                       assert_eq!(route.hops[1].fee_msat, 100);
+                       assert_eq!(route.hops[1].cltv_expiry_delta, 42);
+               }
+
                last_hops[0].fee_base_msat = 1000;
 
                { // Revert to via 6 as the fee on 8 goes up
-                       let route = router.get_route(&node7, &last_hops, 100, 42).unwrap();
+                       let route = router.get_route(&node7, None, &last_hops, 100, 42).unwrap();
                        assert_eq!(route.hops.len(), 4);
 
                        assert_eq!(route.hops[0].pubkey, node2);
@@ -903,7 +1076,7 @@ mod tests {
                }
 
                { // ...but still use 8 for larger payments as 6 has a variable feerate
-                       let route = router.get_route(&node7, &last_hops, 2000, 42).unwrap();
+                       let route = router.get_route(&node7, None, &last_hops, 2000, 42).unwrap();
                        assert_eq!(route.hops.len(), 5);
 
                        assert_eq!(route.hops[0].pubkey, node2);
index 0c3332f996036cc20c945c32802f275a05312c51..e8330b7e29ba9877449bda22641f6faa726c737b 100644 (file)
@@ -2,7 +2,6 @@ use ln::msgs;
 use chain::transaction::OutPoint;
 
 use bitcoin::blockdata::script::Script;
-use bitcoin::util::uint::Uint256;
 
 use secp256k1::key::PublicKey;
 
@@ -14,7 +13,7 @@ pub enum Event {
        /// parameters and then call ChannelManager::funding_transaction_generated.
        /// Generated in ChannelManager message handling.
        FundingGenerationReady {
-               temporary_channel_id: Uint256,
+               temporary_channel_id: [u8; 32],
                channel_value_satoshis: u64,
                output_script: Script,
                /// The value passed in to ChannelManager::create_channel
@@ -47,13 +46,13 @@ pub enum Event {
        PaymentFailed {
                payment_hash: [u8; 32],
        },
-
-       // Events indicating the network loop should send a message to a peer:
        /// Used to indicate that ChannelManager::process_pending_htlc_forwards should be called at a
        /// time in the future.
        PendingHTLCsForwardable {
                time_forwardable: Instant,
        },
+
+       // Events indicating the network loop should send a message to a peer:
        /// Used to indicate that we've initialted a channel open and should send the open_channel
        /// message provided to the given peer
        SendOpenChannel {
@@ -90,6 +89,11 @@ pub enum Event {
                msg: msgs::UpdateFailHTLC,
                commitment_msg: msgs::CommitmentSigned,
        },
+       /// Used to indicate that a shutdown message should be sent to the peer with the given node_id.
+       SendShutdown {
+               node_id: PublicKey,
+               msg: msgs::Shutdown,
+       },
        /// Used to indicate that a channel_announcement and channel_update should be broadcast to all
        /// peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2).
        BroadcastChannelAnnouncement {
@@ -100,6 +104,13 @@ pub enum Event {
        BroadcastChannelUpdate {
                msg: msgs::ChannelUpdate,
        },
+
+       // Events indicating the network loop should change the state of connection with peer:
+       /// Disconnect the given peer, possibly making an attempt to send an ErrorMessage first.
+       DisconnectPeer  {
+               node_id: PublicKey,
+               msg: Option<msgs::ErrorMessage>,
+       }
 }
 
 pub trait EventsProvider {
index a39d288488d0a18e984296e106e358dedbab82cf..008a9e1d7e1e0649b4fe07d92f1f2e142751adcc 100644 (file)
@@ -1,4 +1,3 @@
-pub mod transaction_utils;
 pub mod events;
 
 pub(crate) mod byte_utils;
@@ -6,6 +5,7 @@ pub(crate) mod chacha20poly1305rfc;
 pub(crate) mod internal_traits;
 pub(crate) mod rng;
 pub(crate) mod sha2;
+pub(crate) mod transaction_utils;
 
 #[cfg(feature = "fuzztarget")]
 pub use self::rng::reset_rng_state;
index 818528b8e13e9f35c333c18769ea12dce4543b93..ae50154d95dea23b29d25c36aeff13372b4b101a 100644 (file)
@@ -1,16 +1,16 @@
 #[cfg(not(feature = "fuzztarget"))]
 mod real_rng {
        use rand::{thread_rng,Rng};
-       use bitcoin::util::uint::Uint256;
 
        pub fn fill_bytes(data: &mut [u8]) {
                let mut rng = thread_rng();
                rng.fill_bytes(data);
        }
 
-       pub fn rand_uint256() -> Uint256 {
-               let mut rng = thread_rng();
-               Uint256([rng.gen(), rng.gen(), rng.gen(), rng.gen()])
+       pub fn rand_u832() -> [u8; 32] {
+               let mut res = [0; 32];
+               fill_bytes(&mut res);
+               res
        }
 
        pub fn rand_f32() -> f32 {
@@ -23,7 +23,6 @@ pub use self::real_rng::*;
 
 #[cfg(feature = "fuzztarget")]
 mod fuzzy_rng {
-       use bitcoin::util::uint::Uint256;
        use util::byte_utils;
 
        static mut RNG_ITER: u64 = 0;
@@ -38,9 +37,15 @@ mod fuzzy_rng {
                data[off..].copy_from_slice(&byte_utils::be64_to_array(rng)[0..rem]);
        }
 
-       pub fn rand_uint256() -> Uint256 {
+       pub fn rand_u832() -> [u8; 32] {
                let rng = unsafe { RNG_ITER += 1; RNG_ITER - 1 };
-               Uint256([rng, rng, rng, rng])
+               let mut res = [0; 32];
+               let data = byte_utils::le64_to_array(rng);
+               res[8*0..8*1].copy_from_slice(&data);
+               res[8*1..8*2].copy_from_slice(&data);
+               res[8*2..8*3].copy_from_slice(&data);
+               res[8*3..8*4].copy_from_slice(&data);
+               res
        }
 
        pub fn rand_f32() -> f32 {
index 6647020f6b3d266d9b683796e9c76e1d75f13333..9646754f2d0097f51358cf5be9d86c8519acfcd4 100644 (file)
@@ -2,17 +2,23 @@ use chain::chaininterface;
 use chain::chaininterface::ConfirmationTarget;
 use chain::transaction::OutPoint;
 use ln::channelmonitor;
+use ln::msgs;
+use ln::msgs::{HandleError};
+use util::events;
 
 use bitcoin::blockdata::transaction::Transaction;
 
+use secp256k1::PublicKey;
+
 use std::sync::{Arc,Mutex};
+use std::{mem};
 
 pub struct TestFeeEstimator {
-       pub sat_per_vbyte: u64,
+       pub sat_per_kw: u64,
 }
 impl chaininterface::FeeEstimator for TestFeeEstimator {
-       fn get_est_sat_per_vbyte(&self, _confirmation_target: ConfirmationTarget) -> u64 {
-               self.sat_per_vbyte
+       fn get_est_sat_per_1000_weight(&self, _confirmation_target: ConfirmationTarget) -> u64 {
+               self.sat_per_kw
        }
 }
 
@@ -47,3 +53,95 @@ impl chaininterface::BroadcasterInterface for TestBroadcaster {
                self.txn_broadcasted.lock().unwrap().push(tx.clone());
        }
 }
+
+pub struct TestChannelMessageHandler {
+       pub pending_events: Mutex<Vec<events::Event>>,
+}
+
+impl TestChannelMessageHandler {
+       pub fn new() -> Self {
+               TestChannelMessageHandler {
+                       pending_events: Mutex::new(Vec::new()),
+               }
+       }
+}
+
+impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
+
+       fn handle_open_channel(&self, _their_node_id: &PublicKey, _msg: &msgs::OpenChannel) -> Result<msgs::AcceptChannel, HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_accept_channel(&self, _their_node_id: &PublicKey, _msg: &msgs::AcceptChannel) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_funding_created(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingCreated) -> Result<msgs::FundingSigned, HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_funding_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingSigned) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_funding_locked(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingLocked) -> Result<Option<msgs::AnnouncementSignatures>, HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_shutdown(&self, _their_node_id: &PublicKey, _msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_closing_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::ClosingSigned) -> Result<Option<msgs::ClosingSigned>, HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_update_add_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateAddHTLC) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_update_fulfill_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFulfillHTLC) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_update_fail_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFailHTLC) -> Result<Option<msgs::HTLCFailChannelUpdate>, HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_update_fail_malformed_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_commitment_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option<msgs::CommitmentSigned>), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_revoke_and_ack(&self, _their_node_id: &PublicKey, _msg: &msgs::RevokeAndACK) -> Result<Option<msgs::CommitmentUpdate>, HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_update_fee(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFee) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_announcement_signatures(&self, _their_node_id: &PublicKey, _msg: &msgs::AnnouncementSignatures) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
+}
+
+impl events::EventsProvider for TestChannelMessageHandler {
+       fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
+               let mut pending_events = self.pending_events.lock().unwrap();
+               let mut ret = Vec::new();
+               mem::swap(&mut ret, &mut *pending_events);
+               ret
+       }
+}
+
+pub struct TestRoutingMessageHandler {}
+
+impl TestRoutingMessageHandler {
+       pub fn new() -> Self {
+               TestRoutingMessageHandler {}
+       }
+}
+
+impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
+       fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<(), HandleError> {
+               Err(HandleError { err: "", action: None })
+       }
+       fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {}
+}