Merge pull request #1770 from jkczyz/2022-10-debug-route-hints
authorvalentinewallace <valentinewallace@users.noreply.github.com>
Fri, 21 Oct 2022 17:04:45 +0000 (13:04 -0400)
committerGitHub <noreply@github.com>
Fri, 21 Oct 2022 17:04:45 +0000 (13:04 -0400)
Add logging in route hint filtering

36 files changed:
fuzz/src/onion_message.rs
lightning-background-processor/src/lib.rs
lightning-block-sync/src/lib.rs
lightning-block-sync/src/poll.rs
lightning-invoice/src/lib.rs
lightning-rapid-gossip-sync/src/processing.rs
lightning/src/chain/chainmonitor.rs
lightning/src/chain/channelmonitor.rs
lightning/src/chain/keysinterface.rs
lightning/src/chain/mod.rs
lightning/src/chain/onchaintx.rs
lightning/src/chain/package.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/chanmon_update_fail_tests.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/msgs.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/script.rs
lightning/src/onion_message/functional_tests.rs
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/mod.rs
lightning/src/onion_message/packet.rs
lightning/src/routing/gossip.rs
lightning/src/routing/router.rs
lightning/src/routing/scoring.rs
lightning/src/util/chacha20poly1305rfc.rs
lightning/src/util/config.rs
lightning/src/util/enforcing_trait_impls.rs
lightning/src/util/errors.rs
lightning/src/util/events.rs
lightning/src/util/scid_utils.rs
lightning/src/util/ser.rs
lightning/src/util/ser_macros.rs
rustfmt.toml [new file with mode: 0644]

index a2fe88afc83d6af97896dbf06bb3326d0f66e659..27bf522c5896c71653c7603ead9b42a7bf1176e5 100644 (file)
@@ -10,12 +10,12 @@ use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
 use lightning::ln::script::ShutdownScript;
 use lightning::util::enforcing_trait_impls::EnforcingSigner;
 use lightning::util::logger::Logger;
-use lightning::util::ser::{Readable, Writer};
-use lightning::onion_message::OnionMessenger;
+use lightning::util::ser::{MaybeReadableArgs, Readable, Writeable, Writer};
+use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OnionMessenger};
 
 use utils::test_logger;
 
-use std::io::Cursor;
+use std::io::{self, Cursor};
 use std::sync::atomic::{AtomicU64, Ordering};
 
 #[inline]
@@ -29,7 +29,8 @@ pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
                        node_secret: secret,
                        counter: AtomicU64::new(0),
                };
-               let onion_messenger = OnionMessenger::new(&keys_manager, logger);
+               let custom_msg_handler = TestCustomMessageHandler {};
+               let onion_messenger = OnionMessenger::new(&keys_manager, logger, &custom_msg_handler);
                let mut pk = [2; 33]; pk[1] = 0xff;
                let peer_node_id_not_used = PublicKey::from_slice(&pk).unwrap();
                onion_messenger.handle_onion_message(&peer_node_id_not_used, &msg);
@@ -49,6 +50,38 @@ pub extern "C" fn onion_message_run(data: *const u8, datalen: usize) {
        do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, &logger);
 }
 
+struct TestCustomMessage {}
+
+const CUSTOM_MESSAGE_TYPE: u64 = 4242;
+const CUSTOM_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
+
+impl CustomOnionMessageContents for TestCustomMessage {
+       fn tlv_type(&self) -> u64 {
+               CUSTOM_MESSAGE_TYPE
+       }
+}
+
+impl Writeable for TestCustomMessage {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               Ok(CUSTOM_MESSAGE_CONTENTS.write(w)?)
+       }
+}
+
+impl MaybeReadableArgs<u64> for TestCustomMessage {
+       fn read<R: io::Read>(buffer: &mut R, _message_type: u64,) -> Result<Option<Self>, DecodeError> where Self: Sized {
+               let mut buf = Vec::new();
+               buffer.read_to_end(&mut buf)?;
+               return Ok(Some(TestCustomMessage {}))
+       }
+}
+
+struct TestCustomMessageHandler {}
+
+impl CustomOnionMessageHandler for TestCustomMessageHandler {
+       type CustomMessage = TestCustomMessage;
+       fn handle_custom_message(&self, _msg: Self::CustomMessage) {}
+}
+
 pub struct VecWriter(pub Vec<u8>);
 impl Writer for VecWriter {
        fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
@@ -117,36 +150,37 @@ mod tests {
 
        #[test]
        fn test_no_onion_message_breakage() {
-               let one_hop_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e01120410950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000";
+               let one_hop_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0136041095000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000";
                let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
                super::do_test(&::hex::decode(one_hop_om).unwrap(), &logger);
                {
                        let log_entries = logger.lines.lock().unwrap();
-                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Received an onion message with path_id: None and no reply_path".to_string())), Some(&1));
+                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
+                                               "Received an onion message with path_id None and no reply_path".to_string())), Some(&1));
                }
 
-               let two_unblinded_hops_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210200000000000000000000000000000000000000000000000000000000000000039500000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000001204105e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000";
+               let two_unblinded_hops_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210200000000000000000000000000000000000000000000000000000000000000029500000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003604104b000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000";
                let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
                super::do_test(&::hex::decode(two_unblinded_hops_om).unwrap(), &logger);
                {
                        let log_entries = logger.lines.lock().unwrap();
-                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000003".to_string())), Some(&1));
+                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000002".to_string())), Some(&1));
                }
 
-               let two_unblinded_two_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e01350433042102000000000000000000000000000000000000000000000000000000000000000395000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000058045604210200000000000000000000000000000000000000000000000000000000000000040821020000000000000000000000000000000000000000000000000000000000000e015e0000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000035043304210200000000000000000000000000000000000000000000000000000000000000054b000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000120410ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000";
+               let two_unblinded_two_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e01350433042102000000000000000000000000000000000000000000000000000000000000000295000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000058045604210200000000000000000000000000000000000000000000000000000000000000020821020000000000000000000000000000000000000000000000000000000000000e014b000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000035043304210200000000000000000000000000000000000000000000000000000000000000029500000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003604104b000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000";
                let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
                super::do_test(&::hex::decode(two_unblinded_two_blinded_om).unwrap(), &logger);
                {
                        let log_entries = logger.lines.lock().unwrap();
-                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000003".to_string())), Some(&1));
+                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000002".to_string())), Some(&1));
                }
 
-               let three_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e013504330421020000000000000000000000000000000000000000000000000000000000000003950000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000035043304210200000000000000000000000000000000000000000000000000000000000000045e0000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000001204104a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000";
+               let three_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e013504330421020000000000000000000000000000000000000000000000000000000000000002950000000000000000000000000000006c0000000000000000000000000000000000000000000000000000000000000035043304210200000000000000000000000000000000000000000000000000000000000000024b000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000360410d1000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000";
                let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
                super::do_test(&::hex::decode(three_blinded_om).unwrap(), &logger);
                {
                        let log_entries = logger.lines.lock().unwrap();
-                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000003".to_string())), Some(&1));
+                       assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000002".to_string())), Some(&1));
                }
        }
 }
