diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index a2fe88afc83..9a16083ccda 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -117,36 +117,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: Tlv { tag: 4242, value: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42] }".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)); } } } diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 22389bf5203..7c861a44338 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -12,7 +12,7 @@ use chain::keysinterface::{KeysInterface, Recipient}; use ln::features::InitFeatures; use ln::msgs::{self, OnionMessageHandler}; -use super::{BlindedRoute, Destination, OnionMessenger, SendError}; +use super::{BlindedRoute, Destination, OnionMessenger, SendError, Tlv}; use util::enforcing_trait_impls::EnforcingSigner; use util::test_utils; @@ -80,38 +80,42 @@ fn pass_along_path(path: &Vec, expected_path_id: Option<[u8; 32]> #[test] fn one_hop() { let nodes = create_nodes(2); + let test_tlv = Tlv { tag: 4242, value: vec![42; 32] }; - 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_tlv, None).unwrap(); pass_along_path(&nodes, None); } #[test] fn two_unblinded_hops() { let nodes = create_nodes(3); + let test_tlv = Tlv { tag: 4242, value: vec![42; 32] }; - 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_tlv, None).unwrap(); pass_along_path(&nodes, None); } #[test] fn two_unblinded_two_blinded() { let nodes = create_nodes(5); + let test_tlv = Tlv { tag: 4242, value: vec![42; 32] }; 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_tlv, None).unwrap(); pass_along_path(&nodes, None); } #[test] fn three_blinded_hops() { let nodes = create_nodes(4); + let test_tlv = Tlv { tag: 4242, value: vec![42; 32] }; 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_tlv, None).unwrap(); pass_along_path(&nodes, None); } @@ -119,10 +123,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_tlv = Tlv { tag: 4242, value: vec![42; 32] }; 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_tlv, None).unwrap_err(); assert_eq!(err, SendError::TooBigPacket); } @@ -130,53 +135,56 @@ 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_tlv = Tlv { tag: 4242, value: vec![42; 32] }; // 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), test_tlv.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), test_tlv, None).unwrap_err(); assert_eq!(err, SendError::TooFewBlindedHops); } #[test] fn reply_path() { let nodes = create_nodes(4); + let test_tlv = Tlv { tag: 4242, value: vec![42; 32] }; 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()), test_tlv.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), test_tlv, 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 peer_buffer_full() { let nodes = create_nodes(2); + let test_tlv = Tlv { tag: 4242, value: vec![42; 32] }; 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()), test_tlv.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()), test_tlv, None).unwrap_err(); assert_eq!(err, SendError::BufferFull); } diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index e2409fc45d6..245ace86d99 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -20,12 +20,14 @@ use ln::features::{InitFeatures, NodeFeatures}; use ln::msgs::{self, OnionMessageHandler}; use ln::onion_utils; use super::blinded_route::{BlindedRoute, ForwardTlvs, ReceiveTlvs}; +pub use super::packet::Tlv; use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN}; use super::utils; use util::events::OnionMessageProvider; use util::logger::Logger; use util::ser::Writeable; +use core::mem; use core::ops::Deref; use sync::{Arc, Mutex}; use prelude::*; @@ -41,7 +43,7 @@ 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::onion_message::{BlindedRoute, Destination, OnionMessenger, Tlv}; /// # use lightning::util::logger::{Logger, Record}; /// # use std::sync::Arc; /// # struct FakeLogger {}; @@ -63,20 +65,25 @@ use prelude::*; /// // ChannelManager. /// let onion_messenger = OnionMessenger::new(&keys_manager, logger); /// -/// // Send an empty onion message to a node id. +/// // Send an 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_tlv_type = 4242; +/// # let your_message_bytes = vec![42; 32]; +/// let message = Tlv { tag: your_tlv_type, value: your_message_bytes }; +/// 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_message_bytes = vec![42; 32]; +/// let message = Tlv { tag: your_tlv_type, value: your_message_bytes }; +/// onion_messenger.send_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route), message, reply_path); /// ``` /// /// [offers]: @@ -147,9 +154,9 @@ impl OnionMessenger } } - /// Send an empty onion message to `destination`, routing it through `intermediate_nodes`. + /// Send an onion message with payload `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) -> Result<(), SendError> { + pub fn send_onion_message(&self, intermediate_nodes: &[PublicKey], destination: Destination, message: Tlv, reply_path: Option) -> Result<(), SendError> { if let Destination::BlindedRoute(BlindedRoute { ref blinded_hops, .. }) = destination { if blinded_hops.len() < 2 { return Err(SendError::TooFewBlindedHops); @@ -167,7 +174,7 @@ impl OnionMessenger } }; 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(); @@ -256,11 +263,11 @@ impl OnionMessageHandler for OnionMessenger { 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" }, message); }, Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs { next_node_id, next_blinding_override @@ -396,8 +403,8 @@ pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger( - secp_ctx: &Secp256k1, unblinded_path: &[PublicKey], destination: Destination, mut reply_path: - Option, session_priv: &SecretKey + secp_ctx: &Secp256k1, unblinded_path: &[PublicKey], destination: Destination, mut message: Tlv, + mut reply_path: Option, session_priv: &SecretKey ) -> Result<(Vec<(Payload, [u8; 32])>, Vec), secp256k1::Error> { let num_hops = unblinded_path.len() + destination.num_hops(); let mut payloads = Vec::with_capacity(num_hops); @@ -440,9 +447,13 @@ fn packet_payloads_and_keys( control_tlvs_ss)); blinded_path_idx += 1; } else if let Some(encrypted_payload) = enc_payload_opt { + let mut msg = Tlv { tag: message.tag, value: Vec::new() }; + // Used to get around the compiler's "use of moved value" error + mem::swap(&mut msg.value, &mut message.value); payloads.push((Payload::Receive { control_tlvs: ReceiveControlTlvs::Blinded(encrypted_payload), reply_path: reply_path.take(), + message: msg, }, control_tlvs_ss)); } @@ -462,6 +473,7 @@ fn packet_payloads_and_keys( payloads.push((Payload::Receive { control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id: None, }), reply_path: reply_path.take(), + message, }, control_tlvs_ss)); } diff --git a/lightning/src/onion_message/mod.rs b/lightning/src/onion_message/mod.rs index 2e23b76ada3..3c459f39733 100644 --- a/lightning/src/onion_message/mod.rs +++ b/lightning/src/onion_message/mod.rs @@ -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::{Destination, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger, Tlv}; pub(crate) use self::packet::Packet; diff --git a/lightning/src/onion_message/packet.rs b/lightning/src/onion_message/packet.rs index 1337bdb14d5..08bde578aee 100644 --- a/lightning/src/onion_message/packet.rs +++ b/lightning/src/onion_message/packet.rs @@ -99,18 +99,18 @@ pub(super) enum Payload { Receive { control_tlvs: ReceiveControlTlvs, reply_path: Option, - // Coming soon: - // message: Message, + message: Tlv, } } -// Coming soon: -// enum Message { -// InvoiceRequest(InvoiceRequest), -// Invoice(Invoice), -// InvoiceError(InvoiceError), -// CustomMessage, -// } +#[derive(Clone, Debug)] +/// +pub struct Tlv { + /// + pub tag: u64, + /// + pub value: Vec, +} /// Forward control TLVs in their blinded and unblinded form. pub(super) enum ForwardControlTlvs { @@ -141,11 +141,13 @@ 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: Tlv { tag, value, }, } => { encode_varint_length_prefixed_tlv!(w, { (2, reply_path, option), - (4, encrypted_bytes, vec_type) + (4, encrypted_bytes, vec_type), + (*tag, value, vec_type) }) }, Payload::Forward(ForwardControlTlvs::Unblinded(control_tlvs)) => { @@ -156,11 +158,13 @@ impl Writeable for (Payload, [u8; 32]) { }, Payload::Receive { control_tlvs: ReceiveControlTlvs::Unblinded(control_tlvs), reply_path, + message: Tlv { tag, value, }, } => { 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), + (*tag, value, vec_type) }) }, } @@ -168,7 +172,7 @@ impl Writeable for (Payload, [u8; 32]) { } } -// Uses the provided secret to simultaneously decode and decrypt the control TLVs. +// Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV. impl ReadableArgs for Payload { fn read(r: &mut R, encrypted_tlvs_ss: SharedSecret) -> Result { let v: BigSize = Readable::read(r)?; @@ -176,10 +180,23 @@ impl ReadableArgs for Payload { let mut reply_path: Option = None; let mut read_adapter: Option> = None; let rho = onion_utils::gen_rho_from_shared_secret(&encrypted_tlvs_ss.secret_bytes()); + let (mut message_type, mut message_bytes) = (None, None); + let mut decode_custom_tlv = |msg_type, mut msg_reader: &mut FixedLengthReader<&mut &mut FixedLengthReader<&mut R>>| { + if msg_type >= 64 { + // Don't allow reading more than one data TLV from an onion message. + if message_bytes.is_some() || message_type.is_some() { + return Err(DecodeError::InvalidValue) + } + message_type = Some(msg_type); + decode_tlv!(msg_reader, message_bytes, vec_type); + return Ok(true) + } + Ok(false) + }; decode_tlv_stream!(&mut rd, { (2, reply_path, option), - (4, read_adapter, (option: LengthReadableArgs, rho)) - }); + (4, read_adapter, (option: LengthReadableArgs, rho)), + }, decode_custom_tlv); rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?; match read_adapter { @@ -188,8 +205,15 @@ impl ReadableArgs for Payload { Ok(Payload::Forward(ForwardControlTlvs::Unblinded(tlvs))) }, Some(ChaChaPolyReadAdapter { readable: ControlTlvs::Receive(tlvs)}) => { - Ok(Payload::Receive { control_tlvs: ReceiveControlTlvs::Unblinded(tlvs), reply_path }) - }, + if message_type.is_none() || message_bytes.is_none() { + return Err(DecodeError::InvalidValue) + } + Ok(Payload::Receive { + control_tlvs: ReceiveControlTlvs::Unblinded(tlvs), + reply_path, + message: Tlv { tag: message_type.unwrap(), value: message_bytes.unwrap() }, + }) + } } } } diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 782c0ef27d5..78acbd43768 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -175,7 +175,8 @@ macro_rules! decode_tlv { } 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 = None; let mut stream_ref = $stream; @@ -226,10 +227,18 @@ 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. + continue 'tlv_read; + } + )? + if t % 2 == 0 { + return Err(DecodeError::UnknownRequiredFeature); + } + } } s.eat_remaining()?; }