index 055b5ca6f9937d70cc5b3e76babd9b8778a6b7cc..27cd0663e3291f27e385787d99769553c012de80 100644 (file)
@@ -609,7 +609,7 @@ mod tests {
 
        const EVENT_DEADLINE: u64 = 5 * FRESHNESS_TIMER;
 
-       #[derive(Clone, Eq, Hash, PartialEq)]
+       #[derive(Clone, Hash, PartialEq, Eq)]
        struct TestDescriptor{}
        impl SocketDescriptor for TestDescriptor {
                fn send_data(&mut self, _data: &[u8], _resume_read: bool) -> usize {
index 5d8bc27f8d141c2dcaaad9f1f53f97a25daa1cb0..189a68be0654dab1453ef459d3046d5d0001c17d 100644 (file)
@@ -98,7 +98,7 @@ pub struct BlockSourceError {
 }
 
 /// The kind of `BlockSourceError`, either persistent or transient.
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum BlockSourceErrorKind {
        /// Indicates an error that won't resolve when retrying a request (e.g., invalid data).
        Persistent,
@@ -139,7 +139,7 @@ impl BlockSourceError {
 
 /// A block header and some associated data. This information should be available from most block
 /// sources (and, notably, is available in Bitcoin Core's RPC and REST interfaces).
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub struct BlockHeaderData {
        /// The block header itself.
        pub header: BlockHeader,
index 2bb2f4a07df9e4a0aa79759249d795cc81cd833d..05ccd4504fde0d81a76646d91b44d9b2b1653711 100644 (file)
@@ -4,6 +4,7 @@ use crate::{AsyncBlockSourceResult, BlockData, BlockHeaderData, BlockSource, Blo
 
 use bitcoin::hash_types::BlockHash;
 use bitcoin::network::constants::Network;
+use lightning::chain::BestBlock;
 
 use std::ops::Deref;
 
@@ -29,7 +30,7 @@ pub trait Poll {
 }
 
 /// A chain tip relative to another chain tip in terms of block hash and chainwork.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum ChainTip {
        /// A chain tip with the same hash as another chain's tip.
        Common,
@@ -102,7 +103,7 @@ impl Validate for BlockData {
 }
 
 /// A block header with validated proof of work and corresponding block hash.
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub struct ValidatedBlockHeader {
        pub(crate) block_hash: BlockHash,
        inner: BlockHeaderData,
@@ -146,6 +147,19 @@ impl ValidatedBlockHeader {
 
                Ok(())
        }
+
+    /// Returns the [`BestBlock`] corresponding to this validated block header, which can be passed
+    /// into [`ChannelManager::new`] as part of its [`ChainParameters`]. Useful for ensuring that
+    /// the [`SpvClient`] and [`ChannelManager`] are initialized to the same block during a fresh
+    /// start.
+    ///
+    /// [`SpvClient`]: crate::SpvClient
+    /// [`ChainParameters`]: lightning::ln::channelmanager::ChainParameters
+    /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
+    /// [`ChannelManager::new`]: lightning::ln::channelmanager::ChannelManager::new
+    pub fn to_best_block(&self) -> BestBlock {
+        BestBlock::new(self.block_hash, self.inner.height)
+    }
 }
 
 /// A block with validated data against its transaction list and corresponding block hash.
index 9457d8ae6cc1ccf206df675030c9fc5b57a31160..5aacf53966c59a075e602ad059237b24eac51753 100644 (file)
@@ -101,7 +101,7 @@ mod sync;
 /// Errors that indicate what is wrong with the invoice. They have some granularity for debug
 /// reasons, but should generally result in an "invalid BOLT11 invoice" message for the user.
 #[allow(missing_docs)]
-#[derive(PartialEq, Debug, Clone)]
+#[derive(PartialEq, Eq, Debug, Clone)]
 pub enum ParseError {
        Bech32Error(bech32::Error),
        ParseAmountError(ParseIntError),
@@ -129,7 +129,7 @@ pub enum ParseError {
 /// Indicates that something went wrong while parsing or validating the invoice. Parsing errors
 /// should be mostly seen as opaque and are only there for debugging reasons. Semantic errors
 /// like wrong signatures, missing fields etc. could mean that someone tampered with the invoice.
-#[derive(PartialEq, Debug, Clone)]
+#[derive(PartialEq, Eq, Debug, Clone)]
 pub enum ParseOrSemanticError {
        /// The invoice couldn't be decoded
        ParseError(ParseError),
index 3a60b7c986c85354ee5789f8dadeaf3f3e6d519f..1a46ef587afad0ef28d90d95ead951e1d1f8f69e 100644 (file)
@@ -194,7 +194,13 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
                                synthetic_update.htlc_maximum_msat = htlc_maximum_msat;
                        }
 
-                       network_graph.update_channel_unsigned(&synthetic_update)?;
+                       match network_graph.update_channel_unsigned(&synthetic_update) {
+                               Ok(_) => {},
+                               Err(LightningError { action: ErrorAction::IgnoreDuplicateGossip, .. }) => {},
+                               Err(LightningError { action: ErrorAction::IgnoreAndLog(_), .. }) => {},
+                               Err(LightningError { action: ErrorAction::IgnoreError, .. }) => {},
+                               Err(e) => return Err(e.into()),
+                       }
                }
 
                self.network_graph.set_last_rapid_gossip_sync_timestamp(latest_seen_timestamp);
@@ -435,6 +441,50 @@ mod tests {
                assert!(after.contains("783241506229452801"));
        }
 
+       #[test]
+       fn update_succeeds_when_duplicate_gossip_is_applied() {
+               let initialization_input = vec![
+                       76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
+                       79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
+                       0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
+                       187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
+                       157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
+                       88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
+                       204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
+                       181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
+                       110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
+                       76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
+                       226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 4, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 3, 232,
+                       0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
+                       0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 25, 0, 0, 0, 1, 0, 0, 0, 125, 255, 2,
+                       68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
+                       25, 192,
+               ];
+
+               let block_hash = genesis_block(Network::Bitcoin).block_hash();
+               let logger = TestLogger::new();
+               let network_graph = NetworkGraph::new(block_hash, &logger);
+
+               assert_eq!(network_graph.read_only().channels().len(), 0);
+
+               let rapid_sync = RapidGossipSync::new(&network_graph);
+               let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
+               assert!(initialization_result.is_ok());
+
+               let single_direction_incremental_update_input = vec![
+                       76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
+                       79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 136, 0, 0, 0, 221, 255, 2,
+                       68, 226, 0, 6, 11, 0, 1, 128,
+               ];
+               let update_result_1 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
+               // Apply duplicate update
+               let update_result_2 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
+               assert!(update_result_1.is_ok());
+               assert!(update_result_2.is_ok());
+       }
+
        #[test]
        fn full_update_succeeds() {
                let valid_input = vec![
index 2479e8f7e7b5efd00582d2e9aaac7ecd9cfa9f31..3949810bf3ef33da01c3bbbd9b1cce0a1cfe65fc 100644 (file)
@@ -707,6 +707,7 @@ impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> even
              L::Target: Logger,
              P::Target: Persist<ChannelSigner>,
 {
+       #[cfg(not(anchors))]
        /// Processes [`SpendableOutputs`] events produced from each [`ChannelMonitor`] upon maturity.
        ///
        /// An [`EventHandler`] may safely call back to the provider, though this shouldn't be needed in
@@ -722,6 +723,29 @@ impl<ChannelSigner: Sign, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref> even
                        handler.handle_event(&event);
                }
        }
+       #[cfg(anchors)]
+       /// Processes [`SpendableOutputs`] events produced from each [`ChannelMonitor`] upon maturity.
+       ///
+       /// For channels featuring anchor outputs, this method will also process [`BumpTransaction`]
+       /// events produced from each [`ChannelMonitor`] while there is a balance to claim onchain
+       /// within each channel. As the confirmation of a commitment transaction may be critical to the
+       /// safety of funds, this method must be invoked frequently, ideally once for every chain tip
+       /// update (block connected or disconnected).
+       ///
+       /// An [`EventHandler`] may safely call back to the provider, though this shouldn't be needed in
+       /// order to handle these events.
+       ///
+       /// [`SpendableOutputs`]: events::Event::SpendableOutputs
+       /// [`BumpTransaction`]: events::Event::BumpTransaction
+       fn process_pending_events<H: Deref>(&self, handler: H) where H::Target: EventHandler {
+               let mut pending_events = Vec::new();
+               for monitor_state in self.monitors.read().unwrap().values() {
+                       pending_events.append(&mut monitor_state.monitor.get_and_clear_pending_events());
+               }
+               for event in pending_events.drain(..) {
+                       handler.handle_event(&event);
+               }
+       }
 }
 
 #[cfg(test)]
index 8f8cbdf448adb80d7fa50ee279c86862c1d0abd6..7c6b48d144b79b06c67105cc50d609f238b7581f 100644 (file)
@@ -21,8 +21,7 @@
 //! ChannelMonitors to get out of the HSM and onto monitoring devices.
 
 use bitcoin::blockdata::block::BlockHeader;
-use bitcoin::blockdata::transaction::{TxOut,Transaction};
-use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
+use bitcoin::blockdata::transaction::{OutPoint as BitcoinOutPoint, TxOut, Transaction};
 use bitcoin::blockdata::script::{Script, Builder};
 use bitcoin::blockdata::opcodes;
 
@@ -44,6 +43,8 @@ use chain::{BestBlock, WatchedOutput};
 use chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
 use chain::transaction::{OutPoint, TransactionData};
 use chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, Sign, KeysInterface};
+#[cfg(anchors)]
+use chain::onchaintx::ClaimEvent;
 use chain::onchaintx::OnchainTxHandler;
 use chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
 use chain::Filter;
@@ -51,6 +52,8 @@ use util::logger::Logger;
 use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48, OptionDeserWrapper};
 use util::byte_utils;
 use util::events::Event;
+#[cfg(anchors)]
+use util::events::{AnchorDescriptor, BumpTransactionEvent};
 
 use prelude::*;
 use core::{cmp, mem};
@@ -66,7 +69,7 @@ use sync::Mutex;
 /// much smaller than a full [`ChannelMonitor`]. However, for large single commitment transaction
 /// updates (e.g. ones during which there are hundreds of HTLCs pending on the commitment
 /// transaction), a single update may reach upwards of 1 MiB in serialized size.
-#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq, Eq))]
 #[derive(Clone)]
 #[must_use]
 pub struct ChannelMonitorUpdate {
@@ -125,7 +128,7 @@ impl Readable for ChannelMonitorUpdate {
 }
 
 /// An event to be processed by the ChannelManager.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub enum MonitorEvent {
        /// A monitor event containing an HTLCUpdate.
        HTLCEvent(HTLCUpdate),
@@ -170,7 +173,7 @@ impl_writeable_tlv_based_enum_upgradable!(MonitorEvent,
 /// Simple structure sent back by `chain::Watch` when an HTLC from a forward channel is detected on
 /// chain. Used to update the corresponding HTLC in the backward channel. Failing to pass the
 /// preimage claim backward will lead to loss of funds.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub struct HTLCUpdate {
        pub(crate) payment_hash: PaymentHash,
        pub(crate) payment_preimage: Option<PaymentPreimage>,
@@ -236,7 +239,7 @@ pub const ANTI_REORG_DELAY: u32 = 6;
 pub(crate) const HTLC_FAIL_BACK_BUFFER: u32 = CLTV_CLAIM_BUFFER + LATENCY_GRACE_PERIOD_BLOCKS;
 
 // TODO(devrandom) replace this with HolderCommitmentTransaction
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 struct HolderSignedTx {
        /// txid of the transaction in tx, just used to make comparison faster
        txid: Txid,
@@ -263,9 +266,23 @@ impl_writeable_tlv_based!(HolderSignedTx, {
        (14, htlc_outputs, vec_type)
 });
 
+#[cfg(anchors)]
+impl HolderSignedTx {
+       fn non_dust_htlcs(&self) -> Vec<HTLCOutputInCommitment> {
+               self.htlc_outputs.iter().filter_map(|(htlc, _, _)| {
+                       if let Some(_) = htlc.transaction_output_index {
+                               Some(htlc.clone())
+                       } else {
+                               None
+                       }
+               })
+               .collect()
+       }
+}
+
 /// We use this to track static counterparty commitment transaction data and to generate any
 /// justice or 2nd-stage preimage/timeout transactions.
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 struct CounterpartyCommitmentParameters {
        counterparty_delayed_payment_base_key: PublicKey,
        counterparty_htlc_base_key: PublicKey,
@@ -319,7 +336,7 @@ impl Readable for CounterpartyCommitmentParameters {
 /// transaction causing it.
 ///
 /// Used to determine when the on-chain event can be considered safe from a chain reorganization.
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 struct OnchainEventEntry {
        txid: Txid,
        height: u32,
@@ -361,7 +378,7 @@ type CommitmentTxCounterpartyOutputInfo = Option<(u32, u64)>;
 
 /// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it
 /// once they mature to enough confirmations (ANTI_REORG_DELAY)
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 enum OnchainEvent {
        /// An outbound HTLC failing after a transaction is confirmed. Used
        ///  * when an outbound HTLC output is spent by us after the HTLC timed out
@@ -471,7 +488,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
 
 );
 
-#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq, Eq))]
 #[derive(Clone)]
 pub(crate) enum ChannelMonitorUpdateStep {
        LatestHolderCommitmentTXInfo {
@@ -619,7 +636,7 @@ pub enum Balance {
 }
 
 /// An HTLC which has been irrevocably resolved on-chain, and has reached ANTI_REORG_DELAY.
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 struct IrrevocablyResolvedHTLC {
        commitment_tx_output_idx: Option<u32>,
        /// The txid of the transaction which resolved the HTLC, this may be a commitment (if the HTLC
@@ -1221,7 +1238,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                B::Target: BroadcasterInterface,
                L::Target: Logger,
        {
-               self.inner.lock().unwrap().broadcast_latest_holder_commitment_txn(broadcaster, logger)
+               self.inner.lock().unwrap().broadcast_latest_holder_commitment_txn(broadcaster, logger);
        }
 
        /// Updates a ChannelMonitor on the basis of some new information provided by the Channel
@@ -2222,6 +2239,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!");
                }
                let mut ret = Ok(());
+               let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
                for update in updates.updates.iter() {
                        match update {
                                ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs } => {
@@ -2239,7 +2257,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                },
                                ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => {
                                        log_trace!(logger, "Updating ChannelMonitor with payment preimage");
-                                       let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
                                        self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()), &payment_preimage, broadcaster, &bounded_fee_estimator, logger)
                                },
                                ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => {
@@ -2255,6 +2272,25 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        self.lockdown_from_offchain = true;
                                        if *should_broadcast {
                                                self.broadcast_latest_holder_commitment_txn(broadcaster, logger);
+                                               // If the channel supports anchor outputs, we'll need to emit an external
+                                               // event to be consumed such that a child transaction is broadcast with a
+                                               // high enough feerate for the parent commitment transaction to confirm.
+                                               if self.onchain_tx_handler.opt_anchors() {
+                                                       let funding_output = HolderFundingOutput::build(
+                                                               self.funding_redeemscript.clone(), self.channel_value_satoshis,
+                                                               self.onchain_tx_handler.opt_anchors(),
+                                                       );
+                                                       let best_block_height = self.best_block.height();
+                                                       let commitment_package = PackageTemplate::build_package(
+                                                               self.funding_info.0.txid.clone(), self.funding_info.0.index as u32,
+                                                               PackageSolvingData::HolderFundingOutput(funding_output),
+                                                               best_block_height, false, best_block_height,
+                                                       );
+                                                       self.onchain_tx_handler.update_claims_view(
+                                                               &[], vec![commitment_package], best_block_height, best_block_height,
+                                                               broadcaster, &bounded_fee_estimator, logger,
+                                                       );
+                                               }
                                        } else if !self.holder_tx_signed {
                                                log_error!(logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast");
                                                log_error!(logger, "    in channel monitor for channel {}!", log_bytes!(self.funding_info.0.to_channel_id()));
@@ -2309,6 +2345,34 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        pub fn get_and_clear_pending_events(&mut self) -> Vec<Event> {
                let mut ret = Vec::new();
                mem::swap(&mut ret, &mut self.pending_events);
+               #[cfg(anchors)]
+               for claim_event in self.onchain_tx_handler.get_and_clear_pending_claim_events().drain(..) {
+                       match claim_event {
+                               ClaimEvent::BumpCommitment {
+                                       package_target_feerate_sat_per_1000_weight, commitment_tx, anchor_output_idx,
+                               } => {
+                                       let commitment_txid = commitment_tx.txid();
+                                       debug_assert_eq!(self.current_holder_commitment_tx.txid, commitment_txid);
+                                       let pending_htlcs = self.current_holder_commitment_tx.non_dust_htlcs();
+                                       let commitment_tx_fee_satoshis = self.channel_value_satoshis -
+                                               commitment_tx.output.iter().fold(0u64, |sum, output| sum + output.value);
+                                       ret.push(Event::BumpTransaction(BumpTransactionEvent::ChannelClose {
+                                               package_target_feerate_sat_per_1000_weight,
+                                               commitment_tx,
+                                               commitment_tx_fee_satoshis,
+                                               anchor_descriptor: AnchorDescriptor {
+                                                       channel_keys_id: self.channel_keys_id,
+                                                       channel_value_satoshis: self.channel_value_satoshis,
+                                                       outpoint: BitcoinOutPoint {
+                                                               txid: commitment_txid,
+                                                               vout: anchor_output_idx,
+                                                       },
+                                               },
+                                               pending_htlcs,
+                                       }));
+                               },
+                       }
+               }
                ret
        }
 
@@ -2521,13 +2585,13 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                        CounterpartyOfferedHTLCOutput::build(*per_commitment_point,
                                                                self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
                                                                self.counterparty_commitment_params.counterparty_htlc_base_key,
-                                                               preimage.unwrap(), htlc.clone()))
+                                                               preimage.unwrap(), htlc.clone(), self.onchain_tx_handler.opt_anchors()))
                                        } else {
                                                PackageSolvingData::CounterpartyReceivedHTLCOutput(
                                                        CounterpartyReceivedHTLCOutput::build(*per_commitment_point,
                                                                self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
                                                                self.counterparty_commitment_params.counterparty_htlc_base_key,
-                                                               htlc.clone()))
+                                                               htlc.clone(), self.onchain_tx_handler.opt_anchors()))
                                        };
                                        let aggregation = if !htlc.offered { false } else { true };
                                        let counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry,aggregation, 0);
@@ -2826,7 +2890,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                        self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
                                                txid,
                                                transaction: Some((*tx).clone()),
-                                               height: height,
+                                               height,
                                                event: OnchainEvent::FundingSpendConfirmation {
                                                        on_local_output_csv: balance_spendable_csv,
                                                        commitment_tx_to_counterparty_output,
@@ -2884,21 +2948,26 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                let should_broadcast = self.should_broadcast_holder_commitment_txn(logger);
                if should_broadcast {
-                       let funding_outp = HolderFundingOutput::build(self.funding_redeemscript.clone());
+                       let funding_outp = HolderFundingOutput::build(self.funding_redeemscript.clone(), self.channel_value_satoshis, self.onchain_tx_handler.opt_anchors());
                        let commitment_package = PackageTemplate::build_package(self.funding_info.0.txid.clone(), self.funding_info.0.index as u32, PackageSolvingData::HolderFundingOutput(funding_outp), self.best_block.height(), false, self.best_block.height());
                        claimable_outpoints.push(commitment_package);
                        self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0));
                        let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
                        self.holder_tx_signed = true;
-                       // Because we're broadcasting a commitment transaction, we should construct the package
-                       // assuming it gets confirmed in the next block. Sadly, we have code which considers
-                       // "not yet confirmed" things as discardable, so we cannot do that here.
-                       let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height());
-                       let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &commitment_tx);
-                       if !new_outputs.is_empty() {
-                               watch_outputs.push((self.current_holder_commitment_tx.txid.clone(), new_outputs));
+                       // We can't broadcast our HTLC transactions while the commitment transaction is
+                       // unconfirmed. We'll delay doing so until we detect the confirmed commitment in
+                       // `transactions_confirmed`.
+                       if !self.onchain_tx_handler.opt_anchors() {
+                               // Because we're broadcasting a commitment transaction, we should construct the package
+                               // assuming it gets confirmed in the next block. Sadly, we have code which considers
+                               // "not yet confirmed" things as discardable, so we cannot do that here.
+                               let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height());
+                               let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &commitment_tx);
+                               if !new_outputs.is_empty() {
+                                       watch_outputs.push((self.current_holder_commitment_tx.txid.clone(), new_outputs));
+                               }
+                               claimable_outpoints.append(&mut new_outpoints);
                        }
-                       claimable_outpoints.append(&mut new_outpoints);
                }
 
                // Find which on-chain events have reached their confirmation threshold.
@@ -3418,7 +3487,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                        let entry = OnchainEventEntry {
                                txid: tx.txid(),
                                transaction: Some(tx.clone()),
-                               height: height,
+                               height,
                                event: OnchainEvent::MaturingOutput { descriptor: spendable_output.clone() },
                        };
                        log_info!(logger, "Received spendable output {}, spendable at height {}", log_spendable!(spendable_output), entry.confirmation_threshold());
index 73b8a1b98224ace7aef2f6db05a82ca2a020e476..1c64a8bccdfbe4953b6944cb9b9bbc4115b18f4e 100644 (file)
@@ -36,6 +36,7 @@ use util::crypto::{hkdf_extract_expand_twice, sign};
 use util::ser::{Writeable, Writer, Readable, ReadableArgs};
 
 use chain::transaction::OutPoint;
+use ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
 use ln::{chan_utils, PaymentPreimage};
 use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
 use ln::msgs::UnsignedChannelAnnouncement;
@@ -55,7 +56,7 @@ pub struct KeyMaterial(pub [u8; 32]);
 
 /// Information about a spendable output to a P2WSH script. See
 /// SpendableOutputDescriptor::DelayedPaymentOutput for more details on how to spend this.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct DelayedPaymentOutputDescriptor {
        /// The outpoint which is spendable
        pub outpoint: OutPoint,
@@ -95,7 +96,7 @@ impl_writeable_tlv_based!(DelayedPaymentOutputDescriptor, {
 
 /// Information about a spendable output to our "payment key". See
 /// SpendableOutputDescriptor::StaticPaymentOutput for more details on how to spend this.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct StaticPaymentOutputDescriptor {
        /// The outpoint which is spendable
        pub outpoint: OutPoint,
@@ -126,7 +127,7 @@ impl_writeable_tlv_based!(StaticPaymentOutputDescriptor, {
 /// spend on-chain. The information needed to do this is provided in this enum, including the
 /// outpoint describing which txid and output index is available, the full output which exists at
 /// that txid/index, and any keys or other information required to sign.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum SpendableOutputDescriptor {
        /// An output to a script which was provided via KeysInterface directly, either from
        /// `get_destination_script()` or `get_shutdown_scriptpubkey()`, thus you should already know
@@ -348,6 +349,12 @@ pub trait BaseSign {
        /// chosen to forgo their output as dust.
        fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
 
+       /// Computes the signature for a commitment transaction's anchor output used as an
+       /// input within `anchor_tx`, which spends the commitment transaction, at index `input`.
+       fn sign_holder_anchor_input(
+               &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
+       ) -> Result<Signature, ()>;
+
        /// Signs a channel announcement message with our funding key and our node secret key (aka
        /// node_id or network_key), proving it comes from one of the channel participants.
        ///
@@ -645,6 +652,7 @@ impl InMemorySigner {
                witness.push(witness_script.clone().into_bytes());
                Ok(witness)
        }
+
 }
 
 impl BaseSign for InMemorySigner {
@@ -762,6 +770,16 @@ impl BaseSign for InMemorySigner {
                Ok(closing_tx.trust().sign(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
        }
 
+       fn sign_holder_anchor_input(
+               &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
+       ) -> Result<Signature, ()> {
+               let witness_script = chan_utils::get_anchor_redeemscript(&self.holder_channel_pubkeys.funding_pubkey);
+               let sighash = sighash::SighashCache::new(&*anchor_tx).segwit_signature_hash(
+                       input, &witness_script, ANCHOR_OUTPUT_VALUE_SATOSHI, EcdsaSighashType::All,
+               ).unwrap();
+               Ok(sign(secp_ctx, &hash_to_message!(&sighash[..]), &self.funding_key))
+       }
+
        fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
        -> Result<(Signature, Signature), ()> {
                let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
index c54f9b1d7eba6814cb831bfd3c91c112fcc096cf..bb80440d116a5a11286c41745d9b55e2c07137a5 100644 (file)
@@ -32,7 +32,7 @@ pub(crate) mod onchaintx;
 pub(crate) mod package;
 
 /// The best known block as identified by its hash and height.
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, PartialEq, Eq)]
 pub struct BestBlock {
        block_hash: BlockHash,
        height: u32,
@@ -188,7 +188,7 @@ pub trait Confirm {
 }
 
 /// An enum representing the status of a channel monitor update persistence.
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum ChannelMonitorUpdateStatus {
        /// The update has been durably persisted and all copies of the relevant [`ChannelMonitor`]
        /// have been updated.
@@ -364,7 +364,7 @@ pub trait Filter {
 ///
 /// [`ChannelMonitor`]: channelmonitor::ChannelMonitor
 /// [`ChannelMonitor::block_connected`]: channelmonitor::ChannelMonitor::block_connected
-#[derive(Clone, PartialEq, Hash)]
+#[derive(Clone, PartialEq, Eq, Hash)]
 pub struct WatchedOutput {
        /// First block where the transaction output may have been spent.
        pub block_hash: Option<BlockHash>,
index 0f2edff5ed78bd3472e2f7c93ad8b2e845c62ba1..875f4d896d5d114c97fa4c0777e3b761d03e2b27 100644 (file)
@@ -23,10 +23,16 @@ use bitcoin::secp256k1;
 
 use ln::msgs::DecodeError;
 use ln::PaymentPreimage;
+#[cfg(anchors)]
+use ln::chan_utils;
 use ln::chan_utils::{ChannelTransactionParameters, HolderCommitmentTransaction};
+#[cfg(anchors)]
+use chain::chaininterface::ConfirmationTarget;
 use chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
 use chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER};
 use chain::keysinterface::{Sign, KeysInterface};
+#[cfg(anchors)]
+use chain::package::PackageSolvingData;
 use chain::package::PackageTemplate;
 use util::logger::Logger;
 use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, VecWriter};
@@ -38,6 +44,8 @@ use alloc::collections::BTreeMap;
 use core::cmp;
 use core::ops::Deref;
 use core::mem::replace;
+#[cfg(anchors)]
+use core::mem::swap;
 use bitcoin::hashes::Hash;
 
 const MAX_ALLOC_SIZE: usize = 64*1024;
@@ -46,7 +54,7 @@ const MAX_ALLOC_SIZE: usize = 64*1024;
 /// transaction causing it.
 ///
 /// Used to determine when the on-chain event can be considered safe from a chain reorganization.
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 struct OnchainEventEntry {
        txid: Txid,
        height: u32,
@@ -65,7 +73,7 @@ impl OnchainEventEntry {
 
 /// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it
 /// once they mature to enough confirmations (ANTI_REORG_DELAY)
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 enum OnchainEvent {
        /// Outpoint under claim process by our own tx, once this one get enough confirmations, we remove it from
        /// bump-txn candidate buffer.
@@ -162,6 +170,29 @@ impl Writeable for Option<Vec<Option<(usize, Signature)>>> {
        }
 }
 
+// Represents the different types of claims for which events are yielded externally to satisfy said
+// claims.
+#[cfg(anchors)]
+pub(crate) enum ClaimEvent {
+       /// Event yielded to signal that the commitment transaction fee must be bumped to claim any
+       /// encumbered funds and proceed to HTLC resolution, if any HTLCs exist.
+       BumpCommitment {
+               package_target_feerate_sat_per_1000_weight: u32,
+               commitment_tx: Transaction,
+               anchor_output_idx: u32,
+       },
+}
+
+/// Represents the different ways an output can be claimed (i.e., spent to an address under our
+/// control) onchain.
+pub(crate) enum OnchainClaim {
+       /// A finalized transaction pending confirmation spending the output to claim.
+       Tx(Transaction),
+       #[cfg(anchors)]
+       /// An event yielded externally to signal additional inputs must be added to a transaction
+       /// pending confirmation spending the output to claim.
+       Event(ClaimEvent),
+}
 
 /// OnchainTxHandler receives claiming requests, aggregates them if it's sound, broadcast and
 /// do RBF bumping if possible.
@@ -193,6 +224,8 @@ pub struct OnchainTxHandler<ChannelSigner: Sign> {
        pub(crate) pending_claim_requests: HashMap<Txid, PackageTemplate>,
        #[cfg(not(test))]
        pending_claim_requests: HashMap<Txid, PackageTemplate>,
+       #[cfg(anchors)]
+       pending_claim_events: HashMap<Txid, ClaimEvent>,
 
        // Used to link outpoints claimed in a connected block to a pending claim request.
        // Key is outpoint than monitor parsing has detected we have keys/scripts to claim
@@ -342,6 +375,8 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::Signer> {
                        locktimed_packages,
                        pending_claim_requests,
                        onchain_events_awaiting_threshold_conf,
+                       #[cfg(anchors)]
+                       pending_claim_events: HashMap::new(),
                        secp_ctx,
                })
        }
@@ -361,6 +396,8 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                        claimable_outpoints: HashMap::new(),
                        locktimed_packages: BTreeMap::new(),
                        onchain_events_awaiting_threshold_conf: Vec::new(),
+                       #[cfg(anchors)]
+                       pending_claim_events: HashMap::new(),
 
                        secp_ctx,
                }
@@ -374,11 +411,22 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                self.holder_commitment.to_broadcaster_value_sat()
        }
 
-       /// Lightning security model (i.e being able to redeem/timeout HTLC or penalize coutnerparty onchain) lays on the assumption of claim transactions getting confirmed before timelock expiration
-       /// (CSV or CLTV following cases). In case of high-fee spikes, claim tx may stuck in the mempool, so you need to bump its feerate quickly using Replace-By-Fee or Child-Pay-For-Parent.
-       /// Panics if there are signing errors, because signing operations in reaction to on-chain events
-       /// are not expected to fail, and if they do, we may lose funds.
-       fn generate_claim_tx<F: Deref, L: Deref>(&mut self, cur_height: u32, cached_request: &PackageTemplate, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L) -> Option<(Option<u32>, u64, Transaction)>
+       #[cfg(anchors)]
+       pub(crate) fn get_and_clear_pending_claim_events(&mut self) -> Vec<ClaimEvent> {
+               let mut ret = HashMap::new();
+               swap(&mut ret, &mut self.pending_claim_events);
+               ret.into_iter().map(|(_, event)| event).collect::<Vec<_>>()
+       }
+
+       /// Lightning security model (i.e being able to redeem/timeout HTLC or penalize counterparty
+       /// onchain) lays on the assumption of claim transactions getting confirmed before timelock
+       /// expiration (CSV or CLTV following cases). In case of high-fee spikes, claim tx may get stuck
+       /// in the mempool, so you need to bump its feerate quickly using Replace-By-Fee or
+       /// Child-Pay-For-Parent.
+       ///
+       /// Panics if there are signing errors, because signing operations in reaction to on-chain
+       /// events are not expected to fail, and if they do, we may lose funds.
+       fn generate_claim<F: Deref, L: Deref>(&mut self, cur_height: u32, cached_request: &PackageTemplate, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L) -> Option<(Option<u32>, u64, OnchainClaim)>
                where F::Target: FeeEstimator,
                                        L::Target: Logger,
        {
@@ -388,23 +436,71 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                // didn't receive confirmation of it before, or not enough reorg-safe depth on top of it).
                let new_timer = Some(cached_request.get_height_timer(cur_height));
                if cached_request.is_malleable() {
-                       let predicted_weight = cached_request.package_weight(&self.destination_script, self.channel_transaction_parameters.opt_anchors.is_some());
+                       let predicted_weight = cached_request.package_weight(&self.destination_script);
                        if let Some((output_value, new_feerate)) =
                                        cached_request.compute_package_output(predicted_weight, self.destination_script.dust_value().to_sat(), fee_estimator, logger) {
                                assert!(new_feerate != 0);
 
-                               let transaction = cached_request.finalize_package(self, output_value, self.destination_script.clone(), logger).unwrap();
+                               let transaction = cached_request.finalize_malleable_package(self, output_value, self.destination_script.clone(), logger).unwrap();
                                log_trace!(logger, "...with timer {} and feerate {}", new_timer.unwrap(), new_feerate);
                                assert!(predicted_weight >= transaction.weight());
-                               return Some((new_timer, new_feerate, transaction))
+                               return Some((new_timer, new_feerate, OnchainClaim::Tx(transaction)))
                        }
                } else {
-                       // Note: Currently, amounts of holder outputs spending witnesses aren't used
-                       // as we can't malleate spending package to increase their feerate. This
-                       // should change with the remaining anchor output patchset.
-                       if let Some(transaction) = cached_request.finalize_package(self, 0, self.destination_script.clone(), logger) {
-                               return Some((None, 0, transaction));
+                       // Untractable packages cannot have their fees bumped through Replace-By-Fee. Some
+                       // packages may support fee bumping through Child-Pays-For-Parent, indicated by those
+                       // which require external funding.
+                       #[cfg(not(anchors))]
+                       let inputs = cached_request.inputs();
+                       #[cfg(anchors)]
+                       let mut inputs = cached_request.inputs();
+                       debug_assert_eq!(inputs.len(), 1);
+                       let tx = match cached_request.finalize_untractable_package(self, logger) {
+                               Some(tx) => tx,
+                               None => return None,
+                       };
+                       if !cached_request.requires_external_funding() {
+                               return Some((None, 0, OnchainClaim::Tx(tx)));
                        }
+                       #[cfg(anchors)]
+                       return inputs.find_map(|input| match input {
+                               // Commitment inputs with anchors support are the only untractable inputs supported
+                               // thus far that require external funding.
+                               PackageSolvingData::HolderFundingOutput(..) => {
+                                       debug_assert_eq!(tx.txid(), self.holder_commitment.trust().txid(),
+                                               "Holder commitment transaction mismatch");
+                                       // We'll locate an anchor output we can spend within the commitment transaction.
+                                       let funding_pubkey = &self.channel_transaction_parameters.holder_pubkeys.funding_pubkey;
+                                       match chan_utils::get_anchor_output(&tx, funding_pubkey) {
+                                               // An anchor output was found, so we should yield a funding event externally.
+                                               Some((idx, _)) => {
+                                                       // TODO: Use a lower confirmation target when both our and the
+                                                       // counterparty's latest commitment don't have any HTLCs present.
+                                                       let conf_target = ConfirmationTarget::HighPriority;
+                                                       let package_target_feerate_sat_per_1000_weight = cached_request
+                                                               .compute_package_feerate(fee_estimator, conf_target);
+                                                       Some((
+                                                               new_timer,
+                                                               package_target_feerate_sat_per_1000_weight as u64,
+                                                               OnchainClaim::Event(ClaimEvent::BumpCommitment {
+                                                                       package_target_feerate_sat_per_1000_weight,
+                                                                       commitment_tx: tx.clone(),
+                                                                       anchor_output_idx: idx,
+                                                               }),
+                                                       ))
+                                               },
+                                               // An anchor output was not found. There's nothing we can do other than
+                                               // attempt to broadcast the transaction with its current fee rate and hope
+                                               // it confirms. This is essentially the same behavior as a commitment
+                                               // transaction without anchor outputs.
+                                               None => Some((None, 0, OnchainClaim::Tx(tx.clone()))),
+                                       }
+                               },
+                               _ => {
+                                       debug_assert!(false, "Only HolderFundingOutput inputs should be untractable and require external funding");
+                                       None
+                               },
+                       });
                }
                None
        }
@@ -475,17 +571,30 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                // Generate claim transactions and track them to bump if necessary at
                // height timer expiration (i.e in how many blocks we're going to take action).
                for mut req in preprocessed_requests {
-                       if let Some((new_timer, new_feerate, tx)) = self.generate_claim_tx(cur_height, &req, &*fee_estimator, &*logger) {
+                       if let Some((new_timer, new_feerate, claim)) = self.generate_claim(cur_height, &req, &*fee_estimator, &*logger) {
                                req.set_timer(new_timer);
                                req.set_feerate(new_feerate);
-                               let txid = tx.txid();
+                               let txid = match claim {
+                                       OnchainClaim::Tx(tx) => {
+                                               log_info!(logger, "Broadcasting onchain {}", log_tx!(tx));
+                                               broadcaster.broadcast_transaction(&tx);
+                                               tx.txid()
+                                       },
+                                       #[cfg(anchors)]
+                                       OnchainClaim::Event(claim_event) => {
+                                               log_info!(logger, "Yielding onchain event to spend inputs {:?}", req.outpoints());
+                                               let txid = match claim_event {
+                                                       ClaimEvent::BumpCommitment { ref commitment_tx, .. } => commitment_tx.txid(),
+                                               };
+                                               self.pending_claim_events.insert(txid, claim_event);
+                                               txid
+                                       },
+                               };
                                for k in req.outpoints() {
                                        log_info!(logger, "Registering claiming request for {}:{}", k.txid, k.vout);
                                        self.claimable_outpoints.insert(k.clone(), (txid, conf_height));
                                }
                                self.pending_claim_requests.insert(txid, req);
-                               log_info!(logger, "Broadcasting onchain {}", log_tx!(tx));
-                               broadcaster.broadcast_transaction(&tx);
                        }
                }
 
@@ -577,6 +686,8 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                                                        for outpoint in request.outpoints() {
                                                                log_debug!(logger, "Removing claim tracking for {} due to maturation of claim tx {}.", outpoint, claim_request);
                                                                self.claimable_outpoints.remove(&outpoint);
+                                                               #[cfg(anchors)]
+                                                               self.pending_claim_events.remove(&claim_request);
                                                        }
                                                }
                                        },
@@ -603,9 +714,18 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                // Build, bump and rebroadcast tx accordingly
                log_trace!(logger, "Bumping {} candidates", bump_candidates.len());
                for (first_claim_txid, request) in bump_candidates.iter() {
-                       if let Some((new_timer, new_feerate, bump_tx)) = self.generate_claim_tx(cur_height, &request, &*fee_estimator, &*logger) {
-                               log_info!(logger, "Broadcasting RBF-bumped onchain {}", log_tx!(bump_tx));
-                               broadcaster.broadcast_transaction(&bump_tx);
+                       if let Some((new_timer, new_feerate, bump_claim)) = self.generate_claim(cur_height, &request, &*fee_estimator, &*logger) {
+                               match bump_claim {
+                                       OnchainClaim::Tx(bump_tx) => {
+                                               log_info!(logger, "Broadcasting RBF-bumped onchain {}", log_tx!(bump_tx));
+                                               broadcaster.broadcast_transaction(&bump_tx);
+                                       },
+                                       #[cfg(anchors)]
+                                       OnchainClaim::Event(claim_event) => {
+                                               log_info!(logger, "Yielding RBF-bumped onchain event to spend inputs {:?}", request.outpoints());
+                                               self.pending_claim_events.insert(*first_claim_txid, claim_event);
+                                       },
+                               }
                                if let Some(request) = self.pending_claim_requests.get_mut(first_claim_txid) {
                                        request.set_timer(new_timer);
                                        request.set_feerate(new_feerate);
@@ -667,12 +787,21 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
                                self.onchain_events_awaiting_threshold_conf.push(entry);
                        }
                }
-               for (_, request) in bump_candidates.iter_mut() {
-                       if let Some((new_timer, new_feerate, bump_tx)) = self.generate_claim_tx(height, &request, fee_estimator, &&*logger) {
+               for (_first_claim_txid_height, request) in bump_candidates.iter_mut() {
+                       if let Some((new_timer, new_feerate, bump_claim)) = self.generate_claim(height, &request, fee_estimator, &&*logger) {
                                request.set_timer(new_timer);
                                request.set_feerate(new_feerate);
-                               log_info!(logger, "Broadcasting onchain {}", log_tx!(bump_tx));
-                               broadcaster.broadcast_transaction(&bump_tx);
+                               match bump_claim {
+                                       OnchainClaim::Tx(bump_tx) => {
+                                               log_info!(logger, "Broadcasting onchain {}", log_tx!(bump_tx));
+                                               broadcaster.broadcast_transaction(&bump_tx);
+                                       },
+                                       #[cfg(anchors)]
+                                       OnchainClaim::Event(claim_event) => {
+                                               log_info!(logger, "Yielding onchain event after reorg to spend inputs {:?}", request.outpoints());
+                                               self.pending_claim_events.insert(_first_claim_txid_height.0, claim_event);
+                                       },
+                               }
                        }
                }
                for (ancestor_claim_txid, request) in bump_candidates.drain() {
index c945d8909da4a61cc656a634a75f0b130eb342d2..5aa55fb197583be8e97f4ecc8c05ee806df2433c 100644 (file)
@@ -34,6 +34,8 @@ use util::ser::{Readable, Writer, Writeable};
 use io;
 use prelude::*;
 use core::cmp;
+#[cfg(anchors)]
+use core::convert::TryInto;
 use core::mem;
 use core::ops::Deref;
 use bitcoin::{PackedLockTime, Sequence, Witness};
@@ -86,7 +88,7 @@ const HIGH_FREQUENCY_BUMP_INTERVAL: u32 = 1;
 ///
 /// CSV and pubkeys are used as part of a witnessScript redeeming a balance output, amount is used
 /// as part of the signature hash and revocation secret to generate a satisfying witness.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) struct RevokedOutput {
        per_commitment_point: PublicKey,
        counterparty_delayed_payment_base_key: PublicKey,
@@ -129,7 +131,7 @@ impl_writeable_tlv_based!(RevokedOutput, {
 ///
 /// CSV is used as part of a witnessScript redeeming a balance output, amount is used as part
 /// of the signature hash and revocation secret to generate a satisfying witness.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) struct RevokedHTLCOutput {
        per_commitment_point: PublicKey,
        counterparty_delayed_payment_base_key: PublicKey,
@@ -171,29 +173,36 @@ impl_writeable_tlv_based!(RevokedHTLCOutput, {
 /// witnessScript.
 ///
 /// The preimage is used as part of the witness.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) struct CounterpartyOfferedHTLCOutput {
        per_commitment_point: PublicKey,
        counterparty_delayed_payment_base_key: PublicKey,
        counterparty_htlc_base_key: PublicKey,
        preimage: PaymentPreimage,
-       htlc: HTLCOutputInCommitment
+       htlc: HTLCOutputInCommitment,
+       opt_anchors: Option<()>,
 }
 
 impl CounterpartyOfferedHTLCOutput {
-       pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, preimage: PaymentPreimage, htlc: HTLCOutputInCommitment) -> Self {
+       pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, preimage: PaymentPreimage, htlc: HTLCOutputInCommitment, opt_anchors: bool) -> Self {
                CounterpartyOfferedHTLCOutput {
                        per_commitment_point,
                        counterparty_delayed_payment_base_key,
                        counterparty_htlc_base_key,
                        preimage,
-                       htlc
+                       htlc,
+                       opt_anchors: if opt_anchors { Some(()) } else { None },
                }
        }
+
+       fn opt_anchors(&self) -> bool {
+               self.opt_anchors.is_some()
+       }
 }
 
 impl_writeable_tlv_based!(CounterpartyOfferedHTLCOutput, {
        (0, per_commitment_point, required),
+       (1, opt_anchors, option),
        (2, counterparty_delayed_payment_base_key, required),
        (4, counterparty_htlc_base_key, required),
        (6, preimage, required),
@@ -204,27 +213,34 @@ impl_writeable_tlv_based!(CounterpartyOfferedHTLCOutput, {
 ///
 /// HTLCOutputInCommitment (hash, timelock, directon) and pubkeys are used to generate a suitable
 /// witnessScript.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) struct CounterpartyReceivedHTLCOutput {
        per_commitment_point: PublicKey,
        counterparty_delayed_payment_base_key: PublicKey,
        counterparty_htlc_base_key: PublicKey,
-       htlc: HTLCOutputInCommitment
+       htlc: HTLCOutputInCommitment,
+       opt_anchors: Option<()>,
 }
 
 impl CounterpartyReceivedHTLCOutput {
-       pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, htlc: HTLCOutputInCommitment) -> Self {
+       pub(crate) fn build(per_commitment_point: PublicKey, counterparty_delayed_payment_base_key: PublicKey, counterparty_htlc_base_key: PublicKey, htlc: HTLCOutputInCommitment, opt_anchors: bool) -> Self {
                CounterpartyReceivedHTLCOutput {
                        per_commitment_point,
                        counterparty_delayed_payment_base_key,
                        counterparty_htlc_base_key,
-                       htlc
+                       htlc,
+                       opt_anchors: if opt_anchors { Some(()) } else { None },
                }
        }
+
+       fn opt_anchors(&self) -> bool {
+               self.opt_anchors.is_some()
+       }
 }
 
 impl_writeable_tlv_based!(CounterpartyReceivedHTLCOutput, {
        (0, per_commitment_point, required),
+       (1, opt_anchors, option),
        (2, counterparty_delayed_payment_base_key, required),
        (4, counterparty_htlc_base_key, required),
        (6, htlc, required),
@@ -234,7 +250,7 @@ impl_writeable_tlv_based!(CounterpartyReceivedHTLCOutput, {
 ///
 /// Either offered or received, the amount is always used as part of the bip143 sighash.
 /// Preimage is only included as part of the witness in former case.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) struct HolderHTLCOutput {
        preimage: Option<PaymentPreimage>,
        amount: u64,
@@ -269,28 +285,39 @@ impl_writeable_tlv_based!(HolderHTLCOutput, {
 /// A struct to describe the channel output on the funding transaction.
 ///
 /// witnessScript is used as part of the witness redeeming the funding utxo.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) struct HolderFundingOutput {
        funding_redeemscript: Script,
+       funding_amount: Option<u64>,
+       opt_anchors: Option<()>,
 }
 
+
 impl HolderFundingOutput {
-       pub(crate) fn build(funding_redeemscript: Script) -> Self {
+       pub(crate) fn build(funding_redeemscript: Script, funding_amount: u64, opt_anchors: bool) -> Self {
                HolderFundingOutput {
                        funding_redeemscript,
+                       funding_amount: Some(funding_amount),
+                       opt_anchors: if opt_anchors { Some(()) } else { None },
                }
        }
+
+       fn opt_anchors(&self) -> bool {
+               self.opt_anchors.is_some()
+       }
 }
 
 impl_writeable_tlv_based!(HolderFundingOutput, {
        (0, funding_redeemscript, required),
+       (1, opt_anchors, option),
+       (3, funding_amount, option),
 });
 
 /// A wrapper encapsulating all in-protocol differing outputs types.
 ///
 /// The generic API offers access to an outputs common attributes or allow transformation such as
 /// finalizing an input claiming the output.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) enum PackageSolvingData {
        RevokedOutput(RevokedOutput),
        RevokedHTLCOutput(RevokedHTLCOutput),
@@ -303,24 +330,27 @@ pub(crate) enum PackageSolvingData {
 impl PackageSolvingData {
        fn amount(&self) -> u64 {
                let amt = match self {
-                       PackageSolvingData::RevokedOutput(ref outp) => { outp.amount },
-                       PackageSolvingData::RevokedHTLCOutput(ref outp) => { outp.amount },
-                       PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => { outp.htlc.amount_msat / 1000 },
-                       PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => { outp.htlc.amount_msat / 1000 },
+                       PackageSolvingData::RevokedOutput(ref outp) => outp.amount,
+                       PackageSolvingData::RevokedHTLCOutput(ref outp) => outp.amount,
+                       PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => outp.htlc.amount_msat / 1000,
+                       PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => outp.htlc.amount_msat / 1000,
                        // Note: Currently, amounts of holder outputs spending witnesses aren't used
                        // as we can't malleate spending package to increase their feerate. This
                        // should change with the remaining anchor output patchset.
-                       PackageSolvingData::HolderHTLCOutput(..) => { unreachable!() },
-                       PackageSolvingData::HolderFundingOutput(..) => { unreachable!() },
+                       PackageSolvingData::HolderHTLCOutput(..) => unreachable!(),
+                       PackageSolvingData::HolderFundingOutput(ref outp) => {
+                               debug_assert!(outp.opt_anchors());
+                               outp.funding_amount.unwrap()
+                       }
                };
                amt
        }
-       fn weight(&self, opt_anchors: bool) -> usize {
+       fn weight(&self) -> usize {
                let weight = match self {
                        PackageSolvingData::RevokedOutput(ref outp) => { outp.weight as usize },
                        PackageSolvingData::RevokedHTLCOutput(ref outp) => { outp.weight as usize },
-                       PackageSolvingData::CounterpartyOfferedHTLCOutput(..) => { weight_offered_htlc(opt_anchors) as usize },
-                       PackageSolvingData::CounterpartyReceivedHTLCOutput(..) => { weight_received_htlc(opt_anchors) as usize },
+                       PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => { weight_offered_htlc(outp.opt_anchors()) as usize },
+                       PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => { weight_received_htlc(outp.opt_anchors()) as usize },
                        // Note: Currently, weights of holder outputs spending witnesses aren't used
                        // as we can't malleate spending package to increase their feerate. This
                        // should change with the remaining anchor output patchset.
@@ -444,7 +474,7 @@ impl_writeable_tlv_based_enum!(PackageSolvingData, ;
 /// A malleable package might be aggregated with other packages to save on fees.
 /// A untractable package has been counter-signed and aggregable will break cached counterparty
 /// signatures.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub(crate) enum PackageMalleability {
        Malleable,
        Untractable,
@@ -459,7 +489,7 @@ pub(crate) enum PackageMalleability {
 ///
 /// As packages are time-sensitive, we fee-bump and rebroadcast them at scheduled intervals.
 /// Failing to confirm a package translate as a loss of funds for the user.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub struct PackageTemplate {
        // List of onchain outputs and solving data to generate satisfying witnesses.
        inputs: Vec<(BitcoinOutPoint, PackageSolvingData)>,
@@ -520,6 +550,9 @@ impl PackageTemplate {
        pub(crate) fn outpoints(&self) -> Vec<&BitcoinOutPoint> {
                self.inputs.iter().map(|(o, _)| o).collect()
        }
+       pub(crate) fn inputs(&self) -> impl ExactSizeIterator<Item = &PackageSolvingData> {
+               self.inputs.iter().map(|(_, i)| i)
+       }
        pub(crate) fn split_package(&mut self, split_outp: &BitcoinOutPoint) -> Option<PackageTemplate> {
                match self.malleability {
                        PackageMalleability::Malleable => {
@@ -583,7 +616,7 @@ impl PackageTemplate {
        }
        /// Gets the amount of all outptus being spent by this package, only valid for malleable
        /// packages.
-       fn package_amount(&self) -> u64 {
+       pub(crate) fn package_amount(&self) -> u64 {
                let mut amounts = 0;
                for (_, outp) in self.inputs.iter() {
                        amounts += outp.amount();
@@ -594,13 +627,13 @@ impl PackageTemplate {
                self.inputs.iter().map(|(_, outp)| outp.absolute_tx_timelock(self.height_original))
                        .max().expect("There must always be at least one output to spend in a PackageTemplate")
        }
-       pub(crate) fn package_weight(&self, destination_script: &Script, opt_anchors: bool) -> usize {
+       pub(crate) fn package_weight(&self, destination_script: &Script) -> usize {
                let mut inputs_weight = 0;
                let mut witnesses_weight = 2; // count segwit flags
                for (_, outp) in self.inputs.iter() {
                        // previous_out_point: 36 bytes ; var_int: 1 byte ; sequence: 4 bytes
                        inputs_weight += 41 * WITNESS_SCALE_FACTOR;
-                       witnesses_weight += outp.weight(opt_anchors);
+                       witnesses_weight += outp.weight();
                }
                // version: 4 bytes ; count_tx_in: 1 byte ; count_tx_out: 1 byte ; lock_time: 4 bytes
                let transaction_weight = 10 * WITNESS_SCALE_FACTOR;
@@ -608,47 +641,46 @@ impl PackageTemplate {
                let output_weight = (8 + 1 + destination_script.len()) * WITNESS_SCALE_FACTOR;
                inputs_weight + witnesses_weight + transaction_weight + output_weight
        }
-       pub(crate) fn finalize_package<L: Deref, Signer: Sign>(&self, onchain_handler: &mut OnchainTxHandler<Signer>, value: u64, destination_script: Script, logger: &L) -> Option<Transaction>
-               where L::Target: Logger,
-       {
-               match self.malleability {
-                       PackageMalleability::Malleable => {
-                               let mut bumped_tx = Transaction {
-                                       version: 2,
-                                       lock_time: PackedLockTime::ZERO,
-                                       input: vec![],
-                                       output: vec![TxOut {
-                                               script_pubkey: destination_script,
-                                               value,
-                                       }],
-                               };
-                               for (outpoint, _) in self.inputs.iter() {
-                                       bumped_tx.input.push(TxIn {
-                                               previous_output: *outpoint,
-                                               script_sig: Script::new(),
-                                               sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
-                                               witness: Witness::new(),
-                                       });
-                               }
-                               for (i, (outpoint, out)) in self.inputs.iter().enumerate() {
-                                       log_debug!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
-                                       if !out.finalize_input(&mut bumped_tx, i, onchain_handler) { return None; }
-                               }
-                               log_debug!(logger, "Finalized transaction {} ready to broadcast", bumped_tx.txid());
-                               return Some(bumped_tx);
-                       },
-                       PackageMalleability::Untractable => {
-                               debug_assert_eq!(value, 0, "value is ignored for non-malleable packages, should be zero to ensure callsites are correct");
-                               if let Some((outpoint, outp)) = self.inputs.first() {
-                                       if let Some(final_tx) = outp.get_finalized_tx(outpoint, onchain_handler) {
-                                               log_debug!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
-                                               log_debug!(logger, "Finalized transaction {} ready to broadcast", final_tx.txid());
-                                               return Some(final_tx);
-                                       }
-                                       return None;
-                               } else { panic!("API Error: Package must not be inputs empty"); }
-                       },
+       pub(crate) fn finalize_malleable_package<L: Deref, Signer: Sign>(
+               &self, onchain_handler: &mut OnchainTxHandler<Signer>, value: u64, destination_script: Script, logger: &L
+       ) -> Option<Transaction> where L::Target: Logger {
+               debug_assert!(self.is_malleable());
+               let mut bumped_tx = Transaction {
+                       version: 2,
+                       lock_time: PackedLockTime::ZERO,
+                       input: vec![],
+                       output: vec![TxOut {
+                               script_pubkey: destination_script,
+                               value,
+                       }],
+               };
+               for (outpoint, _) in self.inputs.iter() {
+                       bumped_tx.input.push(TxIn {
+                               previous_output: *outpoint,
+                               script_sig: Script::new(),
+                               sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
+                               witness: Witness::new(),
+                       });
+               }
+               for (i, (outpoint, out)) in self.inputs.iter().enumerate() {
+                       log_debug!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
+                       if !out.finalize_input(&mut bumped_tx, i, onchain_handler) { return None; }
                }
+               log_debug!(logger, "Finalized transaction {} ready to broadcast", bumped_tx.txid());
+               Some(bumped_tx)
+       }
+       pub(crate) fn finalize_untractable_package<L: Deref, Signer: Sign>(
+               &self, onchain_handler: &mut OnchainTxHandler<Signer>, logger: &L,
+       ) -> Option<Transaction> where L::Target: Logger {
+               debug_assert!(!self.is_malleable());
+               if let Some((outpoint, outp)) = self.inputs.first() {
+                       if let Some(final_tx) = outp.get_finalized_tx(outpoint, onchain_handler) {
+                               log_debug!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout);
+                               log_debug!(logger, "Finalized transaction {} ready to broadcast", final_tx.txid());
+                               return Some(final_tx);
+                       }
+                       return None;
+               } else { panic!("API Error: Package must not be inputs empty"); }
        }
        /// In LN, output claimed are time-sensitive, which means we have to spend them before reaching some timelock expiration. At in-channel
        /// output detection, we generate a first version of a claim tx and associate to it a height timer. A height timer is an absolute block
@@ -686,14 +718,45 @@ impl PackageTemplate {
                }
                None
        }
+
+       #[cfg(anchors)]
+       /// Computes a feerate based on the given confirmation target. If a previous feerate was used,
+       /// and the new feerate is below it, we'll use a 25% increase of the previous feerate instead of
+       /// the new one.
+       pub(crate) fn compute_package_feerate<F: Deref>(
+               &self, fee_estimator: &LowerBoundedFeeEstimator<F>, conf_target: ConfirmationTarget,
+       ) -> u32 where F::Target: FeeEstimator {
+               let feerate_estimate = fee_estimator.bounded_sat_per_1000_weight(conf_target);
+               if self.feerate_previous != 0 {
+                       // If old feerate inferior to actual one given back by Fee Estimator, use it to compute new fee...
+                       if feerate_estimate as u64 > self.feerate_previous {
+                               feerate_estimate
+                       } else {
+                               // ...else just increase the previous feerate by 25% (because that's a nice number)
+                               (self.feerate_previous + (self.feerate_previous / 4)).try_into().unwrap_or(u32::max_value())
+                       }
+               } else {
+                       feerate_estimate
+               }
+       }
+
+       /// Determines whether a package contains an input which must have additional external inputs
+       /// attached to help the spending transaction reach confirmation.
+       pub(crate) fn requires_external_funding(&self) -> bool {
+               self.inputs.iter().find(|input| match input.1 {
+                       PackageSolvingData::HolderFundingOutput(ref outp) => outp.opt_anchors(),
+                       _ => false,
+               }).is_some()
+       }
+
        pub (crate) fn build_package(txid: Txid, vout: u32, input_solving_data: PackageSolvingData, soonest_conf_deadline: u32, aggregable: bool, height_original: u32) -> Self {
                let malleability = match input_solving_data {
-                       PackageSolvingData::RevokedOutput(..) => { PackageMalleability::Malleable },
-                       PackageSolvingData::RevokedHTLCOutput(..) => { PackageMalleability::Malleable },
-                       PackageSolvingData::CounterpartyOfferedHTLCOutput(..) => { PackageMalleability::Malleable },
-                       PackageSolvingData::CounterpartyReceivedHTLCOutput(..) => { PackageMalleability::Malleable },
-                       PackageSolvingData::HolderHTLCOutput(..) => { PackageMalleability::Untractable },
-                       PackageSolvingData::HolderFundingOutput(..) => { PackageMalleability::Untractable },
+                       PackageSolvingData::RevokedOutput(..) => PackageMalleability::Malleable,
+                       PackageSolvingData::RevokedHTLCOutput(..) => PackageMalleability::Malleable,
+                       PackageSolvingData::CounterpartyOfferedHTLCOutput(..) => PackageMalleability::Malleable,
+                       PackageSolvingData::CounterpartyReceivedHTLCOutput(..) => PackageMalleability::Malleable,
+                       PackageSolvingData::HolderHTLCOutput(..) => PackageMalleability::Untractable,
+                       PackageSolvingData::HolderFundingOutput(..) => PackageMalleability::Untractable,
                };
                let mut inputs = Vec::with_capacity(1);
                inputs.push((BitcoinOutPoint { txid, vout }, input_solving_data));
@@ -873,26 +936,26 @@ mod tests {
        }
 
        macro_rules! dumb_counterparty_output {
-               ($secp_ctx: expr, $amt: expr) => {
+               ($secp_ctx: expr, $amt: expr, $opt_anchors: expr) => {
                        {
                                let dumb_scalar = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
                                let dumb_point = PublicKey::from_secret_key(&$secp_ctx, &dumb_scalar);
                                let hash = PaymentHash([1; 32]);
                                let htlc = HTLCOutputInCommitment { offered: true, amount_msat: $amt, cltv_expiry: 0, payment_hash: hash, transaction_output_index: None };
-                               PackageSolvingData::CounterpartyReceivedHTLCOutput(CounterpartyReceivedHTLCOutput::build(dumb_point, dumb_point, dumb_point, htlc))
+                               PackageSolvingData::CounterpartyReceivedHTLCOutput(CounterpartyReceivedHTLCOutput::build(dumb_point, dumb_point, dumb_point, htlc, $opt_anchors))
                        }
                }
        }
 
        macro_rules! dumb_counterparty_offered_output {
-               ($secp_ctx: expr, $amt: expr) => {
+               ($secp_ctx: expr, $amt: expr, $opt_anchors: expr) => {
                        {
                                let dumb_scalar = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
                                let dumb_point = PublicKey::from_secret_key(&$secp_ctx, &dumb_scalar);
                                let hash = PaymentHash([1; 32]);
                                let preimage = PaymentPreimage([2;32]);
                                let htlc = HTLCOutputInCommitment { offered: false, amount_msat: $amt, cltv_expiry: 1000, payment_hash: hash, transaction_output_index: None };
-                               PackageSolvingData::CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput::build(dumb_point, dumb_point, dumb_point, preimage, htlc))
+                               PackageSolvingData::CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput::build(dumb_point, dumb_point, dumb_point, preimage, htlc, $opt_anchors))
                        }
                }
        }
@@ -987,7 +1050,7 @@ mod tests {
                let txid = Txid::from_hex("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
                let secp_ctx = Secp256k1::new();
                let revk_outp = dumb_revk_output!(secp_ctx);
-               let counterparty_outp = dumb_counterparty_output!(secp_ctx, 0);
+               let counterparty_outp = dumb_counterparty_output!(secp_ctx, 0, false);
 
                let mut revoked_package = PackageTemplate::build_package(txid, 0, revk_outp, 1000, true, 100);
                let counterparty_package = PackageTemplate::build_package(txid, 1, counterparty_outp, 1000, true, 100);
@@ -1051,7 +1114,7 @@ mod tests {
        fn test_package_amounts() {
                let txid = Txid::from_hex("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
                let secp_ctx = Secp256k1::new();
-               let counterparty_outp = dumb_counterparty_output!(secp_ctx, 1_000_000);
+               let counterparty_outp = dumb_counterparty_output!(secp_ctx, 1_000_000, false);
 
                let package = PackageTemplate::build_package(txid, 0, counterparty_outp, 1000, true, 100);
                assert_eq!(package.package_amount(), 1000);
@@ -1068,24 +1131,22 @@ mod tests {
                {
                        let revk_outp = dumb_revk_output!(secp_ctx);
                        let package = PackageTemplate::build_package(txid, 0, revk_outp, 0, true, 100);
-                       for &opt_anchors in [false, true].iter() {
-                               assert_eq!(package.package_weight(&Script::new(), opt_anchors),  weight_sans_output + WEIGHT_REVOKED_OUTPUT as usize);
-                       }
+                       assert_eq!(package.package_weight(&Script::new()),  weight_sans_output + WEIGHT_REVOKED_OUTPUT as usize);
                }
 
                {
-                       let counterparty_outp = dumb_counterparty_output!(secp_ctx, 1_000_000);
-                       let package = PackageTemplate::build_package(txid, 0, counterparty_outp, 1000, true, 100);
                        for &opt_anchors in [false, true].iter() {
-                               assert_eq!(package.package_weight(&Script::new(), opt_anchors), weight_sans_output + weight_received_htlc(opt_anchors) as usize);
+                               let counterparty_outp = dumb_counterparty_output!(secp_ctx, 1_000_000, opt_anchors);
+                               let package = PackageTemplate::build_package(txid, 0, counterparty_outp, 1000, true, 100);
+                               assert_eq!(package.package_weight(&Script::new()), weight_sans_output + weight_received_htlc(opt_anchors) as usize);
                        }
                }
 
                {
-                       let counterparty_outp = dumb_counterparty_offered_output!(secp_ctx, 1_000_000);
-                       let package = PackageTemplate::build_package(txid, 0, counterparty_outp, 1000, true, 100);
                        for &opt_anchors in [false, true].iter() {
-                               assert_eq!(package.package_weight(&Script::new(), opt_anchors), weight_sans_output + weight_offered_htlc(opt_anchors) as usize);
+                               let counterparty_outp = dumb_counterparty_offered_output!(secp_ctx, 1_000_000, opt_anchors);
+                               let package = PackageTemplate::build_package(txid, 0, counterparty_outp, 1000, true, 100);
+                               assert_eq!(package.package_weight(&Script::new()), weight_sans_output + weight_offered_htlc(opt_anchors) as usize);
                        }
                }
        }
index df0378938b42eeb0b1ff0fbd1413f6f140617a12..15bc0d0e23e08079751972f32d751a76dc4706d7 100644 (file)
@@ -65,7 +65,7 @@ pub fn htlc_timeout_tx_weight(opt_anchors: bool) -> u64 {
        if opt_anchors { HTLC_TIMEOUT_ANCHOR_TX_WEIGHT } else { HTLC_TIMEOUT_TX_WEIGHT }
 }
 
-#[derive(PartialEq)]
+#[derive(PartialEq, Eq)]
 pub(crate) enum HTLCClaim {
        OfferedTimeout,
        OfferedPreimage,
@@ -208,6 +208,7 @@ pub struct CounterpartyCommitmentSecrets {
        old_secrets: [([u8; 32], u64); 49],
 }
 
+impl Eq for CounterpartyCommitmentSecrets {}
 impl PartialEq for CounterpartyCommitmentSecrets {
        fn eq(&self, other: &Self) -> bool {
                for (&(ref secret, ref idx), &(ref o_secret, ref o_idx)) in self.old_secrets.iter().zip(other.old_secrets.iter()) {
@@ -419,7 +420,7 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2
 /// channel basepoints via the new function, or they were obtained via
 /// CommitmentTransaction.trust().keys() because we trusted the source of the
 /// pre-calculated keys.
-#[derive(PartialEq, Clone)]
+#[derive(PartialEq, Eq, Clone)]
 pub struct TxCreationKeys {
        /// The broadcaster's per-commitment public key which was used to derive the other keys.
        pub per_commitment_point: PublicKey,
@@ -444,7 +445,7 @@ impl_writeable_tlv_based!(TxCreationKeys, {
 });
 
 /// One counterparty's public keys which do not change over the life of a channel.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub struct ChannelPublicKeys {
        /// The public key which is used to sign all commitment transactions, as it appears in the
        /// on-chain channel lock-in 2-of-2 multisig output.
@@ -525,8 +526,8 @@ pub fn get_revokeable_redeemscript(revocation_key: &PublicKey, contest_delay: u1
        res
 }
 
-#[derive(Clone, PartialEq)]
 /// Information about an HTLC as it appears in a commitment transaction
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct HTLCOutputInCommitment {
        /// Whether the HTLC was "offered" (ie outbound in relation to this commitment transaction).
        /// Note that this is not the same as whether it is ountbound *from us*. To determine that you
@@ -726,6 +727,23 @@ pub fn get_anchor_redeemscript(funding_pubkey: &PublicKey) -> Script {
                .into_script()
 }
 
+#[cfg(anchors)]
+/// Locates the output with an anchor script paying to `funding_pubkey` within `commitment_tx`.
+pub(crate) fn get_anchor_output<'a>(commitment_tx: &'a Transaction, funding_pubkey: &PublicKey) -> Option<(u32, &'a TxOut)> {
+       let anchor_script = chan_utils::get_anchor_redeemscript(funding_pubkey).to_v0_p2wsh();
+       commitment_tx.output.iter().enumerate()
+               .find(|(_, txout)| txout.script_pubkey == anchor_script)
+               .map(|(idx, txout)| (idx as u32, txout))
+}
+
+/// Returns the witness required to satisfy and spend an anchor input.
+pub fn build_anchor_input_witness(funding_key: &PublicKey, funding_sig: &Signature) -> Witness {
+       let anchor_redeem_script = chan_utils::get_anchor_redeemscript(funding_key);
+       let mut funding_sig = funding_sig.serialize_der().to_vec();
+       funding_sig.push(EcdsaSighashType::All as u8);
+       Witness::from_vec(vec![funding_sig, anchor_redeem_script.to_bytes()])
+}
+
 /// Per-channel data used to build transactions in conjunction with the per-commitment data (CommitmentTransaction).
 /// The fields are organized by holder/counterparty.
 ///
@@ -882,6 +900,7 @@ impl Deref for HolderCommitmentTransaction {
        fn deref(&self) -> &Self::Target { &self.inner }
 }
 
+impl Eq for HolderCommitmentTransaction {}
 impl PartialEq for HolderCommitmentTransaction {
        // We dont care whether we are signed in equality comparison
        fn eq(&self, o: &Self) -> bool {
@@ -1007,7 +1026,7 @@ impl BuiltCommitmentTransaction {
 ///
 /// This class can be used inside a signer implementation to generate a signature given the relevant
 /// secret key.
-#[derive(Clone, Hash, PartialEq)]
+#[derive(Clone, Hash, PartialEq, Eq)]
 pub struct ClosingTransaction {
        to_holder_value_sat: u64,
        to_counterparty_value_sat: u64,
@@ -1147,6 +1166,7 @@ pub struct CommitmentTransaction {
        built: BuiltCommitmentTransaction,
 }
 
+impl Eq for CommitmentTransaction {}
 impl PartialEq for CommitmentTransaction {
        fn eq(&self, o: &Self) -> bool {
                let eq = self.commitment_number == o.commitment_number &&
index 15d46b04688930d03525b6347d6b714a28713b28..11434ce3a89f8a7d3bdef67e5547fb19489599c2 100644 (file)
@@ -2238,11 +2238,12 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
        let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(&nodes[0], nodes[1], 100000);
        let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(&nodes[1]);
 
-       // Do a really complicated dance to get an HTLC into the holding cell, with MonitorUpdateFailed
-       // set but AwaitingRemoteRevoke unset. When this test was written, any attempts to send an HTLC
-       // while MonitorUpdateFailed is set are immediately failed-backwards. Thus, the only way to get
-       // an AddHTLC into the holding cell is to add it while AwaitingRemoteRevoke is set but
-       // MonitorUpdateFailed is unset, and then swap the flags.
+       // Do a really complicated dance to get an HTLC into the holding cell, with
+       // MonitorUpdateInProgress set but AwaitingRemoteRevoke unset. When this test was written, any
+       // attempts to send an HTLC while MonitorUpdateInProgress is set are immediately
+       // failed-backwards. Thus, the only way to get an AddHTLC into the holding cell is to add it
+       // while AwaitingRemoteRevoke is set but MonitorUpdateInProgress is unset, and then swap the
+       // flags.
        //
        // We do this by:
        //  a) routing a payment from node B to node A,
@@ -2255,8 +2256,8 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
        //  e) delivering A's commitment_signed from (b) and the resulting B revoke_and_ack message,
        //     clearing AwaitingRemoteRevoke on node A.
        //
-       // Note that because, at the end, MonitorUpdateFailed is still set, the HTLC generated in (c)
-       // will not be freed from the holding cell.
+       // Note that because, at the end, MonitorUpdateInProgress is still set, the HTLC generated in
+       // (c) will not be freed from the holding cell.
        let (payment_preimage_0, payment_hash_0, _) = route_payment(&nodes[1], &[&nodes[0]], 100_000);
 
        nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
@@ -2745,3 +2746,221 @@ fn double_temp_error() {
        commitment_signed_dance!(nodes[0], nodes[1], commitment_signed_b2, false);
        expect_payment_sent!(nodes[0], payment_preimage_2);
 }
+
+fn do_test_outbound_reload_without_init_mon(use_0conf: bool) {
+       // Test that if the monitor update generated in funding_signed is stored async and we restart
+       // with the latest ChannelManager but the ChannelMonitor persistence never completed we happily
+       // drop the channel and move on.
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+
+       let persister: test_utils::TestPersister;
+       let new_chain_monitor: test_utils::TestChainMonitor;
+       let nodes_0_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
+
+       let mut chan_config = test_default_channel_config();
+       chan_config.manually_accept_inbound_channels = true;
+       chan_config.channel_handshake_limits.trust_own_funding_0conf = true;
+
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(chan_config), Some(chan_config)]);
+       let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
+
+       let events = nodes[1].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       match events[0] {
+               Event::OpenChannelRequest { temporary_channel_id, .. } => {
+                       if use_0conf {
+                               nodes[1].node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
+                       } else {
+                               nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
+                       }
+               },
+               _ => panic!("Unexpected event"),
+       };
+
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+
+       let (temporary_channel_id, funding_tx, ..) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43);
+
+       nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), funding_tx.clone()).unwrap();
+       check_added_monitors!(nodes[0], 0);
+
+       let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
+       check_added_monitors!(nodes[1], 1);
+
+       let bs_signed_locked = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(bs_signed_locked.len(), if use_0conf { 2 } else { 1 });
+       match &bs_signed_locked[0] {
+               MessageSendEvent::SendFundingSigned { msg, .. } => {
+                       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
+
+                       nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &msg);
+                       check_added_monitors!(nodes[0], 1);
+               }
+               _ => panic!("Unexpected event"),
+       }
+       if use_0conf {
+               match &bs_signed_locked[1] {
+                       MessageSendEvent::SendChannelReady { msg, .. } => {
+                               nodes[0].node.handle_channel_ready(&nodes[1].node.get_our_node_id(), &msg);
+                       }
+                       _ => panic!("Unexpected event"),
+               }
+       }
+
+       assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
+       assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
+       assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
+
+       // nodes[0] is now waiting on the first ChannelMonitor persistence to complete in order to
+       // broadcast the funding transaction. If nodes[0] restarts at this point with the
+       // ChannelMonitor lost, we should simply discard the channel.
+
+       // The test framework checks that watched_txn/outputs match the monitor set, which they will
+       // not, so we have to clear them here.
+       nodes[0].chain_source.watched_txn.lock().unwrap().clear();
+       nodes[0].chain_source.watched_outputs.lock().unwrap().clear();
+
+       let nodes_0_serialized = nodes[0].node.encode();
+       persister = test_utils::TestPersister::new();
+       let keys_manager = &chanmon_cfgs[0].keys_manager;
+       new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), nodes[0].logger, node_cfgs[0].fee_estimator, &persister, keys_manager);
+       nodes[0].chain_monitor = &new_chain_monitor;
+
+       let mut nodes_0_read = &nodes_0_serialized[..];
+       let config = UserConfig::default();
+       nodes_0_deserialized = {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+                       default_config: config,
+                       keys_manager,
+                       fee_estimator: node_cfgs[0].fee_estimator,
+                       chain_monitor: nodes[0].chain_monitor,
+                       tx_broadcaster: nodes[0].tx_broadcaster.clone(),
+                       logger: nodes[0].logger,
+                       channel_monitors: HashMap::new(),
+               }).unwrap().1
+       };
+       nodes[0].node = &nodes_0_deserialized;
+       assert!(nodes_0_read.is_empty());
+
+       check_closed_event!(nodes[0], 1, ClosureReason::DisconnectedPeer);
+       assert!(nodes[0].node.list_channels().is_empty());
+}
+
+#[test]
+fn test_outbound_reload_without_init_mon() {
+       do_test_outbound_reload_without_init_mon(true);
+       do_test_outbound_reload_without_init_mon(false);
+}
+
+fn do_test_inbound_reload_without_init_mon(use_0conf: bool, lock_commitment: bool) {
+       // Test that if the monitor update generated by funding_transaction_generated is stored async
+       // and we restart with the latest ChannelManager but the ChannelMonitor persistence never
+       // completed we happily drop the channel and move on.
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+
+       let persister: test_utils::TestPersister;
+       let new_chain_monitor: test_utils::TestChainMonitor;
+       let nodes_1_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
+
+       let mut chan_config = test_default_channel_config();
+       chan_config.manually_accept_inbound_channels = true;
+       chan_config.channel_handshake_limits.trust_own_funding_0conf = true;
+
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(chan_config), Some(chan_config)]);
+       let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
+
+       let events = nodes[1].node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       match events[0] {
+               Event::OpenChannelRequest { temporary_channel_id, .. } => {
+                       if use_0conf {
+                               nodes[1].node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
+                       } else {
+                               nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
+                       }
+               },
+               _ => panic!("Unexpected event"),
+       };
+
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+
+       let (temporary_channel_id, funding_tx, ..) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43);
+
+       nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), funding_tx.clone()).unwrap();
+       check_added_monitors!(nodes[0], 0);
+
+       let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
+       chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
+       check_added_monitors!(nodes[1], 1);
+
+       // nodes[1] happily sends its funding_signed even though its awaiting the persistence of the
+       // initial ChannelMonitor, but it will decline to send its channel_ready even if the funding
+       // transaction is confirmed.
+       let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
+
+       nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
+       check_added_monitors!(nodes[0], 1);
+
+       let as_funding_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
+       if lock_commitment {
+               confirm_transaction(&nodes[0], &as_funding_tx[0]);
+               confirm_transaction(&nodes[1], &as_funding_tx[0]);
+       }
+       if use_0conf || lock_commitment {
+               let as_ready = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReady, nodes[1].node.get_our_node_id());
+               nodes[1].node.handle_channel_ready(&nodes[0].node.get_our_node_id(), &as_ready);
+       }
+       assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
+
+       // nodes[1] is now waiting on the first ChannelMonitor persistence to complete in order to
+       // move the channel to ready (or is waiting on the funding transaction to confirm). If nodes[1]
+       // restarts at this point with the ChannelMonitor lost, we should simply discard the channel.
+
+       // The test framework checks that watched_txn/outputs match the monitor set, which they will
+       // not, so we have to clear them here.
+       nodes[1].chain_source.watched_txn.lock().unwrap().clear();
+       nodes[1].chain_source.watched_outputs.lock().unwrap().clear();
+
+       let nodes_1_serialized = nodes[1].node.encode();
+       persister = test_utils::TestPersister::new();
+       let keys_manager = &chanmon_cfgs[1].keys_manager;
+       new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[1].chain_source), nodes[1].tx_broadcaster.clone(), nodes[1].logger, node_cfgs[1].fee_estimator, &persister, keys_manager);
+       nodes[1].chain_monitor = &new_chain_monitor;
+
+       let mut nodes_1_read = &nodes_1_serialized[..];
+       let config = UserConfig::default();
+       nodes_1_deserialized = {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_1_read, ChannelManagerReadArgs {
+                       default_config: config,
+                       keys_manager,
+                       fee_estimator: node_cfgs[1].fee_estimator,
+                       chain_monitor: nodes[1].chain_monitor,
+                       tx_broadcaster: nodes[1].tx_broadcaster.clone(),
+                       logger: nodes[1].logger,
+                       channel_monitors: HashMap::new(),
+               }).unwrap().1
+       };
+       nodes[1].node = &nodes_1_deserialized;
+       assert!(nodes_1_read.is_empty());
+
+       check_closed_event!(nodes[1], 1, ClosureReason::DisconnectedPeer);
+       assert!(nodes[1].node.list_channels().is_empty());
+}
+
+#[test]
+fn test_inbound_reload_without_init_mon() {
+       do_test_inbound_reload_without_init_mon(true, true);
+       do_test_inbound_reload_without_init_mon(true, false);
+       do_test_inbound_reload_without_init_mon(false, true);
+       do_test_inbound_reload_without_init_mon(false, false);
+}
index 48a701e3b04fb712772a3a9a293536e839ee6de4..cbd04ccf2a072d880b87a3f8a0958405ce8d1c4e 100644 (file)
@@ -273,9 +273,9 @@ enum ChannelState {
        /// dance.
        PeerDisconnected = 1 << 7,
        /// Flag which is set on ChannelFunded, FundingCreated, and FundingSent indicating the user has
-       /// told us they failed to update our ChannelMonitor somewhere and we should pause sending any
-       /// outbound messages until they've managed to do so.
-       MonitorUpdateFailed = 1 << 8,
+       /// told us a ChannelMonitor update is pending async persistence somewhere and we should pause
+       /// sending any outbound messages until they've managed to finish.
+       MonitorUpdateInProgress = 1 << 8,
        /// Flag which implies that we have sent a commitment_signed but are awaiting the responding
        /// revoke_and_ack message. During this time period, we can't generate new commitment_signed
        /// messages as then we will be unable to determine which HTLCs they included in their
@@ -295,7 +295,7 @@ enum ChannelState {
        ShutdownComplete = 4096,
 }
 const BOTH_SIDES_SHUTDOWN_MASK: u32 = ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32;
-const MULTI_STATE_FLAGS: u32 = BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32;
+const MULTI_STATE_FLAGS: u32 = BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32;
 
 pub const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
 
@@ -1776,7 +1776,7 @@ impl<Signer: Sign> Channel<Signer> {
        where L::Target: Logger {
                // Assert that we'll add the HTLC claim to the holding cell in `get_update_fulfill_htlc`
                // (see equivalent if condition there).
-               assert!(self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32) != 0);
+               assert!(self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32) != 0);
                let mon_update_id = self.latest_monitor_update_id; // Forget the ChannelMonitor update
                let fulfill_resp = self.get_update_fulfill_htlc(htlc_id_arg, payment_preimage_arg, logger);
                self.latest_monitor_update_id = mon_update_id;
@@ -1846,7 +1846,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }],
                };
 
-               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 {
+               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 {
                        // Note that this condition is the same as the assertion in
                        // `claim_htlc_while_disconnected_dropping_mon_update` and must match exactly -
                        // `claim_htlc_while_disconnected_dropping_mon_update` would not work correctly if we
@@ -1971,7 +1971,7 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                // Now update local state:
-               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 {
+               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 {
                        for pending_update in self.holding_cell_htlc_updates.iter() {
                                match pending_update {
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => {
@@ -2258,7 +2258,7 @@ impl<Signer: Sign> Channel<Signer> {
                if !self.is_outbound() {
                        return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned()));
                }
-               if self.channel_state & !(ChannelState::MonitorUpdateFailed as u32) != ChannelState::FundingCreated as u32 {
+               if self.channel_state & !(ChannelState::MonitorUpdateInProgress as u32) != ChannelState::FundingCreated as u32 {
                        return Err(ChannelError::Close("Received funding_signed in strange state!".to_owned()));
                }
                if self.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
@@ -2316,7 +2316,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_bitcoin_tx.txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
 
-               assert_eq!(self.channel_state & (ChannelState::MonitorUpdateFailed as u32), 0); // We have no had any monitor(s) yet to fail update!
+               assert_eq!(self.channel_state & (ChannelState::MonitorUpdateInProgress as u32), 0); // We have no had any monitor(s) yet to fail update!
                self.channel_state = ChannelState::FundingSent as u32;
                self.cur_holder_commitment_transaction_number -= 1;
                self.cur_counterparty_commitment_transaction_number -= 1;
@@ -3078,7 +3078,7 @@ impl<Signer: Sign> Channel<Signer> {
                // send_commitment_no_status_check() next which will reset this to RAAFirst.
                self.resend_order = RAACommitmentOrder::CommitmentFirst;
 
-               if (self.channel_state & ChannelState::MonitorUpdateFailed as u32) != 0 {
+               if (self.channel_state & ChannelState::MonitorUpdateInProgress as u32) != 0 {
                        // In case we initially failed monitor updating without requiring a response, we need
                        // to make sure the RAA gets sent first.
                        self.monitor_pending_revoke_and_ack = true;
@@ -3125,7 +3125,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// returns `(None, Vec::new())`.
        pub fn maybe_free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger {
                if self.channel_state >= ChannelState::ChannelFunded as u32 &&
-                  (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) == 0 {
+                  (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)) == 0 {
                        self.free_holding_cell_htlcs(logger)
                } else { Ok((None, Vec::new())) }
        }
@@ -3133,7 +3133,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them
        /// fulfilling or failing the last pending HTLC)
        fn free_holding_cell_htlcs<L: Deref>(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger {
-               assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, 0);
+               assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, 0);
                if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() {
                        log_trace!(logger, "Freeing holding cell with {} HTLC updates{} in channel {}", self.holding_cell_htlc_updates.len(),
                                if self.holding_cell_update_fee.is_some() { " and a fee update" } else { "" }, log_bytes!(self.channel_id()));
@@ -3428,7 +3428,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
 
-               if (self.channel_state & ChannelState::MonitorUpdateFailed as u32) == ChannelState::MonitorUpdateFailed as u32 {
+               if (self.channel_state & ChannelState::MonitorUpdateInProgress as u32) == ChannelState::MonitorUpdateInProgress as u32 {
                        // We can't actually generate a new commitment transaction (incl by freeing holding
                        // cells) while we can't update the monitor, so we just return what we have.
                        if require_commitment {
@@ -3557,7 +3557,7 @@ impl<Signer: Sign> Channel<Signer> {
                        return None;
                }
 
-               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 {
+               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 {
                        self.holding_cell_update_fee = Some(feerate_per_kw);
                        return None;
                }
@@ -3677,15 +3677,15 @@ impl<Signer: Sign> Channel<Signer> {
                self.monitor_pending_forwards.append(&mut pending_forwards);
                self.monitor_pending_failures.append(&mut pending_fails);
                self.monitor_pending_finalized_fulfills.append(&mut pending_finalized_claimed_htlcs);
-               self.channel_state |= ChannelState::MonitorUpdateFailed as u32;
+               self.channel_state |= ChannelState::MonitorUpdateInProgress as u32;
        }
 
        /// Indicates that the latest ChannelMonitor update has been committed by the client
        /// successfully and we should restore normal operation. Returns messages which should be sent
        /// to the remote side.
        pub fn monitor_updating_restored<L: Deref>(&mut self, logger: &L, node_pk: PublicKey, genesis_block_hash: BlockHash, best_block_height: u32) -> MonitorRestoreUpdates where L::Target: Logger {
-               assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, ChannelState::MonitorUpdateFailed as u32);
-               self.channel_state &= !(ChannelState::MonitorUpdateFailed as u32);
+               assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, ChannelState::MonitorUpdateInProgress as u32);
+               self.channel_state &= !(ChannelState::MonitorUpdateInProgress as u32);
 
                // If we're past (or at) the FundingSent stage on an outbound channel, try to
                // (re-)broadcast the funding transaction as we may have declined to broadcast it when we
@@ -3700,9 +3700,9 @@ impl<Signer: Sign> Channel<Signer> {
                        funding_broadcastable = None;
                }
 
-               // We will never broadcast the funding transaction when we're in MonitorUpdateFailed (and
-               // we assume the user never directly broadcasts the funding transaction and waits for us to
-               // do it). Thus, we can only ever hit monitor_pending_channel_ready when we're
+               // We will never broadcast the funding transaction when we're in MonitorUpdateInProgress
+               // (and we assume the user never directly broadcasts the funding transaction and waits for
+               // us to do it). Thus, we can only ever hit monitor_pending_channel_ready when we're
                // * an inbound channel that failed to persist the monitor on funding_created and we got
                //   the funding transaction confirmed before the monitor was persisted, or
                // * a 0-conf channel and intended to send the channel_ready before any broadcast at all.
@@ -3941,7 +3941,7 @@ impl<Signer: Sign> Channel<Signer> {
                if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
                        // If we're waiting on a monitor update, we shouldn't re-send any channel_ready's.
                        if self.channel_state & (ChannelState::OurChannelReady as u32) == 0 ||
-                                       self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
+                                       self.channel_state & (ChannelState::MonitorUpdateInProgress as u32) != 0 {
                                if msg.next_remote_commitment_number != 0 {
                                        return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent channel_ready yet".to_owned()));
                                }
@@ -3975,7 +3975,7 @@ impl<Signer: Sign> Channel<Signer> {
                        // Note that if we need to repeat our ChannelReady we'll do that in the next if block.
                        None
                } else if msg.next_remote_commitment_number + 1 == (INITIAL_COMMITMENT_NUMBER - 1) - self.cur_holder_commitment_transaction_number {
-                       if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
+                       if self.channel_state & (ChannelState::MonitorUpdateInProgress as u32) != 0 {
                                self.monitor_pending_revoke_and_ack = true;
                                None
                        } else {
@@ -3992,7 +3992,7 @@ impl<Signer: Sign> Channel<Signer> {
                let next_counterparty_commitment_number = INITIAL_COMMITMENT_NUMBER - self.cur_counterparty_commitment_transaction_number + if (self.channel_state & ChannelState::AwaitingRemoteRevoke as u32) != 0 { 1 } else { 0 };
 
                let channel_ready = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.cur_holder_commitment_transaction_number == 1 {
-                       // We should never have to worry about MonitorUpdateFailed resending ChannelReady
+                       // We should never have to worry about MonitorUpdateInProgress resending ChannelReady
                        let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
                        Some(msgs::ChannelReady {
                                channel_id: self.channel_id(),
@@ -4008,7 +4008,7 @@ impl<Signer: Sign> Channel<Signer> {
                                log_debug!(logger, "Reconnected channel {} with no loss", log_bytes!(self.channel_id()));
                        }
 
-                       if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) == 0 {
+                       if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) == 0 {
                                // We're up-to-date and not waiting on a remote revoke (if we are our
                                // channel_reestablish should result in them sending a revoke_and_ack), but we may
                                // have received some updates while we were disconnected. Free the holding cell
@@ -4055,7 +4055,7 @@ impl<Signer: Sign> Channel<Signer> {
                                log_debug!(logger, "Reconnected channel {} with only lost remote commitment tx", log_bytes!(self.channel_id()));
                        }
 
-                       if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
+                       if self.channel_state & (ChannelState::MonitorUpdateInProgress as u32) != 0 {
                                self.monitor_pending_commitment_signed = true;
                                Ok(ReestablishResponses {
                                        channel_ready, shutdown_msg, announcement_sigs,
@@ -4137,7 +4137,7 @@ impl<Signer: Sign> Channel<Signer> {
                self.pending_inbound_htlcs.is_empty() && self.pending_outbound_htlcs.is_empty() &&
                        self.channel_state &
                                (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::AwaitingRemoteRevoke as u32 |
-                                ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)
+                                ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)
                                == BOTH_SIDES_SHUTDOWN_MASK &&
                        self.pending_update_fee.is_none()
        }
@@ -4333,7 +4333,7 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ChannelError::Close("Remote tried to send a closing_signed when we were supposed to propose the first one".to_owned()));
                }
 
-               if self.channel_state & ChannelState::MonitorUpdateFailed as u32 != 0 {
+               if self.channel_state & ChannelState::MonitorUpdateInProgress as u32 != 0 {
                        self.pending_counterparty_closing_signed = Some(msg.clone());
                        return Ok((None, None));
                }
@@ -4780,7 +4780,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// Returns true if this channel has been marked as awaiting a monitor update to move forward.
        /// Allowed in any state (including after shutdown)
        pub fn is_awaiting_monitor_update(&self) -> bool {
-               (self.channel_state & ChannelState::MonitorUpdateFailed as u32) != 0
+               (self.channel_state & ChannelState::MonitorUpdateInProgress as u32) != 0
        }
 
        /// Returns true if funding_created was sent/received.
@@ -4788,6 +4788,42 @@ impl<Signer: Sign> Channel<Signer> {
                self.channel_state >= ChannelState::FundingSent as u32
        }
 
+       /// Returns true if the channel is awaiting the persistence of the initial ChannelMonitor.
+       /// If the channel is outbound, this implies we have not yet broadcasted the funding
+       /// transaction. If the channel is inbound, this implies simply that the channel has not
+       /// advanced state.
+       pub fn is_awaiting_initial_mon_persist(&self) -> bool {
+               if !self.is_awaiting_monitor_update() { return false; }
+               if self.channel_state &
+                       !(ChannelState::TheirChannelReady as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)
+                               == ChannelState::FundingSent as u32 {
+                       // If we're not a 0conf channel, we'll be waiting on a monitor update with only
+                       // FundingSent set, though our peer could have sent their channel_ready.
+                       debug_assert!(self.minimum_depth.unwrap_or(1) > 0);
+                       return true;
+               }
+               if self.cur_holder_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 &&
+                       self.cur_counterparty_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 {
+                       // If we're a 0-conf channel, we'll move beyond FundingSent immediately even while
+                       // waiting for the initial monitor persistence. Thus, we check if our commitment
+                       // transaction numbers have both been iterated only exactly once (for the
+                       // funding_signed), and we're awaiting monitor update.
+                       //
+                       // If we got here, we shouldn't have yet broadcasted the funding transaction (as the
+                       // only way to get an awaiting-monitor-update state during initial funding is if the
+                       // initial monitor persistence is still pending).
+                       //
+                       // Because deciding we're awaiting initial broadcast spuriously could result in
+                       // funds-loss (as we don't have a monitor, but have the funding transaction confirmed),
+                       // we hard-assert here, even in production builds.
+                       if self.is_outbound() { assert!(self.funding_transaction.is_some()); }
+                       assert!(self.monitor_pending_channel_ready);
+                       assert_eq!(self.latest_monitor_update_id, 0);
+                       return true;
+               }
+               false
+       }
+
        /// Returns true if our channel_ready has been sent
        pub fn is_our_channel_ready(&self) -> bool {
                (self.channel_state & ChannelState::OurChannelReady as u32) != 0 || self.channel_state >= ChannelState::ChannelFunded as u32
@@ -4866,7 +4902,7 @@ impl<Signer: Sign> Channel<Signer> {
                };
 
                if need_commitment_update {
-                       if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
+                       if self.channel_state & (ChannelState::MonitorUpdateInProgress as u32) == 0 {
                                if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
                                        let next_per_commitment_point =
                                                self.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.secp_ctx);
@@ -5440,9 +5476,9 @@ impl<Signer: Sign> Channel<Signer> {
        /// * In cases where we're waiting on the remote peer to send us a revoke_and_ack, we
        ///   wouldn't be able to determine what they actually ACK'ed if we have two sets of updates
        ///   awaiting ACK.
-       /// * In cases where we're marked MonitorUpdateFailed, we cannot commit to a new state as we
-       ///   may not yet have sent the previous commitment update messages and will need to regenerate
-       ///   them.
+       /// * In cases where we're marked MonitorUpdateInProgress, we cannot commit to a new state as
+       ///   we may not yet have sent the previous commitment update messages and will need to
+       ///   regenerate them.
        ///
        /// You MUST call send_commitment prior to calling any other methods on this Channel!
        ///
@@ -5543,7 +5579,7 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                // Now update local state:
-               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 {
+               if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 {
                        self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::AddHTLC {
                                amount_msat,
                                payment_hash,
@@ -5590,7 +5626,7 @@ impl<Signer: Sign> Channel<Signer> {
                if (self.channel_state & (ChannelState::PeerDisconnected as u32)) == (ChannelState::PeerDisconnected as u32) {
                        panic!("Cannot create commitment tx while disconnected, as send_htlc will have returned an Err so a send_commitment precondition has been violated");
                }
-               if (self.channel_state & (ChannelState::MonitorUpdateFailed as u32)) == (ChannelState::MonitorUpdateFailed as u32) {
+               if (self.channel_state & (ChannelState::MonitorUpdateInProgress as u32)) == (ChannelState::MonitorUpdateInProgress as u32) {
                        panic!("Cannot create commitment tx while awaiting monitor update unfreeze, as send_htlc will have returned an Err so a send_commitment precondition has been violated");
                }
                let mut have_updates = self.is_outbound() && self.pending_update_fee.is_some();
@@ -5782,7 +5818,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
                assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
-               if self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32) != 0 {
+               if self.channel_state & (ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32) != 0 {
                        return Err(APIError::ChannelUnavailable{err: "Cannot begin shutdown while peer is disconnected or we're waiting on a monitor update, maybe force-close instead?".to_owned()});
                }
 
index f234ad9f91f555075804d87db115d98193f09619..fa98e8e9b3fe3a859837c89bbcc468059594b7e5 100644 (file)
@@ -1971,7 +1971,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                log_debug!(self.logger, "Finishing force-closure of channel with {} HTLCs to fail", failed_htlcs.len());
                for htlc_source in failed_htlcs.drain(..) {
                        let (source, payment_hash, counterparty_node_id, channel_id) = htlc_source;
-                       let receiver = HTLCDestination::NextHopChannel { node_id: Some(counterparty_node_id), channel_id: channel_id };
+                       let receiver = HTLCDestination::NextHopChannel { node_id: Some(counterparty_node_id), channel_id };
                        self.fail_htlc_backwards_internal(source, &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }, receiver);
                }
                if let Some((funding_txo, monitor_update)) = monitor_update_option {
@@ -3862,7 +3862,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                }
                                                        } else {
                                                                events::Event::ProbeFailed {
-                                                                       payment_id: payment_id,
+                                                                       payment_id,
                                                                        payment_hash: payment_hash.clone(),
                                                                        path: path.clone(),
                                                                        short_channel_id,
@@ -3909,7 +3909,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
 
                                                if self.payment_is_probe(payment_hash, &payment_id) {
                                                        events::Event::ProbeFailed {
-                                                               payment_id: payment_id,
+                                                               payment_id,
                                                                payment_hash: payment_hash.clone(),
                                                                path: path.clone(),
                                                                short_channel_id: Some(scid),
@@ -6499,7 +6499,7 @@ impl Readable for HTLCSource {
                                }
                                Ok(HTLCSource::OutboundRoute {
                                        session_priv: session_priv.0.unwrap(),
-                                       first_hop_htlc_msat: first_hop_htlc_msat,
+                                       first_hop_htlc_msat,
                                        path: path.unwrap(),
                                        payment_id: payment_id.unwrap(),
                                        payment_secret,
@@ -6921,6 +6921,16 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                        }
                                        by_id.insert(channel.channel_id(), channel);
                                }
+                       } else if channel.is_awaiting_initial_mon_persist() {
+                               // If we were persisted and shut down while the initial ChannelMonitor persistence
+                               // was in-progress, we never broadcasted the funding transaction and can still
+                               // safely discard the channel.
+                               let _ = channel.force_shutdown(false);
+                               channel_closures.push(events::Event::ChannelClosed {
+                                       channel_id: channel.channel_id(),
+                                       user_channel_id: channel.get_user_id(),
+                                       reason: ClosureReason::DisconnectedPeer,
+                               });
                        } else {
                                log_error!(args.logger, "Missing ChannelMonitor for channel {} needed by ChannelManager.", log_bytes!(channel.channel_id()));
                                log_error!(args.logger, " The chain::Watch API *requires* that monitors are persisted durably before returning,");
index 43dfef5d188bc51d8d0aa65df6965ef9ccaf7b1a..c3a57791c08b079840ea704989e4d1a616969f32 100644 (file)
@@ -1126,7 +1126,7 @@ impl SendEvent {
                assert!(updates.update_fail_htlcs.is_empty());
                assert!(updates.update_fail_malformed_htlcs.is_empty());
                assert!(updates.update_fee.is_none());
-               SendEvent { node_id: node_id, msgs: updates.update_add_htlcs, commitment_msg: updates.commitment_signed }
+               SendEvent { node_id, msgs: updates.update_add_htlcs, commitment_msg: updates.commitment_signed }
        }
 
        pub fn from_event(event: MessageSendEvent) -> SendEvent {
index 4c103e1199dfdf3c05d41c2ca3aa1d60de5fd384..6295fb705ae7712ddc60ee6c65ce1df15b6d4d36 100644 (file)
@@ -50,7 +50,7 @@ use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 pub(crate) const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
 
 /// An error in decoding a message or struct.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum DecodeError {
        /// A version byte specified something we don't know how to handle.
        /// Includes unknown realm byte in an OnionHopData packet
@@ -73,7 +73,7 @@ pub enum DecodeError {
 }
 
 /// An init message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Init {
        /// The relevant features which the sender supports
        pub features: InitFeatures,
@@ -85,7 +85,7 @@ pub struct Init {
 }
 
 /// An error message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ErrorMessage {
        /// The channel ID involved in the error.
        ///
@@ -100,7 +100,7 @@ pub struct ErrorMessage {
 }
 
 /// A warning message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct WarningMessage {
        /// The channel ID involved in the warning.
        ///
@@ -114,7 +114,7 @@ pub struct WarningMessage {
 }
 
 /// A ping message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Ping {
        /// The desired response length
        pub ponglen: u16,
@@ -124,7 +124,7 @@ pub struct Ping {
 }
 
 /// A pong message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Pong {
        /// The pong packet size.
        /// This field is not sent on the wire. byteslen zeros are sent.
@@ -132,7 +132,7 @@ pub struct Pong {
 }
 
 /// An open_channel message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct OpenChannel {
        /// The genesis hash of the blockchain where the channel is to be opened
        pub chain_hash: BlockHash,
@@ -179,7 +179,7 @@ pub struct OpenChannel {
 }
 
 /// An accept_channel message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct AcceptChannel {
        /// A temporary channel ID, until the funding outpoint is announced
        pub temporary_channel_id: [u8; 32],
@@ -220,7 +220,7 @@ pub struct AcceptChannel {
 }
 
 /// A funding_created message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct FundingCreated {
        /// A temporary channel ID, until the funding is established
        pub temporary_channel_id: [u8; 32],
@@ -233,7 +233,7 @@ pub struct FundingCreated {
 }
 
 /// A funding_signed message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct FundingSigned {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -242,7 +242,7 @@ pub struct FundingSigned {
 }
 
 /// A channel_ready message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelReady {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -254,7 +254,7 @@ pub struct ChannelReady {
 }
 
 /// A shutdown message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Shutdown {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -266,7 +266,7 @@ pub struct Shutdown {
 /// The minimum and maximum fees which the sender is willing to place on the closing transaction.
 /// This is provided in [`ClosingSigned`] by both sides to indicate the fee range they are willing
 /// to use.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ClosingSignedFeeRange {
        /// The minimum absolute fee, in satoshis, which the sender is willing to place on the closing
        /// transaction.
@@ -277,7 +277,7 @@ pub struct ClosingSignedFeeRange {
 }
 
 /// A closing_signed message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ClosingSigned {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -291,7 +291,7 @@ pub struct ClosingSigned {
 }
 
 /// An update_add_htlc message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateAddHTLC {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -307,7 +307,7 @@ pub struct UpdateAddHTLC {
 }
 
  /// An onion message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct OnionMessage {
        /// Used in decrypting the onion packet's payload.
        pub blinding_point: PublicKey,
@@ -315,7 +315,7 @@ pub struct OnionMessage {
 }
 
 /// An update_fulfill_htlc message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFulfillHTLC {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -326,7 +326,7 @@ pub struct UpdateFulfillHTLC {
 }
 
 /// An update_fail_htlc message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFailHTLC {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -336,7 +336,7 @@ pub struct UpdateFailHTLC {
 }
 
 /// An update_fail_malformed_htlc message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFailMalformedHTLC {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -348,7 +348,7 @@ pub struct UpdateFailMalformedHTLC {
 }
 
 /// A commitment_signed message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct CommitmentSigned {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -359,7 +359,7 @@ pub struct CommitmentSigned {
 }
 
 /// A revoke_and_ack message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct RevokeAndACK {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -370,7 +370,7 @@ pub struct RevokeAndACK {
 }
 
 /// An update_fee message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFee {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -378,7 +378,7 @@ pub struct UpdateFee {
        pub feerate_per_kw: u32,
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 /// Proof that the sender knows the per-commitment secret of the previous commitment transaction.
 /// This is used to convince the recipient that the channel is at a certain commitment
 /// number even if they lost that data due to a local failure.  Of course, the peer may lie
@@ -392,7 +392,7 @@ pub struct DataLossProtect {
 }
 
 /// A channel_reestablish message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelReestablish {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -405,7 +405,7 @@ pub struct ChannelReestablish {
 }
 
 /// An announcement_signatures message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct AnnouncementSignatures {
        /// The channel ID
        pub channel_id: [u8; 32],
@@ -418,7 +418,7 @@ pub struct AnnouncementSignatures {
 }
 
 /// An address which can be used to connect to a remote peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum NetAddress {
        /// An IPv4 address/port on which the peer is listening.
        IPv4 {
@@ -573,7 +573,7 @@ impl Readable for NetAddress {
 
 
 /// The unsigned part of a node_announcement
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UnsignedNodeAnnouncement {
        /// The advertised features
        pub features: NodeFeatures,
@@ -592,7 +592,7 @@ pub struct UnsignedNodeAnnouncement {
        pub(crate) excess_address_data: Vec<u8>,
        pub(crate) excess_data: Vec<u8>,
 }
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 /// A node_announcement message to be sent or received from a peer
 pub struct NodeAnnouncement {
        /// The signature by the node key
@@ -602,7 +602,7 @@ pub struct NodeAnnouncement {
 }
 
 /// The unsigned part of a channel_announcement
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UnsignedChannelAnnouncement {
        /// The advertised channel features
        pub features: ChannelFeatures,
@@ -621,7 +621,7 @@ pub struct UnsignedChannelAnnouncement {
        pub(crate) excess_data: Vec<u8>,
 }
 /// A channel_announcement message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelAnnouncement {
        /// Authentication of the announcement by the first public node
        pub node_signature_1: Signature,
@@ -636,7 +636,7 @@ pub struct ChannelAnnouncement {
 }
 
 /// The unsigned part of a channel_update
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UnsignedChannelUpdate {
        /// The genesis hash of the blockchain where the channel is to be opened
        pub chain_hash: BlockHash,
@@ -669,7 +669,7 @@ pub struct UnsignedChannelUpdate {
        pub excess_data: Vec<u8>,
 }
 /// A channel_update message to be sent or received from a peer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelUpdate {
        /// A signature of the channel update
        pub signature: Signature,
@@ -681,7 +681,7 @@ pub struct ChannelUpdate {
 /// UTXOs in a range of blocks. The recipient of a query makes a best
 /// effort to reply to the query using one or more reply_channel_range
 /// messages.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct QueryChannelRange {
        /// The genesis hash of the blockchain being queried
        pub chain_hash: BlockHash,
@@ -698,7 +698,7 @@ pub struct QueryChannelRange {
 /// not be a perfect view of the network. The short_channel_ids in the
 /// reply are encoded. We only support encoding_type=0 uncompressed
 /// serialization and do not support encoding_type=1 zlib serialization.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ReplyChannelRange {
        /// The genesis hash of the blockchain being queried
        pub chain_hash: BlockHash,
@@ -720,7 +720,7 @@ pub struct ReplyChannelRange {
 /// reply_short_channel_ids_end message. The short_channel_ids sent in
 /// this query are encoded. We only support encoding_type=0 uncompressed
 /// serialization and do not support encoding_type=1 zlib serialization.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct QueryShortChannelIds {
        /// The genesis hash of the blockchain being queried
        pub chain_hash: BlockHash,
@@ -732,7 +732,7 @@ pub struct QueryShortChannelIds {
 /// query_short_channel_ids message. The query recipient makes a best
 /// effort to respond based on their local network view which may not be
 /// a perfect view of the network.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ReplyShortChannelIdsEnd {
        /// The genesis hash of the blockchain that was queried
        pub chain_hash: BlockHash,
@@ -744,7 +744,7 @@ pub struct ReplyShortChannelIdsEnd {
 /// A gossip_timestamp_filter message is used by a node to request
 /// gossip relay for messages in the requested time range when the
 /// gossip_queries feature has been negotiated.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct GossipTimestampFilter {
        /// The genesis hash of the blockchain for channel and node information
        pub chain_hash: BlockHash,
@@ -805,7 +805,7 @@ pub struct LightningError {
 
 /// Struct used to return values from revoke_and_ack messages, containing a bunch of commitment
 /// transaction updates if they were pending.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct CommitmentUpdate {
        /// update_add_htlc messages which should be sent
        pub update_add_htlcs: Vec<UpdateAddHTLC>,
@@ -826,7 +826,7 @@ pub struct CommitmentUpdate {
 /// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a
 /// separate enum type for them.
 /// (C-not exported) due to a free generic in T
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum OptionalField<T> {
        /// Optional field is included in message
        Present(T),
@@ -1083,6 +1083,7 @@ impl onion_utils::Packet for OnionPacket {
        }
 }
 
+impl Eq for OnionPacket { }
 impl PartialEq for OnionPacket {
        fn eq(&self, other: &OnionPacket) -> bool {
                for (i, j) in self.hop_data.iter().zip(other.hop_data.iter()) {
@@ -1100,7 +1101,7 @@ impl fmt::Debug for OnionPacket {
        }
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub(crate) struct OnionErrorPacket {
        // This really should be a constant size slice, but the spec lets these things be up to 128KB?
        // (TODO) We limit it in decode to much lower...
index d1a9744ed332db85c73aefe118a432eeb8032b02..80db0dc0b07e269233afaaad6058ae36aaef288a 100644 (file)
@@ -21,11 +21,11 @@ use ln::features::{InitFeatures, NodeFeatures};
 use ln::msgs;
 use ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler};
 use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager};
-use util::ser::{VecWriter, Writeable, Writer};
+use util::ser::{MaybeReadableArgs, VecWriter, Writeable, Writer};
 use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
 use ln::wire;
 use ln::wire::Encode;
-use onion_message::{SimpleArcOnionMessenger, SimpleRefOnionMessenger};
+use onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
 use routing::gossip::{NetworkGraph, P2PGossipSync};
 use util::atomic_counter::AtomicCounter;
 use util::crypto::sign;
@@ -95,6 +95,23 @@ impl OnionMessageHandler for IgnoringMessageHandler {
                InitFeatures::empty()
        }
 }
+impl CustomOnionMessageHandler for IgnoringMessageHandler {
+       type CustomMessage = Infallible;
+       fn handle_custom_message(&self, _msg: Self::CustomMessage) {
+               // Since we always return `None` in the read the handle method should never be called.
+               unreachable!();
+       }
+}
+impl MaybeReadableArgs<u64> for Infallible {
+       fn read<R: io::Read>(_buffer: &mut R, _msg_type: u64) -> Result<Option<Self>, msgs::DecodeError> where Self: Sized {
+               Ok(None)
+       }
+}
+
+impl CustomOnionMessageContents for Infallible {
+       fn tlv_type(&self) -> u64 { unreachable!(); }
+}
+
 impl Deref for IgnoringMessageHandler {
        type Target = IgnoringMessageHandler;
        fn deref(&self) -> &Self { self }
index 09363b6b51749f033bb482db1ac7b50b28ffaaf2..7b7125891dd08819d821c8f8d2c434076aa63b6b 100644 (file)
@@ -18,7 +18,7 @@ use io;
 /// A script pubkey for shutting down a channel as defined by [BOLT #2].
 ///
 /// [BOLT #2]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub struct ShutdownScript(ShutdownScriptImpl);
 
 /// An error occurring when converting from [`Script`] to [`ShutdownScript`].
@@ -30,7 +30,7 @@ pub struct InvalidShutdownScript {
        pub script: Script
 }
 
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 enum ShutdownScriptImpl {
        /// [`PublicKey`] used to form a P2WPKH script pubkey. Used to support backward-compatible
        /// serialization.
index 22389bf520393eae77daea625ade73682e6a38c1..66ea62bbcec05a7f989f611c8876637822718c6f 100644 (file)
 
 use chain::keysinterface::{KeysInterface, Recipient};
 use ln::features::InitFeatures;
-use ln::msgs::{self, OnionMessageHandler};
-use super::{BlindedRoute, Destination, OnionMessenger, SendError};
+use ln::msgs::{self, DecodeError, OnionMessageHandler};
+use super::{BlindedRoute, CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError};
 use util::enforcing_trait_impls::EnforcingSigner;
+use util::ser::{MaybeReadableArgs, Writeable, Writer};
 use util::test_utils;
 
 use bitcoin::network::constants::Network;
 use bitcoin::secp256k1::{PublicKey, Secp256k1};
 
+use io;
 use sync::Arc;
 
 struct MessengerNode {
        keys_manager: Arc<test_utils::TestKeysInterface>,
-       messenger: OnionMessenger<EnforcingSigner, Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestLogger>>,
+       messenger: OnionMessenger<EnforcingSigner, Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestLogger>, Arc<TestCustomMessageHandler>>,
        logger: Arc<test_utils::TestLogger>,
 }
 
@@ -34,6 +36,43 @@ impl MessengerNode {
        }
 }
 
+#[derive(Clone)]
+struct TestCustomMessage {}
+
+const CUSTOM_MESSAGE_TYPE: u64 = 4242;
+const CUSTOM_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
+
+impl CustomOnionMessageContents for TestCustomMessage {
+       fn tlv_type(&self) -> u64 {
+               CUSTOM_MESSAGE_TYPE
+       }
+}
+
+impl Writeable for TestCustomMessage {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               Ok(CUSTOM_MESSAGE_CONTENTS.write(w)?)
+       }
+}
+
+impl MaybeReadableArgs<u64> for TestCustomMessage {
+       fn read<R: io::Read>(buffer: &mut R, message_type: u64) -> Result<Option<Self>, DecodeError> where Self: Sized {
+               if message_type == CUSTOM_MESSAGE_TYPE {
+                       let mut buf = Vec::new();
+                       buffer.read_to_end(&mut buf)?;
+                       assert_eq!(buf, CUSTOM_MESSAGE_CONTENTS);
+                       return Ok(Some(TestCustomMessage {}))
+               }
+               Ok(None)
+       }
+}
+
+struct TestCustomMessageHandler {}
+
+impl CustomOnionMessageHandler for TestCustomMessageHandler {
+       type CustomMessage = TestCustomMessage;
+       fn handle_custom_message(&self, _msg: Self::CustomMessage) {}
+}
+
 fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
        let mut nodes = Vec::new();
        for i in 0..num_messengers {
@@ -42,7 +81,7 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
                let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet));
                nodes.push(MessengerNode {
                        keys_manager: keys_manager.clone(),
-                       messenger: OnionMessenger::new(keys_manager, logger.clone()),
+                       messenger: OnionMessenger::new(keys_manager, logger.clone(), Arc::new(TestCustomMessageHandler {})),
                        logger,
                });
        }
@@ -80,38 +119,42 @@ fn pass_along_path(path: &Vec<MessengerNode>, expected_path_id: Option<[u8; 32]>
 #[test]
 fn one_hop() {
        let nodes = create_nodes(2);
+       let test_msg = OnionMessageContents::Custom(TestCustomMessage {});
 
-       nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap();
+       nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), test_msg, None).unwrap();
        pass_along_path(&nodes, None);
 }
 
 #[test]
 fn two_unblinded_hops() {
        let nodes = create_nodes(3);
+       let test_msg = OnionMessageContents::Custom(TestCustomMessage {});
 
-       nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk()], Destination::Node(nodes[2].get_node_pk()), None).unwrap();
+       nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk()], Destination::Node(nodes[2].get_node_pk()), test_msg, None).unwrap();
        pass_along_path(&nodes, None);
 }
 
 #[test]
 fn two_unblinded_two_blinded() {
        let nodes = create_nodes(5);
+       let test_msg = OnionMessageContents::Custom(TestCustomMessage {});
 
        let secp_ctx = Secp256k1::new();
        let blinded_route = BlindedRoute::new(&[nodes[3].get_node_pk(), nodes[4].get_node_pk()], &*nodes[4].keys_manager, &secp_ctx).unwrap();
 
-       nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], Destination::BlindedRoute(blinded_route), None).unwrap();
+       nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], Destination::BlindedRoute(blinded_route), test_msg, None).unwrap();
        pass_along_path(&nodes, None);
 }
 
 #[test]
 fn three_blinded_hops() {
        let nodes = create_nodes(4);
+       let test_msg = OnionMessageContents::Custom(TestCustomMessage {});
 
        let secp_ctx = Secp256k1::new();
        let blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap();
 
-       nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), None).unwrap();
+       nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), test_msg, None).unwrap();
        pass_along_path(&nodes, None);
 }
 
@@ -119,10 +162,11 @@ fn three_blinded_hops() {
 fn too_big_packet_error() {
        // Make sure we error as expected if a packet is too big to send.
        let nodes = create_nodes(2);
+       let test_msg = OnionMessageContents::Custom(TestCustomMessage {});
 
        let hop_node_id = nodes[1].get_node_pk();
        let hops = [hop_node_id; 400];
-       let err = nodes[0].messenger.send_onion_message(&hops, Destination::Node(hop_node_id), None).unwrap_err();
+       let err = nodes[0].messenger.send_onion_message(&hops, Destination::Node(hop_node_id), test_msg, None).unwrap_err();
        assert_eq!(err, SendError::TooBigPacket);
 }
 
@@ -130,53 +174,83 @@ fn too_big_packet_error() {
 fn invalid_blinded_route_error() {
        // Make sure we error as expected if a provided blinded route has 0 or 1 hops.
        let nodes = create_nodes(3);
+       let test_msg = TestCustomMessage {};
 
        // 0 hops
        let secp_ctx = Secp256k1::new();
        let mut blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], &*nodes[2].keys_manager, &secp_ctx).unwrap();
        blinded_route.blinded_hops.clear();
-       let err = nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), None).unwrap_err();
+       let err = nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), OnionMessageContents::Custom(test_msg.clone()), None).unwrap_err();
        assert_eq!(err, SendError::TooFewBlindedHops);
 
        // 1 hop
        let mut blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], &*nodes[2].keys_manager, &secp_ctx).unwrap();
        blinded_route.blinded_hops.remove(0);
        assert_eq!(blinded_route.blinded_hops.len(), 1);
-       let err = nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), None).unwrap_err();
+       let err = nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), OnionMessageContents::Custom(test_msg), None).unwrap_err();
        assert_eq!(err, SendError::TooFewBlindedHops);
 }
 
 #[test]
 fn reply_path() {
        let nodes = create_nodes(4);
+       let test_msg = TestCustomMessage {};
        let secp_ctx = Secp256k1::new();
 
        // Destination::Node
        let reply_path = BlindedRoute::new(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap();
-       nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], Destination::Node(nodes[3].get_node_pk()), Some(reply_path)).unwrap();
+       nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], Destination::Node(nodes[3].get_node_pk()), OnionMessageContents::Custom(test_msg.clone()), Some(reply_path)).unwrap();
        pass_along_path(&nodes, None);
        // Make sure the last node successfully decoded the reply path.
        nodes[3].logger.assert_log_contains(
                "lightning::onion_message::messenger".to_string(),
-               format!("Received an onion message with path_id: None and reply_path").to_string(), 1);
+               format!("Received an onion message with path_id None and a reply_path").to_string(), 1);
 
        // Destination::BlindedRoute
        let blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap();
        let reply_path = BlindedRoute::new(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap();
 
-       nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), Some(reply_path)).unwrap();
+       nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), OnionMessageContents::Custom(test_msg), Some(reply_path)).unwrap();
        pass_along_path(&nodes, None);
        nodes[3].logger.assert_log_contains(
                "lightning::onion_message::messenger".to_string(),
-               format!("Received an onion message with path_id: None and reply_path").to_string(), 2);
+               format!("Received an onion message with path_id None and a reply_path").to_string(), 2);
+}
+
+#[test]
+fn invalid_custom_message_type() {
+       let nodes = create_nodes(2);
+
+       struct InvalidCustomMessage{}
+       impl CustomOnionMessageContents for InvalidCustomMessage {
+               fn tlv_type(&self) -> u64 {
+                       // Onion message contents must have a TLV >= 64.
+                       63
+               }
+       }
+
+       impl Writeable for InvalidCustomMessage {
+               fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() }
+       }
+
+       impl MaybeReadableArgs<u64> for InvalidCustomMessage {
+               fn read<R: io::Read>(_buffer: &mut R, _message_type: u64) -> Result<Option<Self>, DecodeError> where Self: Sized {
+                       unreachable!()
+               }
+       }
+
+       let test_msg = OnionMessageContents::Custom(InvalidCustomMessage {});
+       let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), test_msg, None).unwrap_err();
+       assert_eq!(err, SendError::InvalidMessage);
 }
 
 #[test]
 fn peer_buffer_full() {
        let nodes = create_nodes(2);
+       let test_msg = TestCustomMessage {};
        for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger
-               nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap();
+               nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), OnionMessageContents::Custom(test_msg.clone()), None).unwrap();
        }
-       let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap_err();
+       let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), OnionMessageContents::Custom(test_msg), None).unwrap_err();
        assert_eq!(err, SendError::BufferFull);
 }
index e2409fc45d6530c22e9aa62c7061335204f6a81f..83e0311872b9c4ed562585d75c43396809913a60 100644 (file)
@@ -19,7 +19,9 @@ use chain::keysinterface::{InMemorySigner, KeysInterface, KeysManager, Recipient
 use ln::features::{InitFeatures, NodeFeatures};
 use ln::msgs::{self, OnionMessageHandler};
 use ln::onion_utils;
+use ln::peer_handler::IgnoringMessageHandler;
 use super::blinded_route::{BlindedRoute, ForwardTlvs, ReceiveTlvs};
+pub use super::packet::{CustomOnionMessageContents, OnionMessageContents};
 use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN};
 use super::utils;
 use util::events::OnionMessageProvider;
@@ -32,7 +34,7 @@ use prelude::*;
 
 /// A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
 /// used to retrieve invoices and fulfill invoice requests from [offers]. Currently, only sending
-/// and receiving empty onion messages is supported.
+/// and receiving custom onion messages is supported.
 ///
 /// # Example
 ///
@@ -41,8 +43,12 @@ use prelude::*;
 /// # use bitcoin::hashes::_export::_core::time::Duration;
 /// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
 /// # use lightning::chain::keysinterface::{InMemorySigner, KeysManager, KeysInterface};
-/// # use lightning::onion_message::{BlindedRoute, Destination, OnionMessenger};
+/// # use lightning::ln::msgs::DecodeError;
+/// # use lightning::ln::peer_handler::IgnoringMessageHandler;
+/// # use lightning::onion_message::{BlindedRoute, CustomOnionMessageContents, Destination, OnionMessageContents, OnionMessenger};
 /// # use lightning::util::logger::{Logger, Record};
+/// # use lightning::util::ser::{MaybeReadableArgs, Writeable, Writer};
+/// # use lightning::io;
 /// # use std::sync::Arc;
 /// # struct FakeLogger {};
 /// # impl Logger for FakeLogger {
@@ -55,43 +61,67 @@ use prelude::*;
 /// # let node_secret = SecretKey::from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap();
 /// # let secp_ctx = Secp256k1::new();
 /// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
-/// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1,
-/// hop_node_id1);
+/// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1);
 /// # let destination_node_id = hop_node_id1;
-/// #
+/// # let your_custom_message_handler = IgnoringMessageHandler {};
 /// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
 /// // ChannelManager.
-/// let onion_messenger = OnionMessenger::new(&keys_manager, logger);
+/// let onion_messenger = OnionMessenger::new(&keys_manager, logger, your_custom_message_handler);
 ///
-/// // Send an empty onion message to a node id.
+/// # struct YourCustomMessage {}
+/// impl Writeable for YourCustomMessage {
+///    fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+///            # Ok(())
+///            // Write your custom onion message to `w`
+///    }
+/// }
+/// impl CustomOnionMessageContents for YourCustomMessage {
+///    fn tlv_type(&self) -> u64 {
+///            # let your_custom_message_type = 42;
+///            your_custom_message_type
+///    }
+/// }
+/// impl MaybeReadableArgs<u64> for YourCustomMessage {
+///    fn read<R: io::Read>(r: &mut R, message_type: u64) -> Result<Option<Self>, DecodeError> {
+///            # unreachable!()
+///            // Read your custom onion message of type `message_type` from `r`, or return `None`
+///            // if the message type is unknown
+///    }
+/// }
+/// // Send a custom onion message to a node id.
 /// let intermediate_hops = [hop_node_id1, hop_node_id2];
 /// let reply_path = None;
-/// onion_messenger.send_onion_message(&intermediate_hops, Destination::Node(destination_node_id), reply_path);
+/// # let your_custom_message = YourCustomMessage {};
+/// let message = OnionMessageContents::Custom(your_custom_message);
+/// onion_messenger.send_onion_message(&intermediate_hops, Destination::Node(destination_node_id), message, reply_path);
 ///
 /// // Create a blinded route to yourself, for someone to send an onion message to.
 /// # let your_node_id = hop_node_id1;
 /// let hops = [hop_node_id3, hop_node_id4, your_node_id];
 /// let blinded_route = BlindedRoute::new(&hops, &keys_manager, &secp_ctx).unwrap();
 ///
-/// // Send an empty onion message to a blinded route.
+/// // Send a custom onion message to a blinded route.
 /// # let intermediate_hops = [hop_node_id1, hop_node_id2];
 /// let reply_path = None;
-/// onion_messenger.send_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route), reply_path);
+/// # let your_custom_message = YourCustomMessage {};
+/// let message = OnionMessageContents::Custom(your_custom_message);
+/// onion_messenger.send_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route), message, reply_path);
 /// ```
 ///
 /// [offers]: <https://github.com/lightning/bolts/pull/798>
 /// [`OnionMessenger`]: crate::onion_message::OnionMessenger
-pub struct OnionMessenger<Signer: Sign, K: Deref, L: Deref>
+pub struct OnionMessenger<Signer: Sign, K: Deref, L: Deref, CMH: Deref>
        where K::Target: KeysInterface<Signer = Signer>,
              L::Target: Logger,
+             CMH:: Target: CustomOnionMessageHandler,
 {
        keys_manager: K,
        logger: L,
        pending_messages: Mutex<HashMap<PublicKey, VecDeque<msgs::OnionMessage>>>,
        secp_ctx: Secp256k1<secp256k1::All>,
+       custom_handler: CMH,
        // Coming soon:
        // invoice_handler: InvoiceHandler,
-       // custom_handler: CustomHandler, // handles custom onion messages
 }
 
 /// The destination of an onion message.
@@ -114,7 +144,7 @@ impl Destination {
 /// Errors that may occur when [sending an onion message].
 ///
 /// [sending an onion message]: OnionMessenger::send_onion_message
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 pub enum SendError {
        /// Errored computing onion message packet keys.
        Secp256k1(secp256k1::Error),
@@ -126,17 +156,38 @@ pub enum SendError {
        TooFewBlindedHops,
        /// Our next-hop peer was offline or does not support onion message forwarding.
        InvalidFirstHop,
+       /// Onion message contents must have a TLV type >= 64.
+       InvalidMessage,
        /// Our next-hop peer's buffer was full or our total outbound buffer was full.
        BufferFull,
 }
 
-impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
+/// Handler for custom onion messages. If you are using [`SimpleArcOnionMessenger`],
+/// [`SimpleRefOnionMessenger`], or prefer to ignore inbound custom onion messages,
+/// [`IgnoringMessageHandler`] must be provided to [`OnionMessenger::new`]. Otherwise, a custom
+/// implementation of this trait must be provided, with [`CustomMessage`] specifying the supported
+/// message types.
+///
+/// See [`OnionMessenger`] for example usage.
+///
+/// [`IgnoringMessageHandler`]: crate::ln::peer_handler::IgnoringMessageHandler
+/// [`CustomMessage`]: Self::CustomMessage
+pub trait CustomOnionMessageHandler {
+       /// The message known to the handler. To support multiple message types, you may want to make this
+       /// an enum with a variant for each supported message.
+       type CustomMessage: CustomOnionMessageContents;
+       /// Called with the custom message that was received.
+       fn handle_custom_message(&self, msg: Self::CustomMessage);
+}
+
+impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessenger<Signer, K, L, CMH>
        where K::Target: KeysInterface<Signer = Signer>,
              L::Target: Logger,
+             CMH::Target: CustomOnionMessageHandler,
 {
        /// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
        /// their respective handlers.
-       pub fn new(keys_manager: K, logger: L) -> Self {
+       pub fn new(keys_manager: K, logger: L, custom_handler: CMH) -> Self {
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
                OnionMessenger {
@@ -144,17 +195,21 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
                        pending_messages: Mutex::new(HashMap::new()),
                        secp_ctx,
                        logger,
+                       custom_handler,
                }
        }
 
-       /// Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
+       /// Send an onion message with contents `message` to `destination`, routing it through `intermediate_nodes`.
        /// See [`OnionMessenger`] for example usage.
-       pub fn send_onion_message(&self, intermediate_nodes: &[PublicKey], destination: Destination, reply_path: Option<BlindedRoute>) -> Result<(), SendError> {
+       pub fn send_onion_message<T: CustomOnionMessageContents>(&self, intermediate_nodes: &[PublicKey], destination: Destination, message: OnionMessageContents<T>, reply_path: Option<BlindedRoute>) -> Result<(), SendError> {
                if let Destination::BlindedRoute(BlindedRoute { ref blinded_hops, .. }) = destination {
                        if blinded_hops.len() < 2 {
                                return Err(SendError::TooFewBlindedHops);
                        }
                }
+               let OnionMessageContents::Custom(ref msg) = message;
+               if msg.tlv_type() < 64 { return Err(SendError::InvalidMessage) }
+
                let blinding_secret_bytes = self.keys_manager.get_secure_random_bytes();
                let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
                let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {
@@ -167,7 +222,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
                        }
                };
                let (packet_payloads, packet_keys) = packet_payloads_and_keys(
-                       &self.secp_ctx, intermediate_nodes, destination, reply_path, &blinding_secret)
+                       &self.secp_ctx, intermediate_nodes, destination, message, reply_path, &blinding_secret)
                        .map_err(|e| SendError::Secp256k1(e))?;
 
                let prng_seed = self.keys_manager.get_secure_random_bytes();
@@ -221,9 +276,10 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, Ve
        false
 }
 
-impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Signer, K, L>
+impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<Signer, K, L, CMH>
        where K::Target: KeysInterface<Signer = Signer>,
              L::Target: Logger,
+             CMH::Target: CustomOnionMessageHandler,
 {
        /// Handle an incoming onion message. Currently, if a message was destined for us we will log, but
        /// soon we'll delegate the onion message to a handler that can generate invoices or send
@@ -255,12 +311,15 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
                match onion_utils::decode_next_hop(onion_decode_ss, &msg.onion_routing_packet.hop_data[..],
                        msg.onion_routing_packet.hmac, control_tlvs_ss)
                {
-                       Ok((Payload::Receive {
-                               control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
+                       Ok((Payload::Receive::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
+                               message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
                        }, None)) => {
                                log_info!(self.logger,
-                                       "Received an onion message with path_id: {:02x?} and {}reply_path",
-                                               path_id, if reply_path.is_some() { "" } else { "no " });
+                                       "Received an onion message with path_id {:02x?} and {} reply_path",
+                                               path_id, if reply_path.is_some() { "a" } else { "no" });
+                               match message {
+                                       OnionMessageContents::Custom(msg) => self.custom_handler.handle_custom_message(msg),
+                               }
                        },
                        Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs {
                                next_node_id, next_blinding_override
@@ -361,9 +420,10 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
        }
 }
 
-impl<Signer: Sign, K: Deref, L: Deref> OnionMessageProvider for OnionMessenger<Signer, K, L>
+impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionMessenger<Signer, K, L, CMH>
        where K::Target: KeysInterface<Signer = Signer>,
              L::Target: Logger,
+             CMH::Target: CustomOnionMessageHandler,
 {
        fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option<msgs::OnionMessage> {
                let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -383,7 +443,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageProvider for OnionMessenger<S
 ///
 /// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
 /// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
-pub type SimpleArcOnionMessenger<L> = OnionMessenger<InMemorySigner, Arc<KeysManager>, Arc<L>>;
+pub type SimpleArcOnionMessenger<L> = OnionMessenger<InMemorySigner, Arc<KeysManager>, Arc<L>, IgnoringMessageHandler>;
 /// Useful for simplifying the parameters of [`SimpleRefChannelManager`] and
 /// [`SimpleRefPeerManager`]. See their docs for more details.
 ///
@@ -391,14 +451,14 @@ pub type SimpleArcOnionMessenger<L> = OnionMessenger<InMemorySigner, Arc<KeysMan
 ///
 /// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
 /// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
-pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<InMemorySigner, &'a KeysManager, &'b L>;
+pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<InMemorySigner, &'a KeysManager, &'b L, IgnoringMessageHandler>;
 
 /// Construct onion packet payloads and keys for sending an onion message along the given
 /// `unblinded_path` to the given `destination`.
-fn packet_payloads_and_keys<T: secp256k1::Signing + secp256k1::Verification>(
-       secp_ctx: &Secp256k1<T>, unblinded_path: &[PublicKey], destination: Destination, mut reply_path:
-       Option<BlindedRoute>, session_priv: &SecretKey
-) -> Result<(Vec<(Payload, [u8; 32])>, Vec<onion_utils::OnionKeys>), secp256k1::Error> {
+fn packet_payloads_and_keys<T: CustomOnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
+       secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination,
+       message: OnionMessageContents<T>, mut reply_path: Option<BlindedRoute>, session_priv: &SecretKey
+) -> Result<(Vec<(Payload<T>, [u8; 32])>, Vec<onion_utils::OnionKeys>), secp256k1::Error> {
        let num_hops = unblinded_path.len() + destination.num_hops();
        let mut payloads = Vec::with_capacity(num_hops);
        let mut onion_packet_keys = Vec::with_capacity(num_hops);
@@ -411,6 +471,7 @@ fn packet_payloads_and_keys<T: secp256k1::Signing + secp256k1::Verification>(
        let mut unblinded_path_idx = 0;
        let mut blinded_path_idx = 0;
        let mut prev_control_tlvs_ss = None;
+       let mut final_control_tlvs = None;
        utils::construct_keys_callback(secp_ctx, unblinded_path, Some(destination), session_priv, |_, onion_packet_ss, ephemeral_pubkey, control_tlvs_ss, unblinded_pk_opt, enc_payload_opt| {
                if num_unblinded_hops != 0 && unblinded_path_idx < num_unblinded_hops {
                        if let Some(ss) = prev_control_tlvs_ss.take() {
@@ -440,10 +501,8 @@ fn packet_payloads_and_keys<T: secp256k1::Signing + secp256k1::Verification>(
                                control_tlvs_ss));
                        blinded_path_idx += 1;
                } else if let Some(encrypted_payload) = enc_payload_opt {
-                       payloads.push((Payload::Receive {
-                               control_tlvs: ReceiveControlTlvs::Blinded(encrypted_payload),
-                               reply_path: reply_path.take(),
-                       }, control_tlvs_ss));
+                       final_control_tlvs = Some(ReceiveControlTlvs::Blinded(encrypted_payload));
+                       prev_control_tlvs_ss = Some(control_tlvs_ss);
                }
 
                let (rho, mu) = onion_utils::gen_rho_mu_from_shared_secret(onion_packet_ss.as_ref());
@@ -458,18 +517,25 @@ fn packet_payloads_and_keys<T: secp256k1::Signing + secp256k1::Verification>(
                });
        })?;
 
-       if let Some(control_tlvs_ss) = prev_control_tlvs_ss {
+       if let Some(control_tlvs) = final_control_tlvs {
+               payloads.push((Payload::Receive {
+                       control_tlvs,
+                       reply_path: reply_path.take(),
+                       message,
+               }, prev_control_tlvs_ss.unwrap()));
+       } else {
                payloads.push((Payload::Receive {
                        control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id: None, }),
                        reply_path: reply_path.take(),
-               }, control_tlvs_ss));
+                       message,
+               }, prev_control_tlvs_ss.unwrap()));
        }
 
        Ok((payloads, onion_packet_keys))
 }
 
 /// Errors if the serialized payload size exceeds onion_message::BIG_PACKET_HOP_DATA_LEN
-fn construct_onion_message_packet(payloads: Vec<(Payload, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Result<Packet, ()> {
+fn construct_onion_message_packet<T: CustomOnionMessageContents>(payloads: Vec<(Payload<T>, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Result<Packet, ()> {
        // Spec rationale:
        // "`len` allows larger messages to be sent than the standard 1300 bytes allowed for an HTLC
        // onion, but this should be used sparingly as it is reduces anonymity set, hence the
index 2e23b76ada33ac8f1a7355943edb8d5c9ee25392..3c522e30c51bf367c25311b6987418f3fe802931 100644 (file)
@@ -29,5 +29,5 @@ mod functional_tests;
 
 // Re-export structs so they can be imported with just the `onion_message::` module prefix.
 pub use self::blinded_route::{BlindedRoute, BlindedHop};
-pub use self::messenger::{Destination, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
+pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
 pub(crate) use self::packet::Packet;
index 1337bdb14d5d6c3bf83fcadc5beebcea8b6d70d8..41b8a1634f6bcf68147e15e301c72515a543004f 100644 (file)
@@ -16,7 +16,7 @@ use ln::msgs::DecodeError;
 use ln::onion_utils;
 use super::blinded_route::{BlindedRoute, ForwardTlvs, ReceiveTlvs};
 use util::chacha20poly1305rfc::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter};
-use util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer};
+use util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, MaybeReadableArgs, Readable, ReadableArgs, Writeable, Writer};
 
 use core::cmp;
 use io::{self, Read};
@@ -27,7 +27,7 @@ use prelude::*;
 pub(super) const SMALL_PACKET_HOP_DATA_LEN: usize = 1300;
 pub(super) const BIG_PACKET_HOP_DATA_LEN: usize = 32768;
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub(crate) struct Packet {
        pub(super) version: u8,
        pub(super) public_key: PublicKey,
@@ -92,25 +92,52 @@ impl LengthReadable for Packet {
 /// Onion message payloads contain "control" TLVs and "data" TLVs. Control TLVs are used to route
 /// the onion message from hop to hop and for path verification, whereas data TLVs contain the onion
 /// message content itself, such as an invoice request.
-pub(super) enum Payload {
+pub(super) enum Payload<T: CustomOnionMessageContents> {
        /// This payload is for an intermediate hop.
        Forward(ForwardControlTlvs),
        /// This payload is for the final hop.
        Receive {
                control_tlvs: ReceiveControlTlvs,
                reply_path: Option<BlindedRoute>,
-               // Coming soon:
-               // message: Message,
+               message: OnionMessageContents<T>,
        }
 }
 
-// Coming soon:
-// enum Message {
-//     InvoiceRequest(InvoiceRequest),
-//     Invoice(Invoice),
-//     InvoiceError(InvoiceError),
-//     CustomMessage<T>,
-// }
+#[derive(Debug)]
+/// The contents of an onion message. In the context of offers, this would be the invoice, invoice
+/// request, or invoice error.
+pub enum OnionMessageContents<T> where T: CustomOnionMessageContents {
+       // Coming soon:
+       // Invoice,
+       // InvoiceRequest,
+       // InvoiceError,
+       /// A custom onion message specified by the user.
+       Custom(T),
+}
+
+impl<T> OnionMessageContents<T> where T: CustomOnionMessageContents {
+       /// Returns the type that was used to decode the message payload.
+       pub fn tlv_type(&self) -> u64 {
+               match self {
+                       &OnionMessageContents::Custom(ref msg) => msg.tlv_type(),
+               }
+       }
+}
+
+impl<T: CustomOnionMessageContents> Writeable for OnionMessageContents<T> {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               match self {
+                       OnionMessageContents::Custom(msg) => Ok(msg.write(w)?),
+               }
+       }
+}
+
+/// The contents of a custom onion message. Must implement `MaybeReadableArgs<u64>` where the `u64`
+/// is the custom TLV type attempting to be read, and return `Ok(None)` if the TLV type is unknown.
+pub trait CustomOnionMessageContents: Writeable + MaybeReadableArgs<u64> {
+       /// Returns the TLV type identifying the message contents. MUST be >= 64.
+       fn tlv_type(&self) -> u64;
+}
 
 /// Forward control TLVs in their blinded and unblinded form.
 pub(super) enum ForwardControlTlvs {
@@ -132,7 +159,7 @@ pub(super) enum ReceiveControlTlvs {
 }
 
 // Uses the provided secret to simultaneously encode and encrypt the unblinded control TLVs.
-impl Writeable for (Payload, [u8; 32]) {
+impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                match &self.0 {
                        Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => {
@@ -141,11 +168,12 @@ impl Writeable for (Payload, [u8; 32]) {
                                })
                        },
                        Payload::Receive {
-                               control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes), reply_path
+                               control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes), reply_path, message,
                        } => {
                                encode_varint_length_prefixed_tlv!(w, {
                                        (2, reply_path, option),
-                                       (4, encrypted_bytes, vec_type)
+                                       (4, encrypted_bytes, vec_type),
+                                       (message.tlv_type(), message, required)
                                })
                        },
                        Payload::Forward(ForwardControlTlvs::Unblinded(control_tlvs)) => {
@@ -155,12 +183,13 @@ impl Writeable for (Payload, [u8; 32]) {
                                })
                        },
                        Payload::Receive {
-                               control_tlvs: ReceiveControlTlvs::Unblinded(control_tlvs), reply_path,
+                               control_tlvs: ReceiveControlTlvs::Unblinded(control_tlvs), reply_path, message,
                        } => {
                                let write_adapter = ChaChaPolyWriteAdapter::new(self.1, &control_tlvs);
                                encode_varint_length_prefixed_tlv!(w, {
                                        (2, reply_path, option),
-                                       (4, write_adapter, required)
+                                       (4, write_adapter, required),
+                                       (message.tlv_type(), message, required)
                                })
                        },
                }
@@ -168,28 +197,52 @@ impl Writeable for (Payload, [u8; 32]) {
        }
 }
 
-// Uses the provided secret to simultaneously decode and decrypt the control TLVs.
-impl ReadableArgs<SharedSecret> for Payload {
+// Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV.
+impl<T: CustomOnionMessageContents> ReadableArgs<SharedSecret> for Payload<T> {
        fn read<R: Read>(r: &mut R, encrypted_tlvs_ss: SharedSecret) -> Result<Self, DecodeError> {
                let v: BigSize = Readable::read(r)?;
                let mut rd = FixedLengthReader::new(r, v.0);
                let mut reply_path: Option<BlindedRoute> = None;
                let mut read_adapter: Option<ChaChaPolyReadAdapter<ControlTlvs>> = None;
                let rho = onion_utils::gen_rho_from_shared_secret(&encrypted_tlvs_ss.secret_bytes());
+               let mut message_type: Option<u64> = None;
+               let mut message = None;
                decode_tlv_stream!(&mut rd, {
                        (2, reply_path, option),
-                       (4, read_adapter, (option: LengthReadableArgs, rho))
+                       (4, read_adapter, (option: LengthReadableArgs, rho)),
+               }, |msg_type, msg_reader| {
+                       if msg_type < 64 { return Ok(false) }
+                       // Don't allow reading more than one data TLV from an onion message.
+                       if message_type.is_some() { return Err(DecodeError::InvalidValue) }
+
+                       message_type = Some(msg_type);
+                       match T::read(msg_reader, msg_type) {
+                               Ok(Some(msg)) => {
+                                       message = Some(msg);
+                                       Ok(true)
+                               },
+                               Ok(None) => Ok(false),
+                               Err(e) => Err(e),
+                       }
                });
                rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?;
 
                match read_adapter {
                        None => return Err(DecodeError::InvalidValue),
                        Some(ChaChaPolyReadAdapter { readable: ControlTlvs::Forward(tlvs)}) => {
+                               if message_type.is_some() {
+                                       return Err(DecodeError::InvalidValue)
+                               }
                                Ok(Payload::Forward(ForwardControlTlvs::Unblinded(tlvs)))
                        },
                        Some(ChaChaPolyReadAdapter { readable: ControlTlvs::Receive(tlvs)}) => {
-                               Ok(Payload::Receive { control_tlvs: ReceiveControlTlvs::Unblinded(tlvs), reply_path })
-                       },
+                               if message.is_none() { return Err(DecodeError::InvalidValue) }
+                               Ok(Payload::Receive {
+                                       control_tlvs: ReceiveControlTlvs::Unblinded(tlvs),
+                                       reply_path,
+                                       message: OnionMessageContents::Custom(message.unwrap()),
+                               })
+                       }
                }
        }
 }
index 19f109f0cd5d2f8a041302d54becbe035acd4b3d..47d7dab6d1132121a5da3bacf2e57cb52befb2ab 100644 (file)
@@ -164,7 +164,7 @@ pub struct ReadOnlyNetworkGraph<'a> {
 /// return packet by a node along the route. See [BOLT #4] for details.
 ///
 /// [BOLT #4]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum NetworkUpdate {
        /// An error indicating a `channel_update` messages should be applied via
        /// [`NetworkGraph::update_channel`].
@@ -626,7 +626,7 @@ where
        }
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 /// Details about one direction of a channel as received within a [`ChannelUpdate`].
 pub struct ChannelUpdateInfo {
        /// When the last update to the channel direction was issued.
@@ -709,7 +709,7 @@ impl Readable for ChannelUpdateInfo {
        }
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 /// Details about a channel (both directions).
 /// Received within a channel announcement.
 pub struct ChannelInfo {
@@ -1017,7 +1017,7 @@ impl_writeable_tlv_based!(RoutingFees, {
        (2, proportional_millionths, required)
 });
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 /// Information received in the latest node_announcement from this node.
 pub struct NodeAnnouncementInfo {
        /// Protocol features the node announced support for
@@ -1053,7 +1053,7 @@ impl_writeable_tlv_based!(NodeAnnouncementInfo, {
 ///
 /// Since node aliases are provided by third parties, they are a potential avenue for injection
 /// attacks. Care must be taken when processing.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct NodeAlias(pub [u8; 32]);
 
 impl fmt::Display for NodeAlias {
@@ -1094,7 +1094,7 @@ impl Readable for NodeAlias {
        }
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 /// Details about a node in the network, known from the network announcement.
 pub struct NodeInfo {
        /// All valid channels a node has announced
@@ -1247,6 +1247,7 @@ impl<L: Deref> fmt::Display for NetworkGraph<L> where L::Target: Logger {
        }
 }
 
+impl<L: Deref> Eq for NetworkGraph<L> where L::Target: Logger {}
 impl<L: Deref> PartialEq for NetworkGraph<L> where L::Target: Logger {
        fn eq(&self, other: &Self) -> bool {
                self.genesis_hash == other.genesis_hash &&
@@ -1330,7 +1331,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                                        // updates to ensure you always have the latest one, only vaguely suggesting
                                        // that it be at least the current time.
                                        if node_info.last_update  > msg.timestamp {
-                                               return Err(LightningError{err: "Update older than last processed update".to_owned(), action: ErrorAction::IgnoreAndLog(Level::Gossip)});
+                                               return Err(LightningError{err: "Update older than last processed update".to_owned(), action: ErrorAction::IgnoreDuplicateGossip});
                                        } else if node_info.last_update  == msg.timestamp {
                                                return Err(LightningError{err: "Update had the same timestamp as last processed update".to_owned(), action: ErrorAction::IgnoreDuplicateGossip});
                                        }
@@ -1796,7 +1797,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                                                        // pruning based on the timestamp field being more than two weeks old,
                                                        // but only in the non-normative section.
                                                        if existing_chan_info.last_update > msg.timestamp {
-                                                               return Err(LightningError{err: "Update older than last processed update".to_owned(), action: ErrorAction::IgnoreAndLog(Level::Gossip)});
+                                                               return Err(LightningError{err: "Update older than last processed update".to_owned(), action: ErrorAction::IgnoreDuplicateGossip});
                                                        } else if existing_chan_info.last_update == msg.timestamp {
                                                                return Err(LightningError{err: "Update had same timestamp as last processed update".to_owned(), action: ErrorAction::IgnoreDuplicateGossip});
                                                        }
index efba350ce2743f816c39e6c20698a15c3e222454..170ac9c991c43b3f4b079a026bd388801a6ca12d 100644 (file)
@@ -1153,7 +1153,7 @@ where L::Target: Logger {
                                                                lowest_fee_to_peer_through_node: total_fee_msat,
                                                                lowest_fee_to_node: $next_hops_fee_msat as u64 + hop_use_fee_msat,
                                                                total_cltv_delta: hop_total_cltv_delta,
-                                                               value_contribution_msat: value_contribution_msat,
+                                                               value_contribution_msat,
                                                                path_htlc_minimum_msat,
                                                                path_penalty_msat,
                                                                path_length_to_node,
index fefdebfccd30f8b38966e58b7650e81ba06ec080..4052fac1bcddbbe12098a9947d1eca983ba7e253 100644 (file)
@@ -225,6 +225,16 @@ impl<'a, T: Score + 'a> LockableScore<'a> for MultiThreadedLockableScore<T> {
        }
 }
 
+#[cfg(c_bindings)]
+impl<T: Score> Writeable for MultiThreadedLockableScore<T> {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               self.lock().write(writer)
+       }
+}
+
+#[cfg(c_bindings)]
+impl<'a, T: Score + 'a> WriteableScore<'a> for MultiThreadedLockableScore<T> {}
+
 #[cfg(c_bindings)]
 impl<T: Score> MultiThreadedLockableScore<T> {
        /// Creates a new [`MultiThreadedLockableScore`] given an underlying [`Score`].
index 5fddb57eb36a0c1a2d119baeabd7d0a757509ee6..3254e8b0134d298517fcc9095792fb48c9935b50 100644 (file)
@@ -335,7 +335,7 @@ mod tests {
        use util::ser::{self, FixedLengthReader, LengthReadableArgs, Writeable};
 
        // Used for for testing various lengths of serialization.
-       #[derive(Debug, PartialEq)]
+       #[derive(Debug, PartialEq, Eq)]
        struct TestWriteable {
                field1: Vec<u8>,
                field2: Vec<u8>,
index b2004df3e9cbd0c043c2b2ef184e538f267ea02a..f44e43b7db4426ce724a2346b3f5ecd015a8d301 100644 (file)
@@ -274,7 +274,7 @@ impl Default for ChannelHandshakeLimits {
 
 /// Options which apply on a per-channel basis and may change at runtime or based on negotiation
 /// with our counterparty.
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct ChannelConfig {
        /// Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
        /// over the channel.
index f4450cc129d81979cedbf1580e5cc3a0450dad62..34b5954d48525b4555ba45b3de803b334ab24007 100644 (file)
@@ -7,6 +7,7 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
+use ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSHIS};
 use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitmentTransaction, CommitmentTransaction, ChannelTransactionParameters, TrustedCommitmentTransaction, ClosingTransaction};
 use ln::{chan_utils, msgs, PaymentPreimage};
 use chain::keysinterface::{Sign, InMemorySigner, BaseSign};
@@ -199,6 +200,16 @@ impl BaseSign for EnforcingSigner {
                Ok(self.inner.sign_closing_transaction(closing_tx, secp_ctx).unwrap())
        }
 
+       fn sign_holder_anchor_input(
+               &self, anchor_tx: &mut Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
+       ) -> Result<Signature, ()> {
+               debug_assert!(MIN_CHAN_DUST_LIMIT_SATOSHIS > ANCHOR_OUTPUT_VALUE_SATOSHI);
+               // As long as our minimum dust limit is enforced and is greater than our anchor output
+               // value, an anchor output can only have an index within [0, 1].
+               assert!(anchor_tx.input[input].previous_output.vout == 0 || anchor_tx.input[input].previous_output.vout == 1);
+               self.inner.sign_holder_anchor_input(anchor_tx, input, secp_ctx)
+       }
+
        fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
        -> Result<(Signature, Signature), ()> {
                self.inner.sign_channel_announcement(msg, secp_ctx)
index ad699354233cb705fd41221cee58293a3a62c3d2..f00d2ab2d0e741a3b833b56b90ec8edae7fbce93 100644 (file)
@@ -16,7 +16,7 @@ use core::fmt;
 
 /// Indicates an error on the client's part (usually some variant of attempting to use too-low or
 /// too-high values)
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq)]
 pub enum APIError {
        /// Indicates the API was wholly misused (see err for more). Cases where these can be returned
        /// are documented, but generally indicates some precondition of a function was violated.
index 8ddd762e97036bac77fee08c2be7819ec707388e..83e861889bc356bff2cd2305cfd92077e13b6ded 100644 (file)
@@ -15,6 +15,7 @@
 //! few other things.
 
 use chain::keysinterface::SpendableOutputDescriptor;
+use ln::chan_utils::HTLCOutputInCommitment;
 use ln::channelmanager::PaymentId;
 use ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
 use ln::features::ChannelTypeFeatures;
@@ -25,7 +26,7 @@ use routing::gossip::NetworkUpdate;
 use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
 use routing::router::{RouteHop, RouteParameters};
 
-use bitcoin::{PackedLockTime, Transaction};
+use bitcoin::{PackedLockTime, Transaction, OutPoint};
 use bitcoin::blockdata::script::Script;
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
@@ -74,7 +75,7 @@ impl_writeable_tlv_based_enum!(PaymentPurpose,
        (2, SpontaneousPayment)
 );
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 /// The reason the channel was closed. See individual variants more details.
 pub enum ClosureReason {
        /// Closure generated from receiving a peer error message.
@@ -111,11 +112,19 @@ pub enum ClosureReason {
        /// The peer disconnected prior to funding completing. In this case the spec mandates that we
        /// forget the channel entirely - we can attempt again if the peer reconnects.
        ///
+       /// This includes cases where we restarted prior to funding completion, including prior to the
+       /// initial [`ChannelMonitor`] persistence completing.
+       ///
        /// In LDK versions prior to 0.0.107 this could also occur if we were unable to connect to the
        /// peer because of mutual incompatibility between us and our channel counterparty.
+       ///
+       /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
        DisconnectedPeer,
-       /// Closure generated from `ChannelManager::read` if the ChannelMonitor is newer than
-       /// the ChannelManager deserialized.
+       /// Closure generated from `ChannelManager::read` if the [`ChannelMonitor`] is newer than
+       /// the [`ChannelManager`] deserialized.
+       ///
+       /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
+       /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
        OutdatedChannelManager
 }
 
@@ -153,7 +162,7 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
 );
 
 /// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum HTLCDestination {
        /// We tried forwarding to a channel but failed to do so. An example of such an instance is when
        /// there is insufficient capacity in our outbound channel.
@@ -196,6 +205,84 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCDestination,
        }
 );
 
+/// A descriptor used to sign for a commitment transaction's anchor output.
+#[derive(Clone, Debug)]
+pub struct AnchorDescriptor {
+       /// A unique identifier used along with `channel_value_satoshis` to re-derive the
+       /// [`InMemorySigner`] required to sign `input`.
+       ///
+       /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
+       pub channel_keys_id: [u8; 32],
+       /// The value in satoshis of the channel we're attempting to spend the anchor output of. This is
+       /// used along with `channel_keys_id` to re-derive the [`InMemorySigner`] required to sign
+       /// `input`.
+       ///
+       /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
+       pub channel_value_satoshis: u64,
+       /// The transaction input's outpoint corresponding to the commitment transaction's anchor
+       /// output.
+       pub outpoint: OutPoint,
+}
+
+/// Represents the different types of transactions, originating from LDK, to be bumped.
+#[derive(Clone, Debug)]
+pub enum BumpTransactionEvent {
+       /// Indicates that a channel featuring anchor outputs is to be closed by broadcasting the local
+       /// commitment transaction. Since commitment transactions have a static feerate pre-agreed upon,
+       /// they may need additional fees to be attached through a child transaction using the popular
+       /// [Child-Pays-For-Parent](https://bitcoinops.org/en/topics/cpfp) fee bumping technique. This
+       /// child transaction must include the anchor input described within `anchor_descriptor` along
+       /// with additional inputs to meet the target feerate. Failure to meet the target feerate
+       /// decreases the confirmation odds of the transaction package (which includes the commitment
+       /// and child anchor transactions), possibly resulting in a loss of funds. Once the transaction
+       /// is constructed, it must be fully signed for and broadcasted by the consumer of the event
+       /// along with the `commitment_tx` enclosed. Note that the `commitment_tx` must always be
+       /// broadcast first, as the child anchor transaction depends on it.
+       ///
+       /// The consumer should be able to sign for any of the additional inputs included within the
+       /// child anchor transaction. To sign its anchor input, an [`InMemorySigner`] should be
+       /// re-derived through [`KeysManager::derive_channel_keys`] with the help of
+       /// [`AnchorDescriptor::channel_keys_id`] and [`AnchorDescriptor::channel_value_satoshis`].
+       ///
+       /// It is possible to receive more than one instance of this event if a valid child anchor
+       /// transaction is never broadcast or is but not with a sufficient fee to be mined. Care should
+       /// be taken by the consumer of the event to ensure any future iterations of the child anchor
+       /// transaction adhere to the [Replace-By-Fee
+       /// rules](https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md)
+       /// for fee bumps to be accepted into the mempool, and eventually the chain. As the frequency of
+       /// these events is not user-controlled, users may ignore/drop the event if they are no longer
+       /// able to commit external confirmed funds to the child anchor transaction.
+       ///
+       /// The set of `pending_htlcs` on the commitment transaction to be broadcast can be inspected to
+       /// determine whether a significant portion of the channel's funds are allocated to HTLCs,
+       /// enabling users to make their own decisions regarding the importance of the commitment
+       /// transaction's confirmation. Note that this is not required, but simply exists as an option
+       /// for users to override LDK's behavior. On commitments with no HTLCs (indicated by those with
+       /// an empty `pending_htlcs`), confirmation of the commitment transaction can be considered to
+       /// be not urgent.
+       ///
+       /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
+       /// [`KeysManager::derive_channel_keys`]: crate::chain::keysinterface::KeysManager::derive_channel_keys
+       ChannelClose {
+               /// The target feerate that the transaction package, which consists of the commitment
+               /// transaction and the to-be-crafted child anchor transaction, must meet.
+               package_target_feerate_sat_per_1000_weight: u32,
+               /// The channel's commitment transaction to bump the fee of. This transaction should be
+               /// broadcast along with the anchor transaction constructed as a result of consuming this
+               /// event.
+               commitment_tx: Transaction,
+               /// The absolute fee in satoshis of the commitment transaction. This can be used along the
+               /// with weight of the commitment transaction to determine its feerate.
+               commitment_tx_fee_satoshis: u64,
+               /// The descriptor to sign the anchor input of the anchor transaction constructed as a
+               /// result of consuming this event.
+               anchor_descriptor: AnchorDescriptor,
+               /// The set of pending HTLCs on the commitment transaction that need to be resolved once the
+               /// commitment transaction confirms.
+               pending_htlcs: Vec<HTLCOutputInCommitment>,
+       },
+}
+
 /// An Event which you should probably take some action in response to.
 ///
 /// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
@@ -602,6 +689,13 @@ pub enum Event {
                /// Destination of the HTLC that failed to be processed.
                failed_next_destination: HTLCDestination,
        },
+       #[cfg(anchors)]
+       /// Indicates that a transaction originating from LDK needs to have its fee bumped. This event
+       /// requires confirmed external funds to be readily available to spend.
+       ///
+       /// LDK does not currently generate this event. It is limited to the scope of channels with
+       /// anchor outputs, which will be introduced in a future release.
+       BumpTransaction(BumpTransactionEvent),
 }
 
 impl Writeable for Event {
@@ -753,6 +847,15 @@ impl Writeable for Event {
                                        (2, failed_next_destination, required),
                                })
                        },
+                       #[cfg(anchors)]
+                       &Event::BumpTransaction(ref event)=> {
+                               27u8.write(writer)?;
+                               match event {
+                                       // We never write the ChannelClose events as they'll be replayed upon restarting
+                                       // anyway if the commitment transaction remains unconfirmed.
+                                       BumpTransactionEvent::ChannelClose { .. } => {}
+                               }
+                       }
                        // Note that, going forward, all new events must only write data inside of
                        // `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
                        // data via `write_tlv_fields`.
index 676c303bfa8dc1384b404cfe355aa77d99990242..79ef415c7b24f39e0034ad0d299ef8492172fd71 100644 (file)
@@ -20,7 +20,7 @@ pub const MAX_SCID_TX_INDEX: u64 = 0x00ffffff;
 pub const MAX_SCID_VOUT_INDEX: u64 = 0xffff;
 
 /// A `short_channel_id` construction error
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 pub enum ShortChannelIdError {
        BlockOverflow,
        TxIndexOverflow,
index 6ef29073837aa77d856afa37f65c737e6638abe6..3b82da8446da033d5d579cf7ec5a7d87e85225f8 100644 (file)
@@ -269,6 +269,15 @@ impl<T: Readable> MaybeReadable for T {
        }
 }
 
+/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a
+/// Read, given some additional set of arguments which is required to deserialize.
+///
+/// (C-not exported) as we only export serialization to/from byte arrays instead
+pub trait MaybeReadableArgs<P> {
+       /// Reads a Self in from the given Read
+       fn read<R: Read>(reader: &mut R, params: P) -> Result<Option<Self>, DecodeError> where Self: Sized;
+}
+
 pub(crate) struct OptionDeserWrapper<T: Readable>(pub Option<T>);
 impl<T: Readable> Readable for OptionDeserWrapper<T> {
        #[inline]
@@ -399,7 +408,7 @@ impl Readable for BigSize {
 /// In TLV we occasionally send fields which only consist of, or potentially end with, a
 /// variable-length integer which is simply truncated by skipping high zero bytes. This type
 /// encapsulates such integers implementing Readable/Writeable for them.
-#[cfg_attr(test, derive(PartialEq, Debug))]
+#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
 pub(crate) struct HighZeroBytesDroppedBigSize<T>(pub T);
 
 macro_rules! impl_writeable_primitive {
@@ -979,7 +988,7 @@ impl Readable for String {
 /// The character set consists of ASCII alphanumeric characters, hyphens, and periods.
 /// Its length is guaranteed to be representable by a single byte.
 /// This serialization is used by BOLT 7 hostnames.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Hostname(String);
 impl Hostname {
        /// Returns the length of the hostname.
index 94990fcb8a17c8056dfd01d00b18db78d58e466f..8c0a38670b5ad811dffd534721e3980b02fb444d 100644 (file)
@@ -157,25 +157,30 @@ macro_rules! decode_tlv {
                decode_tlv!($reader, $field, required)
        }};
        ($reader: expr, $field: ident, required) => {{
-               $field = ser::Readable::read(&mut $reader)?;
+               $field = ::util::ser::Readable::read(&mut $reader)?;
        }};
        ($reader: expr, $field: ident, vec_type) => {{
-               let f: ::util::ser::VecReadWrapper<_> = ser::Readable::read(&mut $reader)?;
+               let f: ::util::ser::VecReadWrapper<_> = ::util::ser::Readable::read(&mut $reader)?;
                $field = Some(f.0);
        }};
        ($reader: expr, $field: ident, option) => {{
-               $field = Some(ser::Readable::read(&mut $reader)?);
+               $field = Some(::util::ser::Readable::read(&mut $reader)?);
        }};
        ($reader: expr, $field: ident, ignorable) => {{
-               $field = ser::MaybeReadable::read(&mut $reader)?;
+               $field = ::util::ser::MaybeReadable::read(&mut $reader)?;
        }};
        ($reader: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
                $field = Some($trait::read(&mut $reader $(, $read_arg)*)?);
        }};
 }
 
+// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
+// If it is provided, it will be called with the custom type and the `FixedLengthReader` containing
+// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
+// `Ok(false)` if the message type is unknown, and `Err(DecodeError)` if parsing fails.
 macro_rules! decode_tlv_stream {
-       ($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => { {
+       ($stream: expr, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
+        $(, $decode_custom_tlv: expr)?) => { {
                use ln::msgs::DecodeError;
                let mut last_seen_type: Option<u64> = None;
                let mut stream_ref = $stream;
@@ -226,10 +231,19 @@ macro_rules! decode_tlv_stream {
                                                return Err(DecodeError::InvalidValue);
                                        }
                                },)*
-                               x if x % 2 == 0 => {
-                                       return Err(DecodeError::UnknownRequiredFeature);
-                               },
-                               _ => {},
+                               t => {
+                                       $(
+                                               if $decode_custom_tlv(t, &mut s)? {
+                                                       // If a custom TLV was successfully read (i.e. decode_custom_tlv returns true),
+                                                       // continue to the next TLV read.
+                                                       s.eat_remaining()?;
+                                                       continue 'tlv_read;
+                                               }
+                                       )?
+                                       if t % 2 == 0 {
+                                               return Err(DecodeError::UnknownRequiredFeature);
+                                       }
+                               }
                        }
                        s.eat_remaining()?;
                }
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644 (file)
index 0000000..91b8023
--- /dev/null
@@ -0,0 +1 @@
+disable_all_formatting = true
\ No newline at end of file