diff --git a/ci/rustfmt.sh b/ci/rustfmt.sh index a1fdf6bd7f3..1039429bc6a 100755 --- a/ci/rustfmt.sh +++ b/ci/rustfmt.sh @@ -15,5 +15,5 @@ TMP_FILE=$(mktemp) find . -name '*.rs' -type f |sort >$TMP_FILE for file in $(comm -23 $TMP_FILE rustfmt_excluded_files); do echo "Checking formatting of $file" - rustfmt $VERS --check $file + rustfmt $VERS --edition 2021 --check $file done diff --git a/fuzz/src/base32.rs b/fuzz/src/base32.rs index 8171f19f637..c0d71dd7b33 100644 --- a/fuzz/src/base32.rs +++ b/fuzz/src/base32.rs @@ -16,9 +16,11 @@ pub fn do_test(data: &[u8]) { if let Ok(s) = std::str::from_utf8(data) { let first_decoding = base32::Alphabet::RFC4648 { padding: true }.decode(s); if let Ok(first_decoding) = first_decoding { - let encoding_response = base32::Alphabet::RFC4648 { padding: true }.encode(&first_decoding); + let encoding_response = + base32::Alphabet::RFC4648 { padding: true }.encode(&first_decoding); assert_eq!(encoding_response, s.to_ascii_uppercase()); - let second_decoding = base32::Alphabet::RFC4648 { padding: true }.decode(&encoding_response).unwrap(); + let second_decoding = + base32::Alphabet::RFC4648 { padding: true }.decode(&encoding_response).unwrap(); assert_eq!(first_decoding, second_decoding); } } @@ -26,19 +28,23 @@ pub fn do_test(data: &[u8]) { if let Ok(s) = std::str::from_utf8(data) { let first_decoding = base32::Alphabet::RFC4648 { padding: false }.decode(s); if let Ok(first_decoding) = first_decoding { - let encoding_response = base32::Alphabet::RFC4648 { padding: false }.encode(&first_decoding); + let encoding_response = + base32::Alphabet::RFC4648 { padding: false }.encode(&first_decoding); assert_eq!(encoding_response, s.to_ascii_uppercase()); - let second_decoding = base32::Alphabet::RFC4648 { padding: false }.decode(&encoding_response).unwrap(); + let second_decoding = + base32::Alphabet::RFC4648 { padding: false }.decode(&encoding_response).unwrap(); assert_eq!(first_decoding, second_decoding); } } - + let encode_response = base32::Alphabet::RFC4648 { padding: false }.encode(&data); - let decode_response = base32::Alphabet::RFC4648 { padding: false }.decode(&encode_response).unwrap(); + let decode_response = + base32::Alphabet::RFC4648 { padding: false }.decode(&encode_response).unwrap(); assert_eq!(data, decode_response); let encode_response = base32::Alphabet::RFC4648 { padding: true }.encode(&data); - let decode_response = base32::Alphabet::RFC4648 { padding: true }.decode(&encode_response).unwrap(); + let decode_response = + base32::Alphabet::RFC4648 { padding: true }.decode(&encode_response).unwrap(); assert_eq!(data, decode_response); } diff --git a/fuzz/src/bin/base32_target.rs b/fuzz/src/bin/base32_target.rs index cb8620df36f..7937f30855c 100644 --- a/fuzz/src/bin/base32_target.rs +++ b/fuzz/src/bin/base32_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/bech32_parse_target.rs b/fuzz/src/bin/bech32_parse_target.rs index d05ad98191b..62f588d3169 100644 --- a/fuzz/src/bin/bech32_parse_target.rs +++ b/fuzz/src/bin/bech32_parse_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/bolt11_deser_target.rs b/fuzz/src/bin/bolt11_deser_target.rs index 30091c36e8e..f79140ae5eb 100644 --- a/fuzz/src/bin/bolt11_deser_target.rs +++ b/fuzz/src/bin/bolt11_deser_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/chanmon_consistency_target.rs b/fuzz/src/bin/chanmon_consistency_target.rs index 0b03b43c8f6..c4788b0c1b2 100644 --- a/fuzz/src/bin/chanmon_consistency_target.rs +++ b/fuzz/src/bin/chanmon_consistency_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/chanmon_deser_target.rs b/fuzz/src/bin/chanmon_deser_target.rs index 40bbf260df2..e58b8030217 100644 --- a/fuzz/src/bin/chanmon_deser_target.rs +++ b/fuzz/src/bin/chanmon_deser_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/fromstr_to_netaddress_target.rs b/fuzz/src/bin/fromstr_to_netaddress_target.rs index 27f7d8ae9ee..d86d521c762 100644 --- a/fuzz/src/bin/fromstr_to_netaddress_target.rs +++ b/fuzz/src/bin/fromstr_to_netaddress_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/full_stack_target.rs b/fuzz/src/bin/full_stack_target.rs index 1f5238940e5..33bac418f38 100644 --- a/fuzz/src/bin/full_stack_target.rs +++ b/fuzz/src/bin/full_stack_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/indexedmap_target.rs b/fuzz/src/bin/indexedmap_target.rs index 93f7a012ff7..3830e6a24a6 100644 --- a/fuzz/src/bin/indexedmap_target.rs +++ b/fuzz/src/bin/indexedmap_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/invoice_deser_target.rs b/fuzz/src/bin/invoice_deser_target.rs index 14aea952714..ed79d246a58 100644 --- a/fuzz/src/bin/invoice_deser_target.rs +++ b/fuzz/src/bin/invoice_deser_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/invoice_request_deser_target.rs b/fuzz/src/bin/invoice_request_deser_target.rs index c86dbb1c27c..47fd3361fcc 100644 --- a/fuzz/src/bin/invoice_request_deser_target.rs +++ b/fuzz/src/bin/invoice_request_deser_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_accept_channel_target.rs b/fuzz/src/bin/msg_accept_channel_target.rs index 43ae124b428..0b5fa27bcc7 100644 --- a/fuzz/src/bin/msg_accept_channel_target.rs +++ b/fuzz/src/bin/msg_accept_channel_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_accept_channel_v2_target.rs b/fuzz/src/bin/msg_accept_channel_v2_target.rs index 012c1b24ebc..efb02c7acf4 100644 --- a/fuzz/src/bin/msg_accept_channel_v2_target.rs +++ b/fuzz/src/bin/msg_accept_channel_v2_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_announcement_signatures_target.rs b/fuzz/src/bin/msg_announcement_signatures_target.rs index 7608f104580..684f1361f38 100644 --- a/fuzz/src/bin/msg_announcement_signatures_target.rs +++ b/fuzz/src/bin/msg_announcement_signatures_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_channel_announcement_target.rs b/fuzz/src/bin/msg_channel_announcement_target.rs index cf4c1462703..8f326790e0a 100644 --- a/fuzz/src/bin/msg_channel_announcement_target.rs +++ b/fuzz/src/bin/msg_channel_announcement_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_channel_details_target.rs b/fuzz/src/bin/msg_channel_details_target.rs index 4040a7c0084..34f51a30bde 100644 --- a/fuzz/src/bin/msg_channel_details_target.rs +++ b/fuzz/src/bin/msg_channel_details_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_channel_ready_target.rs b/fuzz/src/bin/msg_channel_ready_target.rs index f8cfef2dff4..76733dbecfe 100644 --- a/fuzz/src/bin/msg_channel_ready_target.rs +++ b/fuzz/src/bin/msg_channel_ready_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_channel_reestablish_target.rs b/fuzz/src/bin/msg_channel_reestablish_target.rs index 3aa6dc231d2..cdb4f1048e3 100644 --- a/fuzz/src/bin/msg_channel_reestablish_target.rs +++ b/fuzz/src/bin/msg_channel_reestablish_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_channel_update_target.rs b/fuzz/src/bin/msg_channel_update_target.rs index bb4902dcfc0..0b567c18b81 100644 --- a/fuzz/src/bin/msg_channel_update_target.rs +++ b/fuzz/src/bin/msg_channel_update_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_closing_signed_target.rs b/fuzz/src/bin/msg_closing_signed_target.rs index 0985ab52287..1634b109da9 100644 --- a/fuzz/src/bin/msg_closing_signed_target.rs +++ b/fuzz/src/bin/msg_closing_signed_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_commitment_signed_target.rs b/fuzz/src/bin/msg_commitment_signed_target.rs index f0b26cdc561..0c00a4ceb5a 100644 --- a/fuzz/src/bin/msg_commitment_signed_target.rs +++ b/fuzz/src/bin/msg_commitment_signed_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs b/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs index 5801fbef62b..93f3c66b207 100644 --- a/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs +++ b/fuzz/src/bin/msg_decoded_onion_error_packet_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_error_message_target.rs b/fuzz/src/bin/msg_error_message_target.rs index c36e553bfb3..4840e2bdfe9 100644 --- a/fuzz/src/bin/msg_error_message_target.rs +++ b/fuzz/src/bin/msg_error_message_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_funding_created_target.rs b/fuzz/src/bin/msg_funding_created_target.rs index 1787e9ddb24..f8884116710 100644 --- a/fuzz/src/bin/msg_funding_created_target.rs +++ b/fuzz/src/bin/msg_funding_created_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_funding_signed_target.rs b/fuzz/src/bin/msg_funding_signed_target.rs index 1f0da2a8eaa..42d0316dc9a 100644 --- a/fuzz/src/bin/msg_funding_signed_target.rs +++ b/fuzz/src/bin/msg_funding_signed_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_gossip_timestamp_filter_target.rs b/fuzz/src/bin/msg_gossip_timestamp_filter_target.rs index fe41f3ddd3a..0a47f773114 100644 --- a/fuzz/src/bin/msg_gossip_timestamp_filter_target.rs +++ b/fuzz/src/bin/msg_gossip_timestamp_filter_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_init_target.rs b/fuzz/src/bin/msg_init_target.rs index b4872cc155b..db0c8a8894f 100644 --- a/fuzz/src/bin/msg_init_target.rs +++ b/fuzz/src/bin/msg_init_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_node_announcement_target.rs b/fuzz/src/bin/msg_node_announcement_target.rs index a9fe444deff..1c20a999aaa 100644 --- a/fuzz/src/bin/msg_node_announcement_target.rs +++ b/fuzz/src/bin/msg_node_announcement_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_open_channel_target.rs b/fuzz/src/bin/msg_open_channel_target.rs index ff623cda998..fc6df814dd1 100644 --- a/fuzz/src/bin/msg_open_channel_target.rs +++ b/fuzz/src/bin/msg_open_channel_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_open_channel_v2_target.rs b/fuzz/src/bin/msg_open_channel_v2_target.rs index dfc901f7ac8..732daed18c3 100644 --- a/fuzz/src/bin/msg_open_channel_v2_target.rs +++ b/fuzz/src/bin/msg_open_channel_v2_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_ping_target.rs b/fuzz/src/bin/msg_ping_target.rs index bf7c553541d..bb1a59b9bad 100644 --- a/fuzz/src/bin/msg_ping_target.rs +++ b/fuzz/src/bin/msg_ping_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_pong_target.rs b/fuzz/src/bin/msg_pong_target.rs index a8e4285d171..7a97d93e785 100644 --- a/fuzz/src/bin/msg_pong_target.rs +++ b/fuzz/src/bin/msg_pong_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_query_channel_range_target.rs b/fuzz/src/bin/msg_query_channel_range_target.rs index e07a046cb38..4fd3260db0a 100644 --- a/fuzz/src/bin/msg_query_channel_range_target.rs +++ b/fuzz/src/bin/msg_query_channel_range_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_query_short_channel_ids_target.rs b/fuzz/src/bin/msg_query_short_channel_ids_target.rs index 25fcf311ee1..63f8c48fb3b 100644 --- a/fuzz/src/bin/msg_query_short_channel_ids_target.rs +++ b/fuzz/src/bin/msg_query_short_channel_ids_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_reply_channel_range_target.rs b/fuzz/src/bin/msg_reply_channel_range_target.rs index a0b54f691da..8e5ce619fa4 100644 --- a/fuzz/src/bin/msg_reply_channel_range_target.rs +++ b/fuzz/src/bin/msg_reply_channel_range_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs b/fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs index 464641e5b54..9b9b528abe5 100644 --- a/fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs +++ b/fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_revoke_and_ack_target.rs b/fuzz/src/bin/msg_revoke_and_ack_target.rs index be20070b012..1f401dae773 100644 --- a/fuzz/src/bin/msg_revoke_and_ack_target.rs +++ b/fuzz/src/bin/msg_revoke_and_ack_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_shutdown_target.rs b/fuzz/src/bin/msg_shutdown_target.rs index 9a4cbeb639e..c29bb93bb0b 100644 --- a/fuzz/src/bin/msg_shutdown_target.rs +++ b/fuzz/src/bin/msg_shutdown_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_splice_ack_target.rs b/fuzz/src/bin/msg_splice_ack_target.rs index 15b546b202c..9957a85552f 100644 --- a/fuzz/src/bin/msg_splice_ack_target.rs +++ b/fuzz/src/bin/msg_splice_ack_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_splice_locked_target.rs b/fuzz/src/bin/msg_splice_locked_target.rs index afc6b146579..d9dfcf956be 100644 --- a/fuzz/src/bin/msg_splice_locked_target.rs +++ b/fuzz/src/bin/msg_splice_locked_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_splice_target.rs b/fuzz/src/bin/msg_splice_target.rs index 475c5997171..a88b189b43b 100644 --- a/fuzz/src/bin/msg_splice_target.rs +++ b/fuzz/src/bin/msg_splice_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_stfu_target.rs b/fuzz/src/bin/msg_stfu_target.rs index 9b75073b825..bdef12d4c32 100644 --- a/fuzz/src/bin/msg_stfu_target.rs +++ b/fuzz/src/bin/msg_stfu_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_abort_target.rs b/fuzz/src/bin/msg_tx_abort_target.rs index bbfd4ab8163..76f098b1e2c 100644 --- a/fuzz/src/bin/msg_tx_abort_target.rs +++ b/fuzz/src/bin/msg_tx_abort_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_ack_rbf_target.rs b/fuzz/src/bin/msg_tx_ack_rbf_target.rs index 1d22dcea4b1..1f549a5703f 100644 --- a/fuzz/src/bin/msg_tx_ack_rbf_target.rs +++ b/fuzz/src/bin/msg_tx_ack_rbf_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_add_input_target.rs b/fuzz/src/bin/msg_tx_add_input_target.rs index 7a858880ece..9b7e1cfe7e6 100644 --- a/fuzz/src/bin/msg_tx_add_input_target.rs +++ b/fuzz/src/bin/msg_tx_add_input_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_add_output_target.rs b/fuzz/src/bin/msg_tx_add_output_target.rs index 2fcac4bebae..b8ad29581bc 100644 --- a/fuzz/src/bin/msg_tx_add_output_target.rs +++ b/fuzz/src/bin/msg_tx_add_output_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_complete_target.rs b/fuzz/src/bin/msg_tx_complete_target.rs index 9856c2cdf4c..28b295b0d25 100644 --- a/fuzz/src/bin/msg_tx_complete_target.rs +++ b/fuzz/src/bin/msg_tx_complete_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_init_rbf_target.rs b/fuzz/src/bin/msg_tx_init_rbf_target.rs index 88657e1105a..24fa793315d 100644 --- a/fuzz/src/bin/msg_tx_init_rbf_target.rs +++ b/fuzz/src/bin/msg_tx_init_rbf_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_remove_input_target.rs b/fuzz/src/bin/msg_tx_remove_input_target.rs index 02801865f6b..abe4190a354 100644 --- a/fuzz/src/bin/msg_tx_remove_input_target.rs +++ b/fuzz/src/bin/msg_tx_remove_input_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_remove_output_target.rs b/fuzz/src/bin/msg_tx_remove_output_target.rs index 4e1398135b8..3d084e0048d 100644 --- a/fuzz/src/bin/msg_tx_remove_output_target.rs +++ b/fuzz/src/bin/msg_tx_remove_output_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_tx_signatures_target.rs b/fuzz/src/bin/msg_tx_signatures_target.rs index abb3ab82ac5..fa3b966b478 100644 --- a/fuzz/src/bin/msg_tx_signatures_target.rs +++ b/fuzz/src/bin/msg_tx_signatures_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_update_add_htlc_target.rs b/fuzz/src/bin/msg_update_add_htlc_target.rs index ae8ba13a25d..f3c25a37524 100644 --- a/fuzz/src/bin/msg_update_add_htlc_target.rs +++ b/fuzz/src/bin/msg_update_add_htlc_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_update_fail_htlc_target.rs b/fuzz/src/bin/msg_update_fail_htlc_target.rs index 8767c7a31ad..9698ae92cfe 100644 --- a/fuzz/src/bin/msg_update_fail_htlc_target.rs +++ b/fuzz/src/bin/msg_update_fail_htlc_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs b/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs index 1d5d7daf2f2..b7f511c5ff5 100644 --- a/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs +++ b/fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_update_fee_target.rs b/fuzz/src/bin/msg_update_fee_target.rs index 207df698f6a..b021107f150 100644 --- a/fuzz/src/bin/msg_update_fee_target.rs +++ b/fuzz/src/bin/msg_update_fee_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/msg_update_fulfill_htlc_target.rs b/fuzz/src/bin/msg_update_fulfill_htlc_target.rs index f8e26535910..d87cd5bd490 100644 --- a/fuzz/src/bin/msg_update_fulfill_htlc_target.rs +++ b/fuzz/src/bin/msg_update_fulfill_htlc_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/offer_deser_target.rs b/fuzz/src/bin/offer_deser_target.rs index 64b2c4460dd..51cdb09adec 100644 --- a/fuzz/src/bin/offer_deser_target.rs +++ b/fuzz/src/bin/offer_deser_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/onion_hop_data_target.rs b/fuzz/src/bin/onion_hop_data_target.rs index 0043cee63ce..50d98043d05 100644 --- a/fuzz/src/bin/onion_hop_data_target.rs +++ b/fuzz/src/bin/onion_hop_data_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/onion_message_target.rs b/fuzz/src/bin/onion_message_target.rs index 1c28f5608ec..7bb09477ec5 100644 --- a/fuzz/src/bin/onion_message_target.rs +++ b/fuzz/src/bin/onion_message_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/peer_crypt_target.rs b/fuzz/src/bin/peer_crypt_target.rs index 8690f233251..0ba0252c963 100644 --- a/fuzz/src/bin/peer_crypt_target.rs +++ b/fuzz/src/bin/peer_crypt_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/process_network_graph_target.rs b/fuzz/src/bin/process_network_graph_target.rs index 5b5d8f81615..4ce10e6d4df 100644 --- a/fuzz/src/bin/process_network_graph_target.rs +++ b/fuzz/src/bin/process_network_graph_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/refund_deser_target.rs b/fuzz/src/bin/refund_deser_target.rs index fca53dd2dec..fea8a9c4c6d 100644 --- a/fuzz/src/bin/refund_deser_target.rs +++ b/fuzz/src/bin/refund_deser_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/router_target.rs b/fuzz/src/bin/router_target.rs index f9808ebc80f..0ebec549455 100644 --- a/fuzz/src/bin/router_target.rs +++ b/fuzz/src/bin/router_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/target_template.txt b/fuzz/src/bin/target_template.txt index 7603ccb2719..e828aa998b1 100644 --- a/fuzz/src/bin/target_template.txt +++ b/fuzz/src/bin/target_template.txt @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/bin/zbase32_target.rs b/fuzz/src/bin/zbase32_target.rs index e0ad2c5bcd1..35aa53d1fff 100644 --- a/fuzz/src/bin/zbase32_target.rs +++ b/fuzz/src/bin/zbase32_target.rs @@ -11,6 +11,7 @@ // To modify it, modify target_template.txt and run gen_target.sh instead. #![cfg_attr(feature = "libfuzzer_fuzz", no_main)] +#![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(not(fuzzing))] compile_error!("Fuzz targets need cfg=fuzzing"); diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 1bcba1fbf37..1cdf617fa07 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -34,7 +34,6 @@ use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::hash_types::BlockHash; use lightning::blinded_path::BlindedPath; -use lightning::blinded_path::message::ForwardNode; use lightning::blinded_path::payment::ReceiveTlvs; use lightning::chain; use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, chainmonitor, channelmonitor, Confirm, Watch}; @@ -124,7 +123,7 @@ impl MessageRouter for FuzzRouter { } fn create_blinded_paths( - &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1, + &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1, ) -> Result, ()> { unreachable!() } diff --git a/fuzz/src/chanmon_deser.rs b/fuzz/src/chanmon_deser.rs index 8d425357c96..b9c01213772 100644 --- a/fuzz/src/chanmon_deser.rs +++ b/fuzz/src/chanmon_deser.rs @@ -4,8 +4,8 @@ use bitcoin::hash_types::BlockHash; use lightning::chain::channelmonitor; +use lightning::util::ser::{ReadableArgs, Writeable, Writer}; use lightning::util::test_channel_signer::TestChannelSigner; -use lightning::util::ser::{ReadableArgs, Writer, Writeable}; use lightning::util::test_utils::OnlyReadsKeysInterface; use crate::utils::test_logger; @@ -22,10 +22,19 @@ impl Writer for VecWriter { #[inline] pub fn do_test(data: &[u8], _out: Out) { - if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(data), (&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {})) { + if let Ok((latest_block_hash, monitor)) = + <(BlockHash, channelmonitor::ChannelMonitor)>::read( + &mut Cursor::new(data), + (&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {}), + ) { let mut w = VecWriter(Vec::new()); monitor.write(&mut w).unwrap(); - let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(&w.0), (&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {})).unwrap(); + let deserialized_copy = + <(BlockHash, channelmonitor::ChannelMonitor)>::read( + &mut Cursor::new(&w.0), + (&OnlyReadsKeysInterface {}, &OnlyReadsKeysInterface {}), + ) + .unwrap(); assert!(latest_block_hash == deserialized_copy.0); assert!(monitor == deserialized_copy.1); } @@ -37,5 +46,5 @@ pub fn chanmon_deser_test(data: &[u8], out: Out) { #[no_mangle] pub extern "C" fn chanmon_deser_run(data: *const u8, datalen: usize) { - do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull{}); + do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {}); } diff --git a/fuzz/src/fromstr_to_netaddress.rs b/fuzz/src/fromstr_to_netaddress.rs index dba2d44451e..384ea56a8ef 100644 --- a/fuzz/src/fromstr_to_netaddress.rs +++ b/fuzz/src/fromstr_to_netaddress.rs @@ -7,8 +7,8 @@ // You may not use this file except in accordance with one or both of these // licenses. -use lightning::ln::msgs::SocketAddress; use core::str::FromStr; +use lightning::ln::msgs::SocketAddress; use crate::utils::test_logger; @@ -17,7 +17,6 @@ pub fn do_test(data: &[u8]) { if let Ok(s) = std::str::from_utf8(data) { let _ = SocketAddress::from_str(s); } - } pub fn fromstr_to_netaddress_test(data: &[u8], _out: Out) { @@ -28,4 +27,3 @@ pub fn fromstr_to_netaddress_test(data: &[u8], _out: O pub extern "C" fn fromstr_to_netaddress_run(data: *const u8, datalen: usize) { do_test(unsafe { std::slice::from_raw_parts(data, datalen) }); } - diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 2ae5ba2225d..bdd29be9129 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -31,7 +31,6 @@ use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::hash_types::{Txid, BlockHash}; use lightning::blinded_path::BlindedPath; -use lightning::blinded_path::message::ForwardNode; use lightning::blinded_path::payment::ReceiveTlvs; use lightning::chain; use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen}; @@ -162,7 +161,7 @@ impl MessageRouter for FuzzRouter { } fn create_blinded_paths( - &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1, + &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1, ) -> Result, ()> { unreachable!() } diff --git a/fuzz/src/indexedmap.rs b/fuzz/src/indexedmap.rs index 58775d02467..ee21f04619f 100644 --- a/fuzz/src/indexedmap.rs +++ b/fuzz/src/indexedmap.rs @@ -7,23 +7,31 @@ // You may not use this file except in accordance with one or both of these // licenses. -use lightning::util::indexed_map::{IndexedMap, self}; -use std::collections::{BTreeMap, btree_map}; use lightning::util::hash_tables::*; +use lightning::util::indexed_map::{self, IndexedMap}; +use std::collections::{btree_map, BTreeMap}; use crate::utils::test_logger; -use std::ops::{RangeBounds, Bound}; +use std::ops::{Bound, RangeBounds}; struct ExclLowerInclUpper(u8, u8); impl RangeBounds for ExclLowerInclUpper { - fn start_bound(&self) -> Bound<&u8> { Bound::Excluded(&self.0) } - fn end_bound(&self) -> Bound<&u8> { Bound::Included(&self.1) } + fn start_bound(&self) -> Bound<&u8> { + Bound::Excluded(&self.0) + } + fn end_bound(&self) -> Bound<&u8> { + Bound::Included(&self.1) + } } struct ExclLowerExclUpper(u8, u8); impl RangeBounds for ExclLowerExclUpper { - fn start_bound(&self) -> Bound<&u8> { Bound::Excluded(&self.0) } - fn end_bound(&self) -> Bound<&u8> { Bound::Excluded(&self.1) } + fn start_bound(&self) -> Bound<&u8> { + Bound::Excluded(&self.0) + } + fn end_bound(&self) -> Bound<&u8> { + Bound::Excluded(&self.1) + } } fn check_eq(btree: &BTreeMap, mut indexed: IndexedMap) { @@ -46,36 +54,44 @@ fn check_eq(btree: &BTreeMap, mut indexed: IndexedMap) { if let indexed_map::Entry::Occupied(mut io) = indexed_entry { assert_eq!(bo.get(), io.get()); assert_eq!(bo.get_mut(), io.get_mut()); - } else { panic!(); } + } else { + panic!(); + } }, btree_map::Entry::Vacant(_) => { if let indexed_map::Entry::Vacant(_) = indexed_entry { - } else { panic!(); } - } + } else { + panic!(); + } + }, } } const STRIDE: u8 = 16; for range_type in 0..4 { - for k in 0..=255/STRIDE { + for k in 0..=255 / STRIDE { let lower_bound = k * STRIDE; let upper_bound = lower_bound + (STRIDE - 1); - macro_rules! range { ($map: expr) => { - match range_type { - 0 => $map.range(lower_bound..upper_bound), - 1 => $map.range(lower_bound..=upper_bound), - 2 => $map.range(ExclLowerInclUpper(lower_bound, upper_bound)), - 3 => $map.range(ExclLowerExclUpper(lower_bound, upper_bound)), - _ => unreachable!(), - } - } } + macro_rules! range { + ($map: expr) => { + match range_type { + 0 => $map.range(lower_bound..upper_bound), + 1 => $map.range(lower_bound..=upper_bound), + 2 => $map.range(ExclLowerInclUpper(lower_bound, upper_bound)), + 3 => $map.range(ExclLowerExclUpper(lower_bound, upper_bound)), + _ => unreachable!(), + } + }; + } let mut btree_iter = range!(btree); let mut indexed_iter = range!(indexed); loop { let b_v = btree_iter.next(); let i_v = indexed_iter.next(); assert_eq!(b_v, i_v); - if b_v.is_none() { break; } + if b_v.is_none() { + break; + } } } } @@ -104,7 +120,9 @@ fn check_eq(btree: &BTreeMap, mut indexed: IndexedMap) { #[inline] pub fn do_test(data: &[u8]) { - if data.len() % 2 != 0 { return; } + if data.len() % 2 != 0 { + return; + } let mut btree = BTreeMap::new(); let mut indexed = IndexedMap::new(); @@ -138,13 +156,17 @@ pub fn do_test(data: &[u8]) { } else { assert_eq!(bo.remove_entry(), io.remove_entry()); } - } else { panic!(); } + } else { + panic!(); + } }, btree_map::Entry::Vacant(bv) => { if let indexed_map::Entry::Vacant(iv) = indexed.entry(k) { bv.insert(k); iv.insert(k); - } else { panic!(); } + } else { + panic!(); + } }, } } diff --git a/fuzz/src/invoice_request_deser.rs b/fuzz/src/invoice_request_deser.rs index 1381f6697d1..642da58236f 100644 --- a/fuzz/src/invoice_request_deser.rs +++ b/fuzz/src/invoice_request_deser.rs @@ -7,17 +7,17 @@ // You may not use this file except in accordance with one or both of these // licenses. -use bitcoin::secp256k1::{Keypair, Parity, PublicKey, Secp256k1, SecretKey, self}; use crate::utils::test_logger; +use bitcoin::secp256k1::{self, Keypair, Parity, PublicKey, Secp256k1, SecretKey}; use core::convert::TryFrom; -use lightning::blinded_path::BlindedPath; use lightning::blinded_path::message::ForwardNode; -use lightning::sign::EntropySource; -use lightning::ln::PaymentHash; +use lightning::blinded_path::BlindedPath; use lightning::ln::features::BlindedHopFeatures; +use lightning::ln::PaymentHash; use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice}; use lightning::offers::invoice_request::InvoiceRequest; use lightning::offers::parse::Bolt12SemanticError; +use lightning::sign::EntropySource; use lightning::util::ser::Writeable; #[inline] @@ -38,17 +38,17 @@ pub fn do_test(data: &[u8], _out: Out) { let even_pubkey = x_only_pubkey.public_key(Parity::Even); if signing_pubkey == odd_pubkey || signing_pubkey == even_pubkey { unsigned_invoice - .sign(|message: &UnsignedBolt12Invoice| + .sign(|message: &UnsignedBolt12Invoice| { Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) - ) + }) .unwrap() .write(&mut buffer) .unwrap(); } else { unsigned_invoice - .sign(|message: &UnsignedBolt12Invoice| + .sign(|message: &UnsignedBolt12Invoice| { Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) - ) + }) .unwrap_err(); } } @@ -58,7 +58,9 @@ pub fn do_test(data: &[u8], _out: Out) { struct Randomness; impl EntropySource for Randomness { - fn get_secure_random_bytes(&self) -> [u8; 32] { [42; 32] } + fn get_secure_random_bytes(&self) -> [u8; 32] { + [42; 32] + } } fn pubkey(byte: u8) -> PublicKey { @@ -71,7 +73,7 @@ fn privkey(byte: u8) -> SecretKey { } fn build_response( - invoice_request: &InvoiceRequest, secp_ctx: &Secp256k1 + invoice_request: &InvoiceRequest, secp_ctx: &Secp256k1, ) -> Result { let entropy_source = Randomness {}; let intermediate_nodes = [ @@ -85,8 +87,10 @@ fn build_response( ], ]; let paths = vec![ - BlindedPath::new_for_message(&intermediate_nodes[0], pubkey(42), &entropy_source, secp_ctx).unwrap(), - BlindedPath::new_for_message(&intermediate_nodes[1], pubkey(42), &entropy_source, secp_ctx).unwrap(), + BlindedPath::new_for_message(&intermediate_nodes[0], pubkey(42), &entropy_source, secp_ctx) + .unwrap(), + BlindedPath::new_for_message(&intermediate_nodes[1], pubkey(42), &entropy_source, secp_ctx) + .unwrap(), ]; let payinfo = vec![ diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs index 6efdd94dfcb..2e132edce42 100644 --- a/fuzz/src/lib.rs +++ b/fuzz/src/lib.rs @@ -8,29 +8,29 @@ // licenses. extern crate bitcoin; +extern crate hex; extern crate lightning; extern crate lightning_rapid_gossip_sync; -extern crate hex; pub mod utils; +pub mod base32; pub mod bech32_parse; -pub mod chanmon_deser; +pub mod bolt11_deser; pub mod chanmon_consistency; +pub mod chanmon_deser; +pub mod fromstr_to_netaddress; pub mod full_stack; pub mod indexedmap; pub mod invoice_deser; pub mod invoice_request_deser; pub mod offer_deser; -pub mod bolt11_deser; +pub mod onion_hop_data; pub mod onion_message; pub mod peer_crypt; pub mod process_network_graph; pub mod refund_deser; pub mod router; pub mod zbase32; -pub mod onion_hop_data; -pub mod base32; -pub mod fromstr_to_netaddress; pub mod msg_targets; diff --git a/fuzz/src/msg_targets/gen_target.sh b/fuzz/src/msg_targets/gen_target.sh index 8bce10059f5..05997c07573 100755 --- a/fuzz/src/msg_targets/gen_target.sh +++ b/fuzz/src/msg_targets/gen_target.sh @@ -7,7 +7,10 @@ GEN_TEST() { echo "pub mod $tn;" >> mod.rs } -echo "mod utils;" > mod.rs +{ + echo "#![cfg_attr(rustfmt, rustfmt_skip)]" + echo "mod utils;" +} > mod.rs # Note when adding new targets here you should add a similar line in src/bin/gen_target.sh diff --git a/fuzz/src/msg_targets/mod.rs b/fuzz/src/msg_targets/mod.rs index 837bee65dec..15750a9a5b1 100644 --- a/fuzz/src/msg_targets/mod.rs +++ b/fuzz/src/msg_targets/mod.rs @@ -1,3 +1,4 @@ +#![cfg_attr(rustfmt, rustfmt_skip)] mod utils; pub mod msg_accept_channel; pub mod msg_announcement_signatures; diff --git a/fuzz/src/msg_targets/msg_accept_channel.rs b/fuzz/src/msg_targets/msg_accept_channel.rs index d4e7acf1da7..216fe7c59bd 100644 --- a/fuzz/src/msg_targets/msg_accept_channel.rs +++ b/fuzz/src/msg_targets/msg_accept_channel.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_accept_channel_v2.rs b/fuzz/src/msg_targets/msg_accept_channel_v2.rs index 36b646644ea..c1d7fb55c9b 100644 --- a/fuzz/src/msg_targets/msg_accept_channel_v2.rs +++ b/fuzz/src/msg_targets/msg_accept_channel_v2.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_announcement_signatures.rs b/fuzz/src/msg_targets/msg_announcement_signatures.rs index cf0ca2e2d85..6010e6001b6 100644 --- a/fuzz/src/msg_targets/msg_announcement_signatures.rs +++ b/fuzz/src/msg_targets/msg_announcement_signatures.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_channel_announcement.rs b/fuzz/src/msg_targets/msg_channel_announcement.rs index 0c67ca16edf..d4084c61893 100644 --- a/fuzz/src/msg_targets/msg_channel_announcement.rs +++ b/fuzz/src/msg_targets/msg_channel_announcement.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_channel_details.rs b/fuzz/src/msg_targets/msg_channel_details.rs index 59554fab177..eb9f8beee47 100644 --- a/fuzz/src/msg_targets/msg_channel_details.rs +++ b/fuzz/src/msg_targets/msg_channel_details.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_channel_ready.rs b/fuzz/src/msg_targets/msg_channel_ready.rs index 5b13486f56c..3180928905d 100644 --- a/fuzz/src/msg_targets/msg_channel_ready.rs +++ b/fuzz/src/msg_targets/msg_channel_ready.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_channel_reestablish.rs b/fuzz/src/msg_targets/msg_channel_reestablish.rs index fdc2d1fa62b..f766892a2e2 100644 --- a/fuzz/src/msg_targets/msg_channel_reestablish.rs +++ b/fuzz/src/msg_targets/msg_channel_reestablish.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_channel_update.rs b/fuzz/src/msg_targets/msg_channel_update.rs index 27dadaed562..358305b9dae 100644 --- a/fuzz/src/msg_targets/msg_channel_update.rs +++ b/fuzz/src/msg_targets/msg_channel_update.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_closing_signed.rs b/fuzz/src/msg_targets/msg_closing_signed.rs index 0497b1fcc65..74e04d6675a 100644 --- a/fuzz/src/msg_targets/msg_closing_signed.rs +++ b/fuzz/src/msg_targets/msg_closing_signed.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_commitment_signed.rs b/fuzz/src/msg_targets/msg_commitment_signed.rs index 8726efc586b..7ece314353d 100644 --- a/fuzz/src/msg_targets/msg_commitment_signed.rs +++ b/fuzz/src/msg_targets/msg_commitment_signed.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_decoded_onion_error_packet.rs b/fuzz/src/msg_targets/msg_decoded_onion_error_packet.rs index 3f5243d4e26..9d245e2f2d2 100644 --- a/fuzz/src/msg_targets/msg_decoded_onion_error_packet.rs +++ b/fuzz/src/msg_targets/msg_decoded_onion_error_packet.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_error_message.rs b/fuzz/src/msg_targets/msg_error_message.rs index 6d9d8e27e31..ae16e1686dc 100644 --- a/fuzz/src/msg_targets/msg_error_message.rs +++ b/fuzz/src/msg_targets/msg_error_message.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_funding_created.rs b/fuzz/src/msg_targets/msg_funding_created.rs index c03975da7b9..a6c5ba148c2 100644 --- a/fuzz/src/msg_targets/msg_funding_created.rs +++ b/fuzz/src/msg_targets/msg_funding_created.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_funding_signed.rs b/fuzz/src/msg_targets/msg_funding_signed.rs index 8788d34bc8f..34f0fddaad3 100644 --- a/fuzz/src/msg_targets/msg_funding_signed.rs +++ b/fuzz/src/msg_targets/msg_funding_signed.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_gossip_timestamp_filter.rs b/fuzz/src/msg_targets/msg_gossip_timestamp_filter.rs index 884449b06d5..8e0fb7c5380 100644 --- a/fuzz/src/msg_targets/msg_gossip_timestamp_filter.rs +++ b/fuzz/src/msg_targets/msg_gossip_timestamp_filter.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_init.rs b/fuzz/src/msg_targets/msg_init.rs index 1f21f4b3d5d..5f11441ddf5 100644 --- a/fuzz/src/msg_targets/msg_init.rs +++ b/fuzz/src/msg_targets/msg_init.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_node_announcement.rs b/fuzz/src/msg_targets/msg_node_announcement.rs index ab2ba755092..ce9bb30d3dd 100644 --- a/fuzz/src/msg_targets/msg_node_announcement.rs +++ b/fuzz/src/msg_targets/msg_node_announcement.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_open_channel.rs b/fuzz/src/msg_targets/msg_open_channel.rs index cacb5d767d6..9c924e501db 100644 --- a/fuzz/src/msg_targets/msg_open_channel.rs +++ b/fuzz/src/msg_targets/msg_open_channel.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_open_channel_v2.rs b/fuzz/src/msg_targets/msg_open_channel_v2.rs index 4f6457a3ebb..a43d58ee9e6 100644 --- a/fuzz/src/msg_targets/msg_open_channel_v2.rs +++ b/fuzz/src/msg_targets/msg_open_channel_v2.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_ping.rs b/fuzz/src/msg_targets/msg_ping.rs index 2509fef7e89..2ff54816474 100644 --- a/fuzz/src/msg_targets/msg_ping.rs +++ b/fuzz/src/msg_targets/msg_ping.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_pong.rs b/fuzz/src/msg_targets/msg_pong.rs index 1c90eefdb32..52b9ee08486 100644 --- a/fuzz/src/msg_targets/msg_pong.rs +++ b/fuzz/src/msg_targets/msg_pong.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_query_channel_range.rs b/fuzz/src/msg_targets/msg_query_channel_range.rs index fe2fb405143..6b59636780b 100644 --- a/fuzz/src/msg_targets/msg_query_channel_range.rs +++ b/fuzz/src/msg_targets/msg_query_channel_range.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_query_short_channel_ids.rs b/fuzz/src/msg_targets/msg_query_short_channel_ids.rs index bd8fa59d157..c15915fd1a8 100644 --- a/fuzz/src/msg_targets/msg_query_short_channel_ids.rs +++ b/fuzz/src/msg_targets/msg_query_short_channel_ids.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_reply_channel_range.rs b/fuzz/src/msg_targets/msg_reply_channel_range.rs index 43a3e0f3ddc..3cb94af6c23 100644 --- a/fuzz/src/msg_targets/msg_reply_channel_range.rs +++ b/fuzz/src/msg_targets/msg_reply_channel_range.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_reply_short_channel_ids_end.rs b/fuzz/src/msg_targets/msg_reply_short_channel_ids_end.rs index dc765c76b19..a53459997f9 100644 --- a/fuzz/src/msg_targets/msg_reply_short_channel_ids_end.rs +++ b/fuzz/src/msg_targets/msg_reply_short_channel_ids_end.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_revoke_and_ack.rs b/fuzz/src/msg_targets/msg_revoke_and_ack.rs index 9190c98e882..26f2d7524cd 100644 --- a/fuzz/src/msg_targets/msg_revoke_and_ack.rs +++ b/fuzz/src/msg_targets/msg_revoke_and_ack.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_shutdown.rs b/fuzz/src/msg_targets/msg_shutdown.rs index 26133f7d1db..77c4cfdaae3 100644 --- a/fuzz/src/msg_targets/msg_shutdown.rs +++ b/fuzz/src/msg_targets/msg_shutdown.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_splice.rs b/fuzz/src/msg_targets/msg_splice.rs index e6a18d2561c..f203da0562c 100644 --- a/fuzz/src/msg_targets/msg_splice.rs +++ b/fuzz/src/msg_targets/msg_splice.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_splice_ack.rs b/fuzz/src/msg_targets/msg_splice_ack.rs index cc77c198bb7..65949d273da 100644 --- a/fuzz/src/msg_targets/msg_splice_ack.rs +++ b/fuzz/src/msg_targets/msg_splice_ack.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_splice_locked.rs b/fuzz/src/msg_targets/msg_splice_locked.rs index 39e340fd40b..02e762ade70 100644 --- a/fuzz/src/msg_targets/msg_splice_locked.rs +++ b/fuzz/src/msg_targets/msg_splice_locked.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_stfu.rs b/fuzz/src/msg_targets/msg_stfu.rs index be2029194a7..87845cf28aa 100644 --- a/fuzz/src/msg_targets/msg_stfu.rs +++ b/fuzz/src/msg_targets/msg_stfu.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_target_template.txt b/fuzz/src/msg_targets/msg_target_template.txt index c6064388dca..f5ed99b64d0 100644 --- a/fuzz/src/msg_targets/msg_target_template.txt +++ b/fuzz/src/msg_targets/msg_target_template.txt @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_abort.rs b/fuzz/src/msg_targets/msg_tx_abort.rs index c361b654675..c80df485040 100644 --- a/fuzz/src/msg_targets/msg_tx_abort.rs +++ b/fuzz/src/msg_targets/msg_tx_abort.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_ack_rbf.rs b/fuzz/src/msg_targets/msg_tx_ack_rbf.rs index 9931bfcfb72..41fd1ed9c27 100644 --- a/fuzz/src/msg_targets/msg_tx_ack_rbf.rs +++ b/fuzz/src/msg_targets/msg_tx_ack_rbf.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_add_input.rs b/fuzz/src/msg_targets/msg_tx_add_input.rs index f212b59cd6a..8ae0c61034a 100644 --- a/fuzz/src/msg_targets/msg_tx_add_input.rs +++ b/fuzz/src/msg_targets/msg_tx_add_input.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_add_output.rs b/fuzz/src/msg_targets/msg_tx_add_output.rs index 49b23218fa1..04511ed599f 100644 --- a/fuzz/src/msg_targets/msg_tx_add_output.rs +++ b/fuzz/src/msg_targets/msg_tx_add_output.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_complete.rs b/fuzz/src/msg_targets/msg_tx_complete.rs index c4227b15235..4cd1a271284 100644 --- a/fuzz/src/msg_targets/msg_tx_complete.rs +++ b/fuzz/src/msg_targets/msg_tx_complete.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_init_rbf.rs b/fuzz/src/msg_targets/msg_tx_init_rbf.rs index ea021dc60ac..eab0a747ea8 100644 --- a/fuzz/src/msg_targets/msg_tx_init_rbf.rs +++ b/fuzz/src/msg_targets/msg_tx_init_rbf.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_remove_input.rs b/fuzz/src/msg_targets/msg_tx_remove_input.rs index fe69ad41b8d..1f934eac274 100644 --- a/fuzz/src/msg_targets/msg_tx_remove_input.rs +++ b/fuzz/src/msg_targets/msg_tx_remove_input.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_remove_output.rs b/fuzz/src/msg_targets/msg_tx_remove_output.rs index 6c09d4d9f41..a9e0e8b2ef1 100644 --- a/fuzz/src/msg_targets/msg_tx_remove_output.rs +++ b/fuzz/src/msg_targets/msg_tx_remove_output.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_tx_signatures.rs b/fuzz/src/msg_targets/msg_tx_signatures.rs index 54392d48cda..17dc063adc2 100644 --- a/fuzz/src/msg_targets/msg_tx_signatures.rs +++ b/fuzz/src/msg_targets/msg_tx_signatures.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_update_add_htlc.rs b/fuzz/src/msg_targets/msg_update_add_htlc.rs index e8edf4f4dd5..45a2616243a 100644 --- a/fuzz/src/msg_targets/msg_update_add_htlc.rs +++ b/fuzz/src/msg_targets/msg_update_add_htlc.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_update_fail_htlc.rs b/fuzz/src/msg_targets/msg_update_fail_htlc.rs index b93cc60b505..e338beeee2f 100644 --- a/fuzz/src/msg_targets/msg_update_fail_htlc.rs +++ b/fuzz/src/msg_targets/msg_update_fail_htlc.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_update_fail_malformed_htlc.rs b/fuzz/src/msg_targets/msg_update_fail_malformed_htlc.rs index 24718d54ade..6c1914f03ca 100644 --- a/fuzz/src/msg_targets/msg_update_fail_malformed_htlc.rs +++ b/fuzz/src/msg_targets/msg_update_fail_malformed_htlc.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_update_fee.rs b/fuzz/src/msg_targets/msg_update_fee.rs index 92661537bf7..991dde925f8 100644 --- a/fuzz/src/msg_targets/msg_update_fee.rs +++ b/fuzz/src/msg_targets/msg_update_fee.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_update_fulfill_htlc.rs b/fuzz/src/msg_targets/msg_update_fulfill_htlc.rs index 7f9463e2731..61e3f30b95c 100644 --- a/fuzz/src/msg_targets/msg_update_fulfill_htlc.rs +++ b/fuzz/src/msg_targets/msg_update_fulfill_htlc.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/msg_warning_message.rs b/fuzz/src/msg_targets/msg_warning_message.rs index a5bcf4111f6..0e1a4566677 100644 --- a/fuzz/src/msg_targets/msg_warning_message.rs +++ b/fuzz/src/msg_targets/msg_warning_message.rs @@ -10,6 +10,8 @@ // This file is auto-generated by gen_target.sh based on msg_target_template.txt // To modify it, modify msg_target_template.txt and run gen_target.sh instead. +#![cfg_attr(rustfmt, rustfmt_skip)] + use crate::msg_targets::utils::VecWriter; use crate::utils::test_logger; diff --git a/fuzz/src/msg_targets/utils.rs b/fuzz/src/msg_targets/utils.rs index 6325f3bf10d..5fa474cbf02 100644 --- a/fuzz/src/msg_targets/utils.rs +++ b/fuzz/src/msg_targets/utils.rs @@ -29,81 +29,73 @@ impl Writer for VecWriter { // entirely #[macro_export] macro_rules! test_msg { - ($MsgType: path, $data: ident) => { - { - use lightning::util::ser::{Writeable, Readable}; - let mut r = ::std::io::Cursor::new($data); - if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { - let p = r.position() as usize; - let mut w = VecWriter(Vec::new()); - msg.write(&mut w).unwrap(); + ($MsgType: path, $data: ident) => {{ + use lightning::util::ser::{Readable, Writeable}; + let mut r = ::std::io::Cursor::new($data); + if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { + let p = r.position() as usize; + let mut w = VecWriter(Vec::new()); + msg.write(&mut w).unwrap(); - assert_eq!(w.0.len(), p); - assert_eq!(msg.serialized_length(), p); - assert_eq!(&r.into_inner()[..p], &w.0[..p]); - } + assert_eq!(w.0.len(), p); + assert_eq!(msg.serialized_length(), p); + assert_eq!(&r.into_inner()[..p], &w.0[..p]); } - } + }}; } // Tests a message that may lose data on roundtrip, but shoulnd't lose data compared to our // re-serialization. #[macro_export] macro_rules! test_msg_simple { - ($MsgType: path, $data: ident) => { - { - use lightning::util::ser::{Writeable, Readable}; - let mut r = ::std::io::Cursor::new($data); - if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { - let mut w = VecWriter(Vec::new()); - msg.write(&mut w).unwrap(); - assert_eq!(msg.serialized_length(), w.0.len()); + ($MsgType: path, $data: ident) => {{ + use lightning::util::ser::{Readable, Writeable}; + let mut r = ::std::io::Cursor::new($data); + if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { + let mut w = VecWriter(Vec::new()); + msg.write(&mut w).unwrap(); + assert_eq!(msg.serialized_length(), w.0.len()); - let msg = <$MsgType as Readable>::read(&mut ::std::io::Cursor::new(&w.0)).unwrap(); - let mut w_two = VecWriter(Vec::new()); - msg.write(&mut w_two).unwrap(); - assert_eq!(&w.0[..], &w_two.0[..]); - } + let msg = <$MsgType as Readable>::read(&mut ::std::io::Cursor::new(&w.0)).unwrap(); + let mut w_two = VecWriter(Vec::new()); + msg.write(&mut w_two).unwrap(); + assert_eq!(&w.0[..], &w_two.0[..]); } - } + }}; } // Tests a message that must survive roundtrip exactly, and must exactly empty the read buffer and // split it back out on re-serialization. #[macro_export] macro_rules! test_msg_exact { - ($MsgType: path, $data: ident) => { - { - use lightning::util::ser::{Writeable, Readable}; - let mut r = ::std::io::Cursor::new($data); - if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { - let mut w = VecWriter(Vec::new()); - msg.write(&mut w).unwrap(); - assert_eq!(&r.into_inner()[..], &w.0[..]); - assert_eq!(msg.serialized_length(), w.0.len()); - } + ($MsgType: path, $data: ident) => {{ + use lightning::util::ser::{Readable, Writeable}; + let mut r = ::std::io::Cursor::new($data); + if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { + let mut w = VecWriter(Vec::new()); + msg.write(&mut w).unwrap(); + assert_eq!(&r.into_inner()[..], &w.0[..]); + assert_eq!(msg.serialized_length(), w.0.len()); } - } + }}; } // Tests a message that must survive roundtrip exactly, modulo one "hole" which may be set to // any value on re-serialization. #[macro_export] macro_rules! test_msg_hole { - ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => { - { - use lightning::util::ser::{Writeable, Readable}; - let mut r = ::std::io::Cursor::new($data); - if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { - let mut w = VecWriter(Vec::new()); - msg.write(&mut w).unwrap(); - let p = w.0.len() as usize; - assert_eq!(msg.serialized_length(), p); + ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => {{ + use lightning::util::ser::{Readable, Writeable}; + let mut r = ::std::io::Cursor::new($data); + if let Ok(msg) = <$MsgType as Readable>::read(&mut r) { + let mut w = VecWriter(Vec::new()); + msg.write(&mut w).unwrap(); + let p = w.0.len() as usize; + assert_eq!(msg.serialized_length(), p); - assert_eq!(w.0.len(), p); - assert_eq!(&r.get_ref()[..$hole], &w.0[..$hole]); - assert_eq!(&r.get_ref()[$hole+$hole_len..p], &w.0[$hole+$hole_len..]); - } + assert_eq!(w.0.len(), p); + assert_eq!(&r.get_ref()[..$hole], &w.0[..$hole]); + assert_eq!(&r.get_ref()[$hole + $hole_len..p], &w.0[$hole + $hole_len..]); } - } + }}; } diff --git a/fuzz/src/offer_deser.rs b/fuzz/src/offer_deser.rs index deaa6f3588b..84b69d3fcd3 100644 --- a/fuzz/src/offer_deser.rs +++ b/fuzz/src/offer_deser.rs @@ -7,8 +7,8 @@ // You may not use this file except in accordance with one or both of these // licenses. -use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, SecretKey}; use crate::utils::test_logger; +use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, SecretKey}; use core::convert::TryFrom; use lightning::offers::invoice_request::UnsignedInvoiceRequest; use lightning::offers::offer::{Amount, Offer, Quantity}; @@ -29,9 +29,9 @@ pub fn do_test(data: &[u8], _out: Out) { if let Ok(invoice_request) = build_response(&offer, pubkey) { invoice_request - .sign(|message: &UnsignedInvoiceRequest| + .sign(|message: &UnsignedInvoiceRequest| { Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) - ) + }) .unwrap() .write(&mut buffer) .unwrap(); @@ -40,7 +40,7 @@ pub fn do_test(data: &[u8], _out: Out) { } fn build_response( - offer: &Offer, pubkey: PublicKey + offer: &Offer, pubkey: PublicKey, ) -> Result { let mut builder = offer.request_invoice(vec![42; 64], pubkey)?; diff --git a/fuzz/src/onion_hop_data.rs b/fuzz/src/onion_hop_data.rs index e7f51b99167..36aebb4e194 100644 --- a/fuzz/src/onion_hop_data.rs +++ b/fuzz/src/onion_hop_data.rs @@ -15,19 +15,25 @@ use lightning::util::test_utils; #[inline] pub fn onion_hop_data_test(data: &[u8], _out: Out) { - use lightning::util::ser::ReadableArgs; use bitcoin::secp256k1::PublicKey; + use lightning::util::ser::ReadableArgs; let mut r = ::std::io::Cursor::new(data); let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42)); - let _ = , &&test_utils::TestNodeSigner)>>::read(&mut r, (None, &&node_signer)); + let _ = , + &&test_utils::TestNodeSigner, + )>>::read(&mut r, (None, &&node_signer)); } #[no_mangle] pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) { - use lightning::util::ser::ReadableArgs; use bitcoin::secp256k1::PublicKey; + use lightning::util::ser::ReadableArgs; let data = unsafe { std::slice::from_raw_parts(data, datalen) }; let mut r = ::std::io::Cursor::new(data); let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42)); - let _ = , &&test_utils::TestNodeSigner)>>::read(&mut r, (None, &&node_signer)); + let _ = , + &&test_utils::TestNodeSigner, + )>>::read(&mut r, (None, &&node_signer)); } diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index 4c1c5ac1122..a8a290fefb3 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -1,25 +1,27 @@ // Imports that need to be added manually use bech32::u5; use bitcoin::blockdata::script::ScriptBuf; -use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey, self}; use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1::ecdsa::RecoverableSignature; use bitcoin::secp256k1::schnorr; +use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey}; use lightning::blinded_path::{BlindedPath, EmptyNodeIdLookUp}; -use lightning::blinded_path::message::ForwardNode; use lightning::ln::features::InitFeatures; use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler}; use lightning::ln::script::ShutdownScript; use lightning::offers::invoice::UnsignedBolt12Invoice; use lightning::offers::invoice_request::UnsignedInvoiceRequest; -use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider}; -use lightning::util::test_channel_signer::TestChannelSigner; -use lightning::util::logger::Logger; -use lightning::util::ser::{Readable, Writeable, Writer}; -use lightning::onion_message::messenger::{CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger, PendingOnionMessage, Responder, ResponseInstruction}; +use lightning::onion_message::messenger::{ + CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger, + PendingOnionMessage, Responder, ResponseInstruction, +}; use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler}; use lightning::onion_message::packet::OnionMessageContents; +use lightning::sign::{EntropySource, KeyMaterial, NodeSigner, Recipient, SignerProvider}; +use lightning::util::logger::Logger; +use lightning::util::ser::{Readable, Writeable, Writer}; +use lightning::util::test_channel_signer::TestChannelSigner; use crate::utils::test_logger; @@ -33,17 +35,19 @@ pub fn do_test(data: &[u8], logger: &L) { let mut secret_bytes = [1; 32]; secret_bytes[31] = 2; let secret = SecretKey::from_slice(&secret_bytes).unwrap(); - let keys_manager = KeyProvider { - node_secret: secret, - counter: AtomicU64::new(0), - }; + let keys_manager = KeyProvider { node_secret: secret, counter: AtomicU64::new(0) }; let node_id_lookup = EmptyNodeIdLookUp {}; let message_router = TestMessageRouter {}; let offers_msg_handler = TestOffersMessageHandler {}; let custom_msg_handler = TestCustomMessageHandler {}; let onion_messenger = OnionMessenger::new( - &keys_manager, &keys_manager, logger, &node_id_lookup, &message_router, - &offers_msg_handler, &custom_msg_handler + &keys_manager, + &keys_manager, + logger, + &node_id_lookup, + &message_router, + &offers_msg_handler, + &custom_msg_handler, ); let peer_node_id = { @@ -79,17 +83,13 @@ struct TestMessageRouter {} impl MessageRouter for TestMessageRouter { fn find_path( - &self, _sender: PublicKey, _peers: Vec, destination: Destination + &self, _sender: PublicKey, _peers: Vec, destination: Destination, ) -> Result { - Ok(OnionMessagePath { - intermediate_nodes: vec![], - destination, - first_node_addresses: None, - }) + Ok(OnionMessagePath { intermediate_nodes: vec![], destination, first_node_addresses: None }) } fn create_blinded_paths( - &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1, + &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1, ) -> Result, ()> { unreachable!() } @@ -98,7 +98,9 @@ impl MessageRouter for TestMessageRouter { struct TestOffersMessageHandler {} impl OffersMessageHandler for TestOffersMessageHandler { - fn handle_message(&self, _message: OffersMessage, _responder: Option) -> ResponseInstruction { + fn handle_message( + &self, _message: OffersMessage, _responder: Option, + ) -> ResponseInstruction { ResponseInstruction::NoResponse } } @@ -128,16 +130,20 @@ struct TestCustomMessageHandler {} impl CustomOnionMessageHandler for TestCustomMessageHandler { type CustomMessage = TestCustomMessage; - fn handle_custom_message(&self, message: Self::CustomMessage, responder: Option) -> ResponseInstruction { + fn handle_custom_message( + &self, message: Self::CustomMessage, responder: Option, + ) -> ResponseInstruction { match responder { Some(responder) => responder.respond(message), - None => ResponseInstruction::NoResponse + None => ResponseInstruction::NoResponse, } } - fn read_custom_message(&self, _message_type: u64, buffer: &mut R) -> Result, msgs::DecodeError> { + fn read_custom_message( + &self, _message_type: u64, buffer: &mut R, + ) -> Result, msgs::DecodeError> { let mut buf = Vec::new(); buffer.read_to_end(&mut buf)?; - return Ok(Some(TestCustomMessage {})) + return Ok(Some(TestCustomMessage {})); } fn release_pending_custom_messages(&self) -> Vec> { vec![] @@ -159,8 +165,11 @@ struct KeyProvider { impl EntropySource for KeyProvider { fn get_secure_random_bytes(&self) -> [u8; 32] { let ctr = self.counter.fetch_add(1, Ordering::Relaxed); - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - (ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8] + #[rustfmt::skip] + let random_bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + (ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, + (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]; + random_bytes } } @@ -168,15 +177,17 @@ impl NodeSigner for KeyProvider { fn get_node_id(&self, recipient: Recipient) -> Result { let node_secret = match recipient { Recipient::Node => Ok(&self.node_secret), - Recipient::PhantomNode => Err(()) + Recipient::PhantomNode => Err(()), }?; Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret)) } - fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result { + fn ecdh( + &self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>, + ) -> Result { let mut node_secret = match recipient { Recipient::Node => Ok(self.node_secret.clone()), - Recipient::PhantomNode => Err(()) + Recipient::PhantomNode => Err(()), }?; if let Some(tweak) = tweak { node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?; @@ -184,14 +195,18 @@ impl NodeSigner for KeyProvider { Ok(SharedSecret::new(other_key, &node_secret)) } - fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!() } + fn get_inbound_payment_key_material(&self) -> KeyMaterial { + unreachable!() + } - fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result { + fn sign_invoice( + &self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient, + ) -> Result { unreachable!() } fn sign_bolt12_invoice_request( - &self, _invoice_request: &UnsignedInvoiceRequest + &self, _invoice_request: &UnsignedInvoiceRequest, ) -> Result { unreachable!() } @@ -202,7 +217,9 @@ impl NodeSigner for KeyProvider { unreachable!() } - fn sign_gossip_message(&self, _msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result { + fn sign_gossip_message( + &self, _msg: lightning::ln::msgs::UnsignedGossipMessage, + ) -> Result { unreachable!() } } @@ -212,17 +229,29 @@ impl SignerProvider for KeyProvider { #[cfg(taproot)] type TaprootSigner = TestChannelSigner; - fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!() } + fn generate_channel_keys_id( + &self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128, + ) -> [u8; 32] { + unreachable!() + } - fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { + fn derive_channel_signer( + &self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32], + ) -> Self::EcdsaSigner { unreachable!() } - fn read_chan_signer(&self, _data: &[u8]) -> Result { unreachable!() } + fn read_chan_signer(&self, _data: &[u8]) -> Result { + unreachable!() + } - fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result { unreachable!() } + fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result { + unreachable!() + } - fn get_shutdown_scriptpubkey(&self) -> Result { unreachable!() } + fn get_shutdown_scriptpubkey(&self) -> Result { + unreachable!() + } } #[cfg(test)] @@ -238,8 +267,17 @@ mod tests { } impl Logger for TrackingLogger { fn log(&self, record: Record) { - *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1; - println!("{:<5} [{} : {}, {}] {}", record.level.to_string(), record.module_path, record.file, record.line, record.args); + let mut lines_lock = self.lines.lock().unwrap(); + let key = (record.module_path.to_string(), format!("{}", record.args)); + *lines_lock.entry(key).or_insert(0) += 1; + println!( + "{:<5} [{} : {}, {}] {}", + record.level.to_string(), + record.module_path, + record.file, + record.line, + record.args + ); } } diff --git a/fuzz/src/peer_crypt.rs b/fuzz/src/peer_crypt.rs index 41d8c093606..b01aa02400b 100644 --- a/fuzz/src/peer_crypt.rs +++ b/fuzz/src/peer_crypt.rs @@ -7,33 +7,30 @@ // You may not use this file except in accordance with one or both of these // licenses. -use lightning::ln::peer_channel_encryptor::{PeerChannelEncryptor, MessageBuf}; +use lightning::ln::peer_channel_encryptor::{MessageBuf, PeerChannelEncryptor}; use lightning::util::test_utils::TestNodeSigner; -use bitcoin::secp256k1::{Secp256k1, PublicKey, SecretKey}; +use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; use crate::utils::test_logger; #[inline] fn slice_to_be16(v: &[u8]) -> u16 { - ((v[0] as u16) << 8*1) | - ((v[1] as u16) << 8*0) + ((v[0] as u16) << 8 * 1) | ((v[1] as u16) << 8 * 0) } #[inline] pub fn do_test(data: &[u8]) { let mut read_pos = 0; macro_rules! get_slice { - ($len: expr) => { - { - let slice_len = $len as usize; - if data.len() < read_pos + slice_len { - return; - } - read_pos += slice_len; - &data[read_pos - slice_len..read_pos] + ($len: expr) => {{ + let slice_len = $len as usize; + if data.len() < read_pos + slice_len { + return; } - } + read_pos += slice_len; + &data[read_pos - slice_len..read_pos] + }}; } let secp_ctx = Secp256k1::signing_only(); @@ -63,7 +60,12 @@ pub fn do_test(data: &[u8]) { crypter } else { let mut crypter = PeerChannelEncryptor::new_inbound(&&node_signer); - match crypter.process_act_one_with_keys(get_slice!(50), &&node_signer, ephemeral_key, &secp_ctx) { + match crypter.process_act_one_with_keys( + get_slice!(50), + &&node_signer, + ephemeral_key, + &secp_ctx, + ) { Ok(_) => {}, Err(_) => return, } @@ -77,9 +79,11 @@ pub fn do_test(data: &[u8]) { let mut buf = [0; 65536 + 16]; loop { if get_slice!(1)[0] == 0 { - crypter.encrypt_buffer(MessageBuf::from_encoded(&get_slice!(slice_to_be16(get_slice!(2))))); + crypter.encrypt_buffer(MessageBuf::from_encoded(&get_slice!(slice_to_be16( + get_slice!(2) + )))); } else { - let len = match crypter.decrypt_length_header(get_slice!(16+2)) { + let len = match crypter.decrypt_length_header(get_slice!(16 + 2)) { Ok(len) => len, Err(_) => return, }; diff --git a/fuzz/src/process_network_graph.rs b/fuzz/src/process_network_graph.rs index b4c6a29e8a9..980c147e96a 100644 --- a/fuzz/src/process_network_graph.rs +++ b/fuzz/src/process_network_graph.rs @@ -6,7 +6,8 @@ use crate::utils::test_logger; /// Actual fuzz test, method signature and name are fixed fn do_test(data: &[u8], out: Out) { let logger = test_logger::TestLogger::new("".to_owned(), out); - let network_graph = lightning::routing::gossip::NetworkGraph::new(bitcoin::Network::Bitcoin, &logger); + let network_graph = + lightning::routing::gossip::NetworkGraph::new(bitcoin::Network::Bitcoin, &logger); let rapid_sync = RapidGossipSync::new(&network_graph, &logger); let _ = rapid_sync.update_network_graph(data); } diff --git a/fuzz/src/refund_deser.rs b/fuzz/src/refund_deser.rs index 7937ca1efc6..11907b6d696 100644 --- a/fuzz/src/refund_deser.rs +++ b/fuzz/src/refund_deser.rs @@ -7,17 +7,17 @@ // You may not use this file except in accordance with one or both of these // licenses. -use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, SecretKey, self}; use crate::utils::test_logger; +use bitcoin::secp256k1::{self, Keypair, PublicKey, Secp256k1, SecretKey}; use core::convert::TryFrom; -use lightning::blinded_path::BlindedPath; use lightning::blinded_path::message::ForwardNode; -use lightning::sign::EntropySource; -use lightning::ln::PaymentHash; +use lightning::blinded_path::BlindedPath; use lightning::ln::features::BlindedHopFeatures; +use lightning::ln::PaymentHash; use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice}; use lightning::offers::parse::Bolt12SemanticError; use lightning::offers::refund::Refund; +use lightning::sign::EntropySource; use lightning::util::ser::Writeable; #[inline] @@ -34,9 +34,9 @@ pub fn do_test(data: &[u8], _out: Out) { if let Ok(invoice) = build_response(&refund, pubkey, &secp_ctx) { invoice - .sign(|message: &UnsignedBolt12Invoice| + .sign(|message: &UnsignedBolt12Invoice| { Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) - ) + }) .unwrap() .write(&mut buffer) .unwrap(); @@ -47,7 +47,9 @@ pub fn do_test(data: &[u8], _out: Out) { struct Randomness; impl EntropySource for Randomness { - fn get_secure_random_bytes(&self) -> [u8; 32] { [42; 32] } + fn get_secure_random_bytes(&self) -> [u8; 32] { + [42; 32] + } } fn pubkey(byte: u8) -> PublicKey { @@ -60,7 +62,7 @@ fn privkey(byte: u8) -> SecretKey { } fn build_response( - refund: &Refund, signing_pubkey: PublicKey, secp_ctx: &Secp256k1 + refund: &Refund, signing_pubkey: PublicKey, secp_ctx: &Secp256k1, ) -> Result { let entropy_source = Randomness {}; let intermediate_nodes = [ @@ -74,8 +76,10 @@ fn build_response( ], ]; let paths = vec![ - BlindedPath::new_for_message(&intermediate_nodes[0], pubkey(42), &entropy_source, secp_ctx).unwrap(), - BlindedPath::new_for_message(&intermediate_nodes[1], pubkey(42), &entropy_source, secp_ctx).unwrap(), + BlindedPath::new_for_message(&intermediate_nodes[0], pubkey(42), &entropy_source, secp_ctx) + .unwrap(), + BlindedPath::new_for_message(&intermediate_nodes[1], pubkey(42), &entropy_source, secp_ctx) + .unwrap(), ]; let payinfo = vec![ diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index 2a36d890936..a4002682111 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -14,57 +14,59 @@ use bitcoin::blockdata::transaction::TxOut; use lightning::blinded_path::{BlindedHop, BlindedPath, IntroductionNode}; use lightning::chain::transaction::OutPoint; -use lightning::ln::ChannelId; -use lightning::ln::channel_state::{ChannelDetails, ChannelCounterparty, ChannelShutdownState}; +use lightning::ln::channel_state::{ChannelCounterparty, ChannelDetails, ChannelShutdownState}; use lightning::ln::channelmanager; use lightning::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures}; use lightning::ln::msgs; +use lightning::ln::ChannelId; use lightning::offers::invoice::BlindedPayInfo; use lightning::routing::gossip::{NetworkGraph, RoutingFees}; +use lightning::routing::router::{ + find_route, PaymentParameters, RouteHint, RouteHintHop, RouteParameters, +}; +use lightning::routing::scoring::{ + ProbabilisticScorer, ProbabilisticScoringDecayParameters, ProbabilisticScoringFeeParameters, +}; use lightning::routing::utxo::{UtxoFuture, UtxoLookup, UtxoLookupError, UtxoResult}; -use lightning::routing::router::{find_route, PaymentParameters, RouteHint, RouteHintHop, RouteParameters}; -use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters, ProbabilisticScoringDecayParameters}; use lightning::util::config::UserConfig; use lightning::util::hash_tables::*; use lightning::util::ser::Readable; use bitcoin::hashes::Hash; -use bitcoin::secp256k1::PublicKey; use bitcoin::network::Network; +use bitcoin::secp256k1::PublicKey; use crate::utils::test_logger; use std::convert::TryInto; -use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; #[inline] pub fn slice_to_be16(v: &[u8]) -> u16 { - ((v[0] as u16) << 8*1) | - ((v[1] as u16) << 8*0) + ((v[0] as u16) << 8 * 1) | ((v[1] as u16) << 8 * 0) } #[inline] pub fn slice_to_be32(v: &[u8]) -> u32 { - ((v[0] as u32) << 8*3) | - ((v[1] as u32) << 8*2) | - ((v[2] as u32) << 8*1) | - ((v[3] as u32) << 8*0) + ((v[0] as u32) << 8 * 3) + | ((v[1] as u32) << 8 * 2) + | ((v[2] as u32) << 8 * 1) + | ((v[3] as u32) << 8 * 0) } #[inline] pub fn slice_to_be64(v: &[u8]) -> u64 { - ((v[0] as u64) << 8*7) | - ((v[1] as u64) << 8*6) | - ((v[2] as u64) << 8*5) | - ((v[3] as u64) << 8*4) | - ((v[4] as u64) << 8*3) | - ((v[5] as u64) << 8*2) | - ((v[6] as u64) << 8*1) | - ((v[7] as u64) << 8*0) + ((v[0] as u64) << 8 * 7) + | ((v[1] as u64) << 8 * 6) + | ((v[2] as u64) << 8 * 5) + | ((v[3] as u64) << 8 * 4) + | ((v[4] as u64) << 8 * 3) + | ((v[5] as u64) << 8 * 2) + | ((v[6] as u64) << 8 * 1) + | ((v[7] as u64) << 8 * 0) } - struct InputData { data: Vec, read_pos: AtomicUsize, @@ -93,7 +95,9 @@ struct FuzzChainSource<'a, 'b, Out: test_logger::Output> { impl UtxoLookup for FuzzChainSource<'_, '_, Out> { fn get_utxo(&self, _chain_hash: &ChainHash, _short_channel_id: u64) -> UtxoResult { let input_slice = self.input.get_slice(2); - if input_slice.is_none() { return UtxoResult::Sync(Err(UtxoLookupError::UnknownTx)); } + if input_slice.is_none() { + return UtxoResult::Sync(Err(UtxoLookupError::UnknownTx)); + } let input_slice = input_slice.unwrap(); let txo_res = TxOut { value: Amount::from_sat(if input_slice[0] % 2 == 0 { 1_000_000 } else { 1_000 }), @@ -122,17 +126,14 @@ impl UtxoLookup for FuzzChainSource<'_, '_, Out> { #[inline] pub fn do_test(data: &[u8], out: Out) { - let input = Arc::new(InputData { - data: data.to_vec(), - read_pos: AtomicUsize::new(0), - }); + let input = Arc::new(InputData { data: data.to_vec(), read_pos: AtomicUsize::new(0) }); macro_rules! get_slice_nonadvancing { ($len: expr) => { match input.get_slice_nonadvancing($len as usize) { Some(slice) => slice, None => return, } - } + }; } macro_rules! get_slice { ($len: expr) => { @@ -140,7 +141,7 @@ pub fn do_test(data: &[u8], out: Out) { Some(slice) => slice, None => return, } - } + }; } macro_rules! decode_msg { @@ -160,18 +161,16 @@ pub fn do_test(data: &[u8], out: Out) { msgs::DecodeError::Io(e) => panic!("{:?}", e), msgs::DecodeError::UnsupportedCompression => return, msgs::DecodeError::DangerousValue => return, - } + }, } - }} + }}; } macro_rules! decode_msg_with_len16 { - ($MsgType: path, $excess: expr) => { - { - let extra_len = slice_to_be16(get_slice_nonadvancing!(2)); - decode_msg!($MsgType, 2 + (extra_len as usize) + $excess) - } - } + ($MsgType: path, $excess: expr) => {{ + let extra_len = slice_to_be16(get_slice_nonadvancing!(2)); + decode_msg!($MsgType, 2 + (extra_len as usize) + $excess) + }}; } macro_rules! get_pubkey_from_node_id { @@ -180,7 +179,7 @@ pub fn do_test(data: &[u8], out: Out) { Ok(pk) => pk, Err(_) => return, } - } + }; } macro_rules! get_pubkey { @@ -189,17 +188,14 @@ pub fn do_test(data: &[u8], out: Out) { Ok(key) => key, Err(_) => return, } - } + }; } let logger = test_logger::TestLogger::new("".to_owned(), out); let our_pubkey = get_pubkey!(); let net_graph = NetworkGraph::new(Network::Bitcoin, &logger); - let chain_source = FuzzChainSource { - input: Arc::clone(&input), - net_graph: &net_graph, - }; + let chain_source = FuzzChainSource { input: Arc::clone(&input), net_graph: &net_graph }; let mut node_pks = new_hash_map(); let mut scid = 42; @@ -211,32 +207,41 @@ pub fn do_test(data: &[u8], out: Out) { count => { for _ in 0..count { scid += 1; - let (rnid, _) = - node_pks.iter().skip(u16::from_be_bytes(get_slice!(2).try_into().unwrap()) as usize % node_pks.len()).next().unwrap(); + let skip = u16::from_be_bytes(get_slice!(2).try_into().unwrap()) as usize + % node_pks.len(); + let (rnid, _) = node_pks.iter().skip(skip).next().unwrap(); let capacity = u64::from_be_bytes(get_slice!(8).try_into().unwrap()); $first_hops_vec.push(ChannelDetails { channel_id: ChannelId::new_zero(), counterparty: ChannelCounterparty { node_id: *rnid, - features: channelmanager::provided_init_features(&UserConfig::default()), + features: channelmanager::provided_init_features( + &UserConfig::default(), + ), unspendable_punishment_reserve: 0, forwarding_info: None, outbound_htlc_minimum_msat: None, outbound_htlc_maximum_msat: None, }, - funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), + funding_txo: Some(OutPoint { + txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), + index: 0, + }), channel_type: None, short_channel_id: Some(scid), inbound_scid_alias: None, outbound_scid_alias: None, channel_value_satoshis: capacity, - user_channel_id: 0, inbound_capacity_msat: 0, + user_channel_id: 0, + inbound_capacity_msat: 0, unspendable_punishment_reserve: None, confirmations_required: None, confirmations: None, force_close_spend_delay: None, - is_outbound: true, is_channel_ready: true, - is_usable: true, is_public: true, + is_outbound: true, + is_channel_ready: true, + is_usable: true, + is_public: true, balance_msat: 0, outbound_capacity_msat: capacity.saturating_mul(1000), next_outbound_htlc_limit_msat: capacity.saturating_mul(1000), @@ -253,7 +258,7 @@ pub fn do_test(data: &[u8], out: Out) { Some(&$first_hops_vec[..]) }, } - } + }; } macro_rules! last_hops { @@ -261,8 +266,8 @@ pub fn do_test(data: &[u8], out: Out) { let count = get_slice!(1)[0]; for _ in 0..count { scid += 1; - let (rnid, _) = - node_pks.iter().skip(slice_to_be16(get_slice!(2)) as usize % node_pks.len()).next().unwrap(); + let skip = slice_to_be16(get_slice!(2)) as usize % node_pks.len(); + let (rnid, _) = node_pks.iter().skip(skip).next().unwrap(); $last_hops.push(RouteHint(vec![RouteHintHop { src_node_id: *rnid, short_channel_id: scid, @@ -275,30 +280,47 @@ pub fn do_test(data: &[u8], out: Out) { htlc_maximum_msat: None, }])); } - } + }; } macro_rules! find_routes { ($first_hops: expr, $node_pks: expr, $route_params: expr) => { - let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &net_graph, &logger); + let scorer = ProbabilisticScorer::new( + ProbabilisticScoringDecayParameters::default(), + &net_graph, + &logger, + ); let random_seed_bytes: [u8; 32] = [get_slice!(1)[0]; 32]; for (target, ()) in $node_pks { let final_value_msat = slice_to_be64(get_slice!(8)); let final_cltv_expiry_delta = slice_to_be32(get_slice!(4)); let route_params = $route_params(final_value_msat, final_cltv_expiry_delta, target); - let _ = find_route(&our_pubkey, &route_params, &net_graph, - $first_hops.map(|c| c.iter().collect::>()).as_ref().map(|a| a.as_slice()), - &logger, &scorer, &ProbabilisticScoringFeeParameters::default(), &random_seed_bytes); + let _ = find_route( + &our_pubkey, + &route_params, + &net_graph, + $first_hops + .map(|c| c.iter().collect::>()) + .as_ref() + .map(|a| a.as_slice()), + &logger, + &scorer, + &ProbabilisticScoringFeeParameters::default(), + &random_seed_bytes, + ); } - } + }; } loop { match get_slice!(1)[0] { 0 => { let start_len = slice_to_be16(&get_slice_nonadvancing!(2)[0..2]) as usize; - let addr_len = slice_to_be16(&get_slice_nonadvancing!(start_len+2 + 74)[start_len+2 + 72..start_len+2 + 74]); - if addr_len > (37+1)*4 { + let addr_len = slice_to_be16( + &get_slice_nonadvancing!(start_len + 2 + 74) + [start_len + 2 + 72..start_len + 2 + 74], + ); + if addr_len > (37 + 1) * 4 { return; } let msg = decode_msg_with_len16!(msgs::UnsignedNodeAnnouncement, 288); @@ -306,20 +328,26 @@ pub fn do_test(data: &[u8], out: Out) { let _ = net_graph.update_node_from_unsigned_announcement(&msg); }, 1 => { - let msg = decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32+8+33*4); + let msg = + decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32 + 8 + 33 * 4); node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1), ()); node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2), ()); - let _ = net_graph.update_channel_from_unsigned_announcement:: - <&FuzzChainSource<'_, '_, Out>>(&msg, &None); + let _ = net_graph + .update_channel_from_unsigned_announcement::<&FuzzChainSource<'_, '_, Out>>( + &msg, &None, + ); }, 2 => { - let msg = decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32+8+33*4); + let msg = + decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32 + 8 + 33 * 4); node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1), ()); node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2), ()); - let _ = net_graph.update_channel_from_unsigned_announcement(&msg, &Some(&chain_source)); + let _ = + net_graph.update_channel_from_unsigned_announcement(&msg, &Some(&chain_source)); }, 3 => { - let _ = net_graph.update_channel_unsigned(&decode_msg!(msgs::UnsignedChannelUpdate, 72)); + let _ = net_graph + .update_channel_unsigned(&decode_msg!(msgs::UnsignedChannelUpdate, 72)); }, 4 => { let short_channel_id = slice_to_be64(get_slice!(8)); @@ -333,12 +361,18 @@ pub fn do_test(data: &[u8], out: Out) { let first_hops = first_hops!(first_hops_vec); let mut last_hops = Vec::new(); last_hops!(last_hops); - find_routes!(first_hops, node_pks.iter(), |final_amt, final_delta, target: &PublicKey| { - RouteParameters::from_payment_params_and_value( - PaymentParameters::from_node_id(*target, final_delta) - .with_route_hints(last_hops.clone()).unwrap(), - final_amt) - }); + find_routes!( + first_hops, + node_pks.iter(), + |final_amt, final_delta, target: &PublicKey| { + RouteParameters::from_payment_params_and_value( + PaymentParameters::from_node_id(*target, final_delta) + .with_route_hints(last_hops.clone()) + .unwrap(), + final_amt, + ) + } + ); }, x => { let mut first_hops_vec = Vec::new(); @@ -346,38 +380,47 @@ pub fn do_test(data: &[u8], out: Out) { let mut last_hops_unblinded = Vec::new(); last_hops!(last_hops_unblinded); let dummy_pk = PublicKey::from_slice(&[2; 33]).unwrap(); - let last_hops: Vec<(BlindedPayInfo, BlindedPath)> = last_hops_unblinded.into_iter().map(|hint| { - let hop = &hint.0[0]; - let payinfo = BlindedPayInfo { - fee_base_msat: hop.fees.base_msat, - fee_proportional_millionths: hop.fees.proportional_millionths, - htlc_minimum_msat: hop.htlc_minimum_msat.unwrap(), - htlc_maximum_msat: hop.htlc_minimum_msat.unwrap().saturating_mul(100), - cltv_expiry_delta: hop.cltv_expiry_delta, - features: BlindedHopFeatures::empty(), - }; - let num_blinded_hops = x % 250; - let mut blinded_hops = Vec::new(); - for _ in 0..num_blinded_hops { - blinded_hops.push(BlindedHop { - blinded_node_id: dummy_pk, - encrypted_payload: Vec::new() - }); - } - (payinfo, BlindedPath { - introduction_node: IntroductionNode::NodeId(hop.src_node_id), - blinding_point: dummy_pk, - blinded_hops, + let last_hops: Vec<(BlindedPayInfo, BlindedPath)> = last_hops_unblinded + .into_iter() + .map(|hint| { + let hop = &hint.0[0]; + let payinfo = BlindedPayInfo { + fee_base_msat: hop.fees.base_msat, + fee_proportional_millionths: hop.fees.proportional_millionths, + htlc_minimum_msat: hop.htlc_minimum_msat.unwrap(), + htlc_maximum_msat: hop.htlc_minimum_msat.unwrap().saturating_mul(100), + cltv_expiry_delta: hop.cltv_expiry_delta, + features: BlindedHopFeatures::empty(), + }; + let num_blinded_hops = x % 250; + let mut blinded_hops = Vec::new(); + for _ in 0..num_blinded_hops { + blinded_hops.push(BlindedHop { + blinded_node_id: dummy_pk, + encrypted_payload: Vec::new(), + }); + } + ( + payinfo, + BlindedPath { + introduction_node: IntroductionNode::NodeId(hop.src_node_id), + blinding_point: dummy_pk, + blinded_hops, + }, + ) }) - }).collect(); + .collect(); let mut features = Bolt12InvoiceFeatures::empty(); features.set_basic_mpp_optional(); find_routes!(first_hops, [(dummy_pk, ())].iter(), |final_amt, _, _| { - RouteParameters::from_payment_params_and_value(PaymentParameters::blinded(last_hops.clone()) - .with_bolt12_features(features.clone()).unwrap(), - final_amt) + RouteParameters::from_payment_params_and_value( + PaymentParameters::blinded(last_hops.clone()) + .with_bolt12_features(features.clone()) + .unwrap(), + final_amt, + ) }); - } + }, } } } diff --git a/fuzz/src/utils/test_logger.rs b/fuzz/src/utils/test_logger.rs index 5e5817e23f1..6d9de02e387 100644 --- a/fuzz/src/utils/test_logger.rs +++ b/fuzz/src/utils/test_logger.rs @@ -8,10 +8,10 @@ // licenses. use lightning::util::logger::{Logger, Record}; -use std::sync::{Arc, Mutex}; use std::io::Write; +use std::sync::{Arc, Mutex}; -pub trait Output : Clone + 'static { +pub trait Output: Clone + 'static { fn locked_write(&self, data: &[u8]); } @@ -36,7 +36,7 @@ impl StringBuffer { } } -pub struct TestLogger { +pub struct TestLogger { id: String, out: Out, } @@ -52,13 +52,22 @@ impl<'a, Out: Output> Write for LockedWriteAdapter<'a, Out> { self.0.locked_write(data); Ok(data.len()) } - fn flush(&mut self) -> Result<(), std::io::Error> { Ok(()) } + fn flush(&mut self) -> Result<(), std::io::Error> { + Ok(()) + } } impl Logger for TestLogger { fn log(&self, record: Record) { - write!(LockedWriteAdapter(&self.out), - "{:<5} {} [{} : {}] {}\n", record.level.to_string(), self.id, record.module_path, record.line, record.args) - .unwrap(); + write!( + LockedWriteAdapter(&self.out), + "{:<5} {} [{} : {}] {}\n", + record.level.to_string(), + self.id, + record.module_path, + record.line, + record.args + ) + .unwrap(); } } diff --git a/fuzz/src/utils/test_persister.rs b/fuzz/src/utils/test_persister.rs index a99c397d0b2..7de3cc6bebb 100644 --- a/fuzz/src/utils/test_persister.rs +++ b/fuzz/src/utils/test_persister.rs @@ -1,6 +1,6 @@ use lightning::chain; -use lightning::chain::{chainmonitor, channelmonitor}; use lightning::chain::transaction::OutPoint; +use lightning::chain::{chainmonitor, channelmonitor}; use lightning::util::test_channel_signer::TestChannelSigner; use std::sync::Mutex; @@ -9,14 +9,18 @@ pub struct TestPersister { pub update_ret: Mutex, } impl chainmonitor::Persist for TestPersister { - fn persist_new_channel(&self, _funding_txo: OutPoint, _data: &channelmonitor::ChannelMonitor) -> chain::ChannelMonitorUpdateStatus { + fn persist_new_channel( + &self, _funding_txo: OutPoint, _data: &channelmonitor::ChannelMonitor, + ) -> chain::ChannelMonitorUpdateStatus { self.update_ret.lock().unwrap().clone() } - fn update_persisted_channel(&self, _funding_txo: OutPoint, _update: Option<&channelmonitor::ChannelMonitorUpdate>, _data: &channelmonitor::ChannelMonitor) -> chain::ChannelMonitorUpdateStatus { + fn update_persisted_channel( + &self, _funding_txo: OutPoint, _update: Option<&channelmonitor::ChannelMonitorUpdate>, + _data: &channelmonitor::ChannelMonitor, + ) -> chain::ChannelMonitorUpdateStatus { self.update_ret.lock().unwrap().clone() } - fn archive_persisted_channel(&self, _: OutPoint) { - } + fn archive_persisted_channel(&self, _: OutPoint) {} } diff --git a/lightning-custom-message/src/lib.rs b/lightning-custom-message/src/lib.rs index e2000bc5804..a0948f23b5f 100644 --- a/lightning-custom-message/src/lib.rs +++ b/lightning-custom-message/src/lib.rs @@ -20,7 +20,7 @@ //! //! # use bitcoin::secp256k1::PublicKey; //! # use lightning::io; -//! # use lightning::ln::msgs::{DecodeError, LightningError}; +//! # use lightning::ln::msgs::{DecodeError, Init, LightningError}; //! # use lightning::ln::features::{InitFeatures, NodeFeatures}; //! use lightning::ln::peer_handler::CustomMessageHandler; //! use lightning::ln::wire::{CustomMessageReader, self}; @@ -68,6 +68,12 @@ //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> { //! # unimplemented!() //! # } +//! # fn peer_disconnected(&self, _their_node_id: &PublicKey) { +//! # unimplemented!() +//! # } +//! # fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> { +//! # unimplemented!() +//! # } //! # fn provided_node_features(&self) -> NodeFeatures { //! # unimplemented!() //! # } @@ -114,6 +120,12 @@ //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> { //! # unimplemented!() //! # } +//! # fn peer_disconnected(&self, _their_node_id: &PublicKey) { +//! # unimplemented!() +//! # } +//! # fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> { +//! # unimplemented!() +//! # } //! # fn provided_node_features(&self) -> NodeFeatures { //! # unimplemented!() //! # } @@ -160,6 +172,12 @@ //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> { //! # unimplemented!() //! # } +//! # fn peer_disconnected(&self, _their_node_id: &PublicKey) { +//! # unimplemented!() +//! # } +//! # fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> { +//! # unimplemented!() +//! # } //! # fn provided_node_features(&self) -> NodeFeatures { //! # unimplemented!() //! # } @@ -287,6 +305,22 @@ macro_rules! composite_custom_message_handler { .collect() } + fn peer_disconnected(&self, their_node_id: &$crate::bitcoin::secp256k1::PublicKey) { + $( + self.$field.peer_disconnected(their_node_id); + )* + } + + fn peer_connected(&self, their_node_id: &$crate::bitcoin::secp256k1::PublicKey, msg: &$crate::lightning::ln::msgs::Init, inbound: bool) -> Result<(), ()> { + let mut result = Ok(()); + $( + if let Err(e) = self.$field.peer_connected(their_node_id, msg, inbound) { + result = Err(e); + } + )* + result + } + fn provided_node_features(&self) -> $crate::lightning::ln::features::NodeFeatures { $crate::lightning::ln::features::NodeFeatures::empty() $( diff --git a/lightning-transaction-sync/src/common.rs b/lightning-transaction-sync/src/common.rs index c635f7385c6..420d7d8a957 100644 --- a/lightning-transaction-sync/src/common.rs +++ b/lightning-transaction-sync/src/common.rs @@ -1,10 +1,10 @@ -use lightning::chain::{Confirm, WatchedOutput}; -use lightning::chain::channelmonitor::ANTI_REORG_DELAY; -use bitcoin::{Txid, BlockHash, Transaction, OutPoint}; use bitcoin::block::Header; +use bitcoin::{BlockHash, OutPoint, Transaction, Txid}; +use lightning::chain::channelmonitor::ANTI_REORG_DELAY; +use lightning::chain::{Confirm, WatchedOutput}; -use std::collections::{HashSet, HashMap}; - +use std::collections::{HashMap, HashSet}; +use std::ops::Deref; // Represents the current state. pub(crate) struct SyncState { @@ -33,10 +33,11 @@ impl SyncState { pending_sync: false, } } - pub fn sync_unconfirmed_transactions( - &mut self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, - unconfirmed_txs: Vec, - ) { + pub fn sync_unconfirmed_transactions( + &mut self, confirmables: &Vec, unconfirmed_txs: Vec, + ) where + C::Target: Confirm, + { for txid in unconfirmed_txs { for c in confirmables { c.transaction_unconfirmed(&txid); @@ -46,21 +47,24 @@ impl SyncState { // If a previously-confirmed output spend is unconfirmed, re-add the watched output to // the tracking map. - self.outputs_spends_pending_threshold_conf.retain(|(conf_txid, _, prev_outpoint, output)| { - if txid == *conf_txid { - self.watched_outputs.insert(*prev_outpoint, output.clone()); - false - } else { - true - } - }) + self.outputs_spends_pending_threshold_conf.retain( + |(conf_txid, _, prev_outpoint, output)| { + if txid == *conf_txid { + self.watched_outputs.insert(*prev_outpoint, output.clone()); + false + } else { + true + } + }, + ) } } - pub fn sync_confirmed_transactions( - &mut self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, - confirmed_txs: Vec - ) { + pub fn sync_confirmed_transactions( + &mut self, confirmables: &Vec, confirmed_txs: Vec, + ) where + C::Target: Confirm, + { for ctx in confirmed_txs { for c in confirmables { c.transactions_confirmed( @@ -74,20 +78,19 @@ impl SyncState { for input in &ctx.tx.input { if let Some(output) = self.watched_outputs.remove(&input.previous_output) { - self.outputs_spends_pending_threshold_conf.push((ctx.tx.txid(), ctx.block_height, input.previous_output, output)); + let spent = (ctx.tx.txid(), ctx.block_height, input.previous_output, output); + self.outputs_spends_pending_threshold_conf.push(spent); } } } } pub fn prune_output_spends(&mut self, cur_height: u32) { - self.outputs_spends_pending_threshold_conf.retain(|(_, conf_height, _, _)| { - cur_height < conf_height + ANTI_REORG_DELAY - 1 - }); + self.outputs_spends_pending_threshold_conf + .retain(|(_, conf_height, _, _)| cur_height < conf_height + ANTI_REORG_DELAY - 1); } } - // A queue that is to be filled by `Filter` and drained during the next syncing round. pub(crate) struct FilterQueue { // Transactions that were registered via the `Filter` interface and have to be processed. @@ -98,10 +101,7 @@ pub(crate) struct FilterQueue { impl FilterQueue { pub fn new() -> Self { - Self { - transactions: HashSet::new(), - outputs: HashMap::new(), - } + Self { transactions: HashSet::new(), outputs: HashMap::new() } } // Processes the transaction and output queues and adds them to the given [`SyncState`]. diff --git a/lightning-transaction-sync/src/electrum.rs b/lightning-transaction-sync/src/electrum.rs index d2cb7256fd0..8ba250f8460 100644 --- a/lightning-transaction-sync/src/electrum.rs +++ b/lightning-transaction-sync/src/electrum.rs @@ -1,24 +1,24 @@ -use crate::common::{ConfirmedTx, SyncState, FilterQueue}; -use crate::error::{TxSyncError, InternalError}; +use crate::common::{ConfirmedTx, FilterQueue, SyncState}; +use crate::error::{InternalError, TxSyncError}; use electrum_client::Client as ElectrumClient; use electrum_client::ElectrumApi; use electrum_client::GetMerkleRes; -use lightning::util::logger::Logger; -use lightning::{log_error, log_debug, log_trace}; use lightning::chain::WatchedOutput; use lightning::chain::{Confirm, Filter}; +use lightning::util::logger::Logger; +use lightning::{log_debug, log_error, log_trace}; -use bitcoin::{BlockHash, Script, Transaction, Txid}; use bitcoin::block::Header; use bitcoin::hash_types::TxMerkleNode; -use bitcoin::hashes::Hash; use bitcoin::hashes::sha256d::Hash as Sha256d; +use bitcoin::hashes::Hash; +use bitcoin::{BlockHash, Script, Transaction, Txid}; +use std::collections::HashSet; use std::ops::Deref; use std::sync::Mutex; -use std::collections::HashSet; use std::time::Instant; /// Synchronizes LDK with a given Electrum server. @@ -64,12 +64,7 @@ where let sync_state = Mutex::new(SyncState::new()); let queue = Mutex::new(FilterQueue::new()); - Ok(Self { - sync_state, - queue, - client, - logger, - }) + Ok(Self { sync_state, queue, client, logger }) } /// Synchronizes the given `confirmables` via their [`Confirm`] interface implementations. This @@ -83,7 +78,10 @@ where /// [`ChainMonitor`]: lightning::chain::chainmonitor::ChainMonitor /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager /// [`Filter`]: lightning::chain::Filter - pub fn sync(&self, confirmables: Vec<&(dyn Confirm + Sync + Send)>) -> Result<(), TxSyncError> { + pub fn sync(&self, confirmables: Vec) -> Result<(), TxSyncError> + where + C::Target: Confirm, + { // This lock makes sure we're syncing once at a time. let mut sync_state = self.sync_state.lock().unwrap(); @@ -122,15 +120,15 @@ where num_unconfirmed += unconfirmed_txs.len(); sync_state.sync_unconfirmed_transactions( &confirmables, - unconfirmed_txs + unconfirmed_txs, ); - } + }, Ok(true) => { log_debug!(self.logger, "Encountered inconsistency during transaction sync, restarting."); sync_state.pending_sync = true; continue; - } + }, Err(err) => { // (Semi-)permanent failure, retry later. log_error!(self.logger, @@ -140,7 +138,7 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } }, Err(err) => { @@ -152,7 +150,7 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } // Update the best block. @@ -171,17 +169,15 @@ where match self.check_update_tip(&mut tip_header, &mut tip_height) { Ok(false) => { num_confirmed += confirmed_txs.len(); - sync_state.sync_confirmed_transactions( - &confirmables, - confirmed_txs - ); - } + sync_state + .sync_confirmed_transactions(&confirmables, confirmed_txs); + }, Ok(true) => { log_debug!(self.logger, "Encountered inconsistency during transaction sync, restarting."); sync_state.pending_sync = true; continue; - } + }, Err(err) => { // (Semi-)permanent failure, retry later. log_error!(self.logger, @@ -191,16 +187,18 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } - } + }, Err(InternalError::Inconsistency) => { // Immediately restart syncing when we encounter any inconsistencies. - log_debug!(self.logger, - "Encountered inconsistency during transaction sync, restarting."); + log_debug!( + self.logger, + "Encountered inconsistency during transaction sync, restarting." + ); sync_state.pending_sync = true; continue; - } + }, Err(err) => { // (Semi-)permanent failure, retry later. log_error!(self.logger, @@ -210,27 +208,35 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } sync_state.last_sync_hash = Some(tip_header.block_hash()); sync_state.pending_sync = false; } } #[cfg(feature = "time")] - log_debug!(self.logger, + log_debug!( + self.logger, "Finished transaction sync at tip {} in {}ms: {} confirmed, {} unconfirmed.", - tip_header.block_hash(), start_time.elapsed().as_millis(), num_confirmed, - num_unconfirmed); + tip_header.block_hash(), + start_time.elapsed().as_millis(), + num_confirmed, + num_unconfirmed + ); #[cfg(not(feature = "time"))] - log_debug!(self.logger, + log_debug!( + self.logger, "Finished transaction sync at tip {}: {} confirmed, {} unconfirmed.", - tip_header.block_hash(), num_confirmed, num_unconfirmed); + tip_header.block_hash(), + num_confirmed, + num_unconfirmed + ); Ok(()) } - fn check_update_tip(&self, cur_tip_header: &mut Header, cur_tip_height: &mut u32) - -> Result - { + fn check_update_tip( + &self, cur_tip_header: &mut Header, cur_tip_height: &mut u32, + ) -> Result { let check_notification = self.client.block_headers_subscribe()?; let check_tip_hash = check_notification.header.block_hash(); @@ -256,12 +262,12 @@ where fn get_confirmed_transactions( &self, sync_state: &SyncState, ) -> Result, InternalError> { - // First, check the confirmation status of registered transactions as well as the // status of dependent transactions of registered outputs. let mut confirmed_txs: Vec = Vec::new(); let mut watched_script_pubkeys = Vec::with_capacity( - sync_state.watched_transactions.len() + sync_state.watched_outputs.len()); + sync_state.watched_transactions.len() + sync_state.watched_outputs.len(), + ); let mut watched_txs = Vec::with_capacity(sync_state.watched_transactions.len()); for txid in &sync_state.watched_transactions { @@ -278,14 +284,14 @@ where log_error!(self.logger, "Failed due to retrieving invalid tx data."); return Err(InternalError::Failed); } - } + }, Err(electrum_client::Error::Protocol(_)) => { // We couldn't find the tx, do nothing. - } + }, Err(e) => { log_error!(self.logger, "Failed to look up transaction {}: {}.", txid, e); return Err(InternalError::Failed); - } + }, } } @@ -310,9 +316,9 @@ where if confirmed_txs.iter().any(|ctx| ctx.txid == **txid) { continue; } - let mut filtered_history = script_history.iter().filter(|h| h.tx_hash == **txid); - if let Some(history) = filtered_history.next() - { + let mut filtered_history = + script_history.iter().filter(|h| h.tx_hash == **txid); + if let Some(history) = filtered_history.next() { let prob_conf_height = history.height as u32; let confirmed_tx = self.get_confirmed_tx(tx, prob_conf_height)?; confirmed_txs.push(confirmed_tx); @@ -320,8 +326,8 @@ where debug_assert!(filtered_history.next().is_none()); } - for (watched_output, script_history) in sync_state.watched_outputs.values() - .zip(output_results) + for (watched_output, script_history) in + sync_state.watched_outputs.values().zip(output_results) { for possible_output_spend in script_history { if possible_output_spend.height <= 0 { @@ -337,8 +343,8 @@ where Ok(tx) => { let mut is_spend = false; for txin in &tx.input { - let watched_outpoint = watched_output.outpoint - .into_bitcoin_outpoint(); + let watched_outpoint = + watched_output.outpoint.into_bitcoin_outpoint(); if txin.previous_output == watched_outpoint { is_spend = true; break; @@ -352,21 +358,24 @@ where let prob_conf_height = possible_output_spend.height as u32; let confirmed_tx = self.get_confirmed_tx(&tx, prob_conf_height)?; confirmed_txs.push(confirmed_tx); - } + }, Err(e) => { - log_trace!(self.logger, + log_trace!( + self.logger, "Inconsistency: Tx {} was unconfirmed during syncing: {}", - txid, e); + txid, + e + ); return Err(InternalError::Inconsistency); - } + }, } } } - } + }, Err(e) => { log_error!(self.logger, "Failed to look up script histories: {}.", e); return Err(InternalError::Failed); - } + }, } // Sort all confirmed transactions first by block height, then by in-block @@ -378,9 +387,12 @@ where Ok(confirmed_txs) } - fn get_unconfirmed_transactions( - &self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, - ) -> Result, InternalError> { + fn get_unconfirmed_transactions( + &self, confirmables: &Vec, + ) -> Result, InternalError> + where + C::Target: Confirm, + { // Query the interface for relevant txids and check whether the relevant blocks are still // in the best chain, mark them unconfirmed otherwise let relevant_txids = confirmables @@ -408,9 +420,9 @@ where Ok(unconfirmed_txs) } - fn get_confirmed_tx(&self, tx: &Transaction, prob_conf_height: u32) - -> Result - { + fn get_confirmed_tx( + &self, tx: &Transaction, prob_conf_height: u32, + ) -> Result { let txid = tx.txid(); match self.client.transaction_get_merkle(&txid, prob_conf_height as usize) { Ok(merkle_res) => { @@ -418,36 +430,47 @@ where match self.client.block_header(prob_conf_height as usize) { Ok(block_header) => { let pos = merkle_res.pos; - if !self.validate_merkle_proof(&txid, - &block_header.merkle_root, merkle_res)? - { - log_trace!(self.logger, + if !self.validate_merkle_proof( + &txid, + &block_header.merkle_root, + merkle_res, + )? { + log_trace!( + self.logger, "Inconsistency: Block {} was unconfirmed during syncing.", - block_header.block_hash()); + block_header.block_hash() + ); return Err(InternalError::Inconsistency); } let confirmed_tx = ConfirmedTx { tx: tx.clone(), txid, - block_header, block_height: prob_conf_height, + block_header, + block_height: prob_conf_height, pos, }; Ok(confirmed_tx) - } + }, Err(e) => { - log_error!(self.logger, + log_error!( + self.logger, "Failed to retrieve block header for height {}: {}.", - prob_conf_height, e); + prob_conf_height, + e + ); Err(InternalError::Failed) - } + }, } - } + }, Err(e) => { - log_trace!(self.logger, + log_trace!( + self.logger, "Inconsistency: Tx {} was unconfirmed during syncing: {}", - txid, e); + txid, + e + ); Err(InternalError::Inconsistency) - } + }, } } @@ -458,20 +481,16 @@ where &self.client } - fn validate_merkle_proof(&self, txid: &Txid, merkle_root: &TxMerkleNode, - merkle_res: GetMerkleRes) -> Result - { + fn validate_merkle_proof( + &self, txid: &Txid, merkle_root: &TxMerkleNode, merkle_res: GetMerkleRes, + ) -> Result { let mut index = merkle_res.pos; let mut cur = txid.to_raw_hash(); for mut bytes in merkle_res.merkle { bytes.reverse(); // unwrap() safety: `bytes` has len 32 so `from_slice` can never fail. let next_hash = Sha256d::from_slice(&bytes).unwrap(); - let (left, right) = if index % 2 == 0 { - (cur, next_hash) - } else { - (next_hash, cur) - }; + let (left, right) = if index % 2 == 0 { (cur, next_hash) } else { (next_hash, cur) }; let data = [&left[..], &right[..]].concat(); cur = Sha256d::hash(&data); diff --git a/lightning-transaction-sync/src/error.rs b/lightning-transaction-sync/src/error.rs index d1f4a319e86..be59cb026b4 100644 --- a/lightning-transaction-sync/src/error.rs +++ b/lightning-transaction-sync/src/error.rs @@ -31,7 +31,7 @@ impl fmt::Display for InternalError { Self::Failed => write!(f, "Failed to conduct transaction sync."), Self::Inconsistency => { write!(f, "Encountered an inconsistency during transaction sync.") - } + }, } } } diff --git a/lightning-transaction-sync/src/esplora.rs b/lightning-transaction-sync/src/esplora.rs index 2e35a150c55..f176d535124 100644 --- a/lightning-transaction-sync/src/esplora.rs +++ b/lightning-transaction-sync/src/esplora.rs @@ -1,21 +1,21 @@ -use crate::error::{TxSyncError, InternalError}; -use crate::common::{SyncState, FilterQueue, ConfirmedTx}; +use crate::common::{ConfirmedTx, FilterQueue, SyncState}; +use crate::error::{InternalError, TxSyncError}; -use lightning::util::logger::Logger; -use lightning::{log_error, log_debug, log_trace}; use lightning::chain::WatchedOutput; use lightning::chain::{Confirm, Filter}; +use lightning::util::logger::Logger; +use lightning::{log_debug, log_error, log_trace}; use bitcoin::{BlockHash, Script, Txid}; -use esplora_client::Builder; -#[cfg(feature = "async-interface")] -use esplora_client::r#async::AsyncClient; #[cfg(not(feature = "async-interface"))] use esplora_client::blocking::BlockingClient; +#[cfg(feature = "async-interface")] +use esplora_client::r#async::AsyncClient; +use esplora_client::Builder; -use std::collections::HashSet; use core::ops::Deref; +use std::collections::HashSet; /// Synchronizes LDK with a given [`Esplora`] server. /// @@ -64,12 +64,7 @@ where pub fn from_client(client: EsploraClientType, logger: L) -> Self { let sync_state = MutexType::new(SyncState::new()); let queue = std::sync::Mutex::new(FilterQueue::new()); - Self { - sync_state, - queue, - client, - logger, - } + Self { sync_state, queue, client, logger } } /// Synchronizes the given `confirmables` via their [`Confirm`] interface implementations. This @@ -84,7 +79,10 @@ where /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager /// [`Filter`]: lightning::chain::Filter #[maybe_async] - pub fn sync(&self, confirmables: Vec<&(dyn Confirm + Sync + Send)>) -> Result<(), TxSyncError> { + pub fn sync(&self, confirmables: Vec) -> Result<(), TxSyncError> + where + C::Target: Confirm, + { // This lock makes sure we're syncing once at a time. #[cfg(not(feature = "async-interface"))] let mut sync_state = self.sync_state.lock().unwrap(); @@ -128,9 +126,9 @@ where num_unconfirmed += unconfirmed_txs.len(); sync_state.sync_unconfirmed_transactions( &confirmables, - unconfirmed_txs + unconfirmed_txs, ); - } + }, Err(err) => { // (Semi-)permanent failure, retry later. log_error!(self.logger, @@ -140,7 +138,7 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } }, Err(err) => { @@ -152,17 +150,24 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } - match maybe_await!(self.sync_best_block_updated(&confirmables, &mut sync_state, &tip_hash)) { - Ok(()) => {} + match maybe_await!(self.sync_best_block_updated( + &confirmables, + &mut sync_state, + &tip_hash + )) { + Ok(()) => {}, Err(InternalError::Inconsistency) => { // Immediately restart syncing when we encounter any inconsistencies. - log_debug!(self.logger, "Encountered inconsistency during transaction sync, restarting."); + log_debug!( + self.logger, + "Encountered inconsistency during transaction sync, restarting." + ); sync_state.pending_sync = true; continue; - } + }, Err(err) => { // (Semi-)permanent failure, retry later. log_error!(self.logger, @@ -172,7 +177,7 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } } @@ -191,11 +196,9 @@ where continue; } num_confirmed += confirmed_txs.len(); - sync_state.sync_confirmed_transactions( - &confirmables, - confirmed_txs - ); - } + sync_state + .sync_confirmed_transactions(&confirmables, confirmed_txs); + }, Err(err) => { // (Semi-)permanent failure, retry later. log_error!(self.logger, @@ -205,15 +208,18 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } - } + }, Err(InternalError::Inconsistency) => { // Immediately restart syncing when we encounter any inconsistencies. - log_debug!(self.logger, "Encountered inconsistency during transaction sync, restarting."); + log_debug!( + self.logger, + "Encountered inconsistency during transaction sync, restarting." + ); sync_state.pending_sync = true; continue; - } + }, Err(err) => { // (Semi-)permanent failure, retry later. log_error!(self.logger, @@ -223,26 +229,39 @@ where ); sync_state.pending_sync = true; return Err(TxSyncError::from(err)); - } + }, } sync_state.last_sync_hash = Some(tip_hash); sync_state.pending_sync = false; } } #[cfg(feature = "time")] - log_debug!(self.logger, "Finished transaction sync at tip {} in {}ms: {} confirmed, {} unconfirmed.", - tip_hash, start_time.elapsed().as_millis(), num_confirmed, num_unconfirmed); + log_debug!( + self.logger, + "Finished transaction sync at tip {} in {}ms: {} confirmed, {} unconfirmed.", + tip_hash, + start_time.elapsed().as_millis(), + num_confirmed, + num_unconfirmed + ); #[cfg(not(feature = "time"))] - log_debug!(self.logger, "Finished transaction sync at tip {}: {} confirmed, {} unconfirmed.", - tip_hash, num_confirmed, num_unconfirmed); + log_debug!( + self.logger, + "Finished transaction sync at tip {}: {} confirmed, {} unconfirmed.", + tip_hash, + num_confirmed, + num_unconfirmed + ); Ok(()) } #[maybe_async] - fn sync_best_block_updated( - &self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, sync_state: &mut SyncState, tip_hash: &BlockHash, - ) -> Result<(), InternalError> { - + fn sync_best_block_updated( + &self, confirmables: &Vec, sync_state: &mut SyncState, tip_hash: &BlockHash, + ) -> Result<(), InternalError> + where + C::Target: Confirm, + { // Inform the interface of the new block. let tip_header = maybe_await!(self.client.get_header_by_hash(tip_hash))?; let tip_status = maybe_await!(self.client.get_block_status(&tip_hash))?; @@ -265,7 +284,6 @@ where fn get_confirmed_transactions( &self, sync_state: &SyncState, ) -> Result, InternalError> { - // First, check the confirmation status of registered transactions as well as the // status of dependent transactions of registered outputs. @@ -281,7 +299,8 @@ where } for (_, output) in &sync_state.watched_outputs { - if let Some(output_status) = maybe_await!(self.client + if let Some(output_status) = maybe_await!(self + .client .get_output_status(&output.outpoint.txid, output.outpoint.index as u64))? { if let Some(spending_txid) = output_status.txid { @@ -296,13 +315,11 @@ where } } - if let Some(confirmed_tx) = maybe_await!(self - .get_confirmed_tx( - spending_txid, - spending_tx_status.block_hash, - spending_tx_status.block_height, - ))? - { + if let Some(confirmed_tx) = maybe_await!(self.get_confirmed_tx( + spending_txid, + spending_tx_status.block_hash, + spending_tx_status.block_height, + ))? { confirmed_txs.push(confirmed_tx); } } @@ -328,7 +345,13 @@ where let block_hash = block_header.block_hash(); if let Some(expected_block_hash) = expected_block_hash { if expected_block_hash != block_hash { - log_trace!(self.logger, "Inconsistency: Tx {} expected in block {}, but is confirmed in {}", txid, expected_block_hash, block_hash); + log_trace!( + self.logger, + "Inconsistency: Tx {} expected in block {}, but is confirmed in {}", + txid, + expected_block_hash, + block_hash + ); return Err(InternalError::Inconsistency); } } @@ -360,7 +383,11 @@ where } else { // If any previously-confirmed block suddenly is no longer confirmed, we found // an inconsistency and should start over. - log_trace!(self.logger, "Inconsistency: Tx {} was unconfirmed during syncing.", txid); + log_trace!( + self.logger, + "Inconsistency: Tx {} was unconfirmed during syncing.", + txid + ); return Err(InternalError::Inconsistency); } } @@ -369,9 +396,12 @@ where } #[maybe_async] - fn get_unconfirmed_transactions( - &self, confirmables: &Vec<&(dyn Confirm + Sync + Send)>, - ) -> Result, InternalError> { + fn get_unconfirmed_transactions( + &self, confirmables: &Vec, + ) -> Result, InternalError> + where + C::Target: Confirm, + { // Query the interface for relevant txids and check whether the relevant blocks are still // in the best chain, mark them unconfirmed otherwise let relevant_txids = confirmables @@ -417,7 +447,6 @@ type EsploraClientType = AsyncClient; #[cfg(not(feature = "async-interface"))] type EsploraClientType = BlockingClient; - impl Filter for EsploraSyncClient where L::Target: Logger, diff --git a/lightning-transaction-sync/src/lib.rs b/lightning-transaction-sync/src/lib.rs index 7bd4b4aee3f..96e0c0dfe9c 100644 --- a/lightning-transaction-sync/src/lib.rs +++ b/lightning-transaction-sync/src/lib.rs @@ -60,10 +60,8 @@ #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] - #![deny(missing_docs)] #![deny(unsafe_code)] - #![cfg_attr(docsrs, feature(doc_auto_cfg))] #[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))] @@ -83,7 +81,7 @@ mod error; #[cfg(any(feature = "esplora-blocking", feature = "esplora-async", feature = "electrum"))] pub use error::TxSyncError; -#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))] -pub use esplora::EsploraSyncClient; #[cfg(feature = "electrum")] pub use electrum::ElectrumSyncClient; +#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))] +pub use esplora::EsploraSyncClient; diff --git a/lightning-transaction-sync/tests/integration_tests.rs b/lightning-transaction-sync/tests/integration_tests.rs index b1118e45776..b30594a717d 100644 --- a/lightning-transaction-sync/tests/integration_tests.rs +++ b/lightning-transaction-sync/tests/integration_tests.rs @@ -1,26 +1,29 @@ -#![cfg(all(not(target_os = "windows"), any(feature = "esplora-blocking", feature = "esplora-async", feature = "electrum")))] +#![cfg(all( + not(target_os = "windows"), + any(feature = "esplora-blocking", feature = "esplora-async", feature = "electrum") +))] -#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))] -use lightning_transaction_sync::EsploraSyncClient; -#[cfg(feature = "electrum")] -use lightning_transaction_sync::ElectrumSyncClient; -use lightning::chain::{Confirm, Filter, WatchedOutput}; use lightning::chain::transaction::{OutPoint, TransactionData}; +use lightning::chain::{Confirm, Filter, WatchedOutput}; use lightning::util::test_utils::TestLogger; +#[cfg(feature = "electrum")] +use lightning_transaction_sync::ElectrumSyncClient; +#[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))] +use lightning_transaction_sync::EsploraSyncClient; -use electrsd::{bitcoind, bitcoind::BitcoinD, ElectrsD}; -use bitcoin::{Amount, Txid, BlockHash}; +use bdk_macros::maybe_await; use bitcoin::blockdata::block::Header; use bitcoin::blockdata::constants::genesis_block; use bitcoin::network::Network; -use electrsd::bitcoind::bitcoincore_rpc::bitcoincore_rpc_json::AddressType; +use bitcoin::{Amount, BlockHash, Txid}; use bitcoind::bitcoincore_rpc::RpcApi; -use bdk_macros::maybe_await; +use electrsd::bitcoind::bitcoincore_rpc::bitcoincore_rpc_json::AddressType; +use electrsd::{bitcoind, bitcoind::BitcoinD, ElectrsD}; +use std::collections::{HashMap, HashSet}; use std::env; use std::sync::Mutex; use std::time::Duration; -use std::collections::{HashMap, HashSet}; pub fn setup_bitcoind_and_electrsd() -> (BitcoinD, ElectrsD) { let bitcoind_exe = @@ -63,8 +66,11 @@ pub fn wait_for_block(electrsd: &ElectrsD, min_height: usize) { // it didn't. Since we can't proceed without subscribing, we try again after a delay // and panic if it still fails. std::thread::sleep(Duration::from_secs(1)); - electrsd.client.block_headers_subscribe_raw().expect("failed to subscribe to block headers") - } + electrsd + .client + .block_headers_subscribe_raw() + .expect("failed to subscribe to block headers") + }, }; loop { if header.height >= min_height { @@ -90,7 +96,7 @@ where None if delay.as_millis() < 512 => { delay = delay.mul_f32(2.0); tries += 1; - } + }, None if tries == 10 => panic!("Exceeded our maximum wait time."), None => tries += 1, } @@ -132,7 +138,8 @@ impl Confirm for TestConfirmable { let block_hash = header.block_hash(); self.confirmed_txs.lock().unwrap().insert(txid, (block_hash, height)); self.unconfirmed_txs.lock().unwrap().remove(&txid); - self.events.lock().unwrap().push(TestConfirmableEvent::Confirmed(txid, block_hash, height)); + let event = TestConfirmableEvent::Confirmed(txid, block_hash, height); + self.events.lock().unwrap().push(event); } } @@ -145,11 +152,13 @@ impl Confirm for TestConfirmable { fn best_block_updated(&self, header: &Header, height: u32) { let block_hash = header.block_hash(); *self.best_block.lock().unwrap() = (block_hash, height); - self.events.lock().unwrap().push(TestConfirmableEvent::BestBlockUpdated(block_hash, height)); + let event = TestConfirmableEvent::BestBlockUpdated(block_hash, height); + self.events.lock().unwrap().push(event); } fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option)> { - self.confirmed_txs.lock().unwrap().iter().map(|(&txid, (hash, height))| (txid, *height, Some(*hash))).collect::>() + let lock = self.confirmed_txs.lock().unwrap(); + lock.iter().map(|(&txid, (hash, height))| (txid, *height, Some(*hash))).collect() } } @@ -165,12 +174,37 @@ macro_rules! test_syncing { assert_eq!(events.len(), 1); // Check registered confirmed transactions are marked confirmed - let new_address = $bitcoind.client.get_new_address(Some("test"), - Some(AddressType::Legacy)).unwrap().assume_checked(); - let txid = $bitcoind.client.send_to_address(&new_address, Amount::from_sat(5000), None, None, - None, None, None, None).unwrap(); - let second_txid = $bitcoind.client.send_to_address(&new_address, Amount::from_sat(5000), None, - None, None, None, None, None).unwrap(); + let new_address = $bitcoind + .client + .get_new_address(Some("test"), Some(AddressType::Legacy)) + .unwrap() + .assume_checked(); + let txid = $bitcoind + .client + .send_to_address( + &new_address, + Amount::from_sat(5000), + None, + None, + None, + None, + None, + None, + ) + .unwrap(); + let second_txid = $bitcoind + .client + .send_to_address( + &new_address, + Amount::from_sat(5000), + None, + None, + None, + None, + None, + None, + ) + .unwrap(); $tx_sync.register_tx(&txid, &new_address.payload().script_pubkey()); maybe_await!($tx_sync.sync(vec![&$confirmable])).unwrap(); @@ -193,13 +227,17 @@ macro_rules! test_syncing { let block_hash = tx_res.info.blockhash.unwrap(); let tx = tx_res.transaction().unwrap(); let prev_outpoint = tx.input.first().unwrap().previous_output; - let prev_tx = $bitcoind.client.get_transaction(&prev_outpoint.txid, None).unwrap().transaction() + let prev_tx = $bitcoind + .client + .get_transaction(&prev_outpoint.txid, None) + .unwrap() + .transaction() .unwrap(); let prev_script_pubkey = prev_tx.output[prev_outpoint.vout as usize].script_pubkey.clone(); let output = WatchedOutput { block_hash: Some(block_hash), outpoint: OutPoint { txid: prev_outpoint.txid, index: prev_outpoint.vout as u16 }, - script_pubkey: prev_script_pubkey + script_pubkey: prev_script_pubkey, }; $tx_sync.register_output(output); diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 447ae04e3d4..cd6061a2030 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -3105,9 +3105,7 @@ impl ChannelMonitorImpl { }, commitment_txid: htlc.commitment_txid, per_commitment_number: htlc.per_commitment_number, - per_commitment_point: self.onchain_tx_handler.signer.get_per_commitment_point( - htlc.per_commitment_number, &self.onchain_tx_handler.secp_ctx, - ), + per_commitment_point: htlc.per_commitment_point, feerate_per_kw: 0, htlc: htlc.htlc, preimage: htlc.preimage, diff --git a/lightning/src/chain/onchaintx.rs b/lightning/src/chain/onchaintx.rs index be097b637d0..e5757cfd1e5 100644 --- a/lightning/src/chain/onchaintx.rs +++ b/lightning/src/chain/onchaintx.rs @@ -20,6 +20,7 @@ use bitcoin::blockdata::script::{Script, ScriptBuf}; use bitcoin::hashes::{Hash, HashEngine}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hash_types::{Txid, BlockHash}; +use bitcoin::secp256k1::PublicKey; use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature}; use bitcoin::secp256k1; @@ -180,6 +181,7 @@ pub(crate) struct ExternalHTLCClaim { pub(crate) htlc: HTLCOutputInCommitment, pub(crate) preimage: Option, pub(crate) counterparty_sig: Signature, + pub(crate) per_commitment_point: PublicKey, } // Represents the different types of claims for which events are yielded externally to satisfy said @@ -1231,6 +1233,7 @@ impl OnchainTxHandler { htlc: htlc.clone(), preimage: *preimage, counterparty_sig: counterparty_htlc_sig, + per_commitment_point: trusted_tx.per_commitment_point(), } }) }; diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index c165e81fcab..a8d50ff6ef3 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1554,8 +1554,9 @@ where /// # /// # fn example(channel_manager: T) -> Result<(), Bolt12SemanticError> { /// # let channel_manager = channel_manager.get_cm(); +/// # let absolute_expiry = None; /// let offer = channel_manager -/// .create_offer_builder()? +/// .create_offer_builder(absolute_expiry)? /// # ; /// # // Needed for compiling for c_bindings /// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into(); @@ -2287,6 +2288,19 @@ const MAX_UNFUNDED_CHANNEL_PEERS: usize = 50; /// many peers we reject new (inbound) connections. const MAX_NO_CHANNEL_PEERS: usize = 250; +/// The maximum expiration from the current time where an [`Offer`] or [`Refund`] is considered +/// short-lived, while anything with a greater expiration is considered long-lived. +/// +/// Using [`ChannelManager::create_offer_builder`] or [`ChannelManager::create_refund_builder`], +/// will included a [`BlindedPath`] created using: +/// - [`MessageRouter::create_compact_blinded_paths`] when short-lived, and +/// - [`MessageRouter::create_blinded_paths`] when long-lived. +/// +/// Using compact [`BlindedPath`]s may provide better privacy as the [`MessageRouter`] could select +/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to +/// become invalid over time as channels are closed. Thus, they are only suitable for short-term use. +pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 60 * 24); + /// Used by [`ChannelManager::list_recent_payments`] to express the status of recent payments. /// These include payments that have yet to find a successful path, or have unresolved HTLCs. #[derive(Debug, PartialEq)] @@ -8240,16 +8254,15 @@ where macro_rules! create_offer_builder { ($self: ident, $builder: ty) => { /// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the - /// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer will - /// not have an expiration unless otherwise set on the builder. + /// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer's + /// expiration will be `absolute_expiry` if `Some`, otherwise it will not expire. /// /// # Privacy /// - /// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the offer. - /// However, if one is not found, uses a one-hop [`BlindedPath`] with - /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case, - /// the node must be announced, otherwise, there is no way to find a path to the introduction in - /// order to send the [`InvoiceRequest`]. + /// Uses [`MessageRouter`] to construct a [`BlindedPath`] for the offer based on the given + /// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for + /// privacy implications as well as those of the parameterized [`Router`], which implements + /// [`MessageRouter`]. /// /// Also, uses a derived signing pubkey in the offer for recipient privacy. /// @@ -8264,19 +8277,27 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => { /// /// [`Offer`]: crate::offers::offer::Offer /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest - pub fn create_offer_builder(&$self) -> Result<$builder, Bolt12SemanticError> { + pub fn create_offer_builder( + &$self, absolute_expiry: Option + ) -> Result<$builder, Bolt12SemanticError> { let node_id = $self.get_our_node_id(); let expanded_key = &$self.inbound_payment_key; let entropy = &*$self.entropy_source; let secp_ctx = &$self.secp_ctx; - let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?; + let path = $self.create_blinded_path_using_absolute_expiry(absolute_expiry) + .map_err(|_| Bolt12SemanticError::MissingPaths)?; let builder = OfferBuilder::deriving_signing_pubkey( node_id, expanded_key, entropy, secp_ctx ) .chain_hash($self.chain_hash) .path(path); + let builder = match absolute_expiry { + None => builder, + Some(absolute_expiry) => builder.absolute_expiry(absolute_expiry), + }; + Ok(builder.into()) } } } @@ -8304,11 +8325,10 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => { /// /// # Privacy /// - /// Uses [`MessageRouter::create_blinded_paths`] to construct a [`BlindedPath`] for the refund. - /// However, if one is not found, uses a one-hop [`BlindedPath`] with - /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case, - /// the node must be announced, otherwise, there is no way to find a path to the introduction in - /// order to send the [`Bolt12Invoice`]. + /// Uses [`MessageRouter`] to construct a [`BlindedPath`] for the refund based on the given + /// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for + /// privacy implications as well as those of the parameterized [`Router`], which implements + /// [`MessageRouter`]. /// /// Also, uses a derived payer id in the refund for payer privacy. /// @@ -8337,7 +8357,8 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => { let entropy = &*$self.entropy_source; let secp_ctx = &$self.secp_ctx; - let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?; + let path = $self.create_blinded_path_using_absolute_expiry(Some(absolute_expiry)) + .map_err(|_| Bolt12SemanticError::MissingPaths)?; let builder = RefundBuilder::deriving_payer_id( node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id )? @@ -8406,10 +8427,9 @@ where /// /// # Privacy /// - /// Uses a one-hop [`BlindedPath`] for the reply path with [`ChannelManager::get_our_node_id`] - /// as the introduction node and a derived payer id for payer privacy. As such, currently, the - /// node must be announced. Otherwise, there is no way to find a path to the introduction node - /// in order to send the [`Bolt12Invoice`]. + /// For payer privacy, uses a derived payer id and uses [`MessageRouter::create_blinded_paths`] + /// to construct a [`BlindedPath`] for the reply path. For further privacy implications, see the + /// docs of the parameterized [`Router`], which implements [`MessageRouter`]. /// /// # Limitations /// @@ -8686,6 +8706,38 @@ where inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key) } + /// Creates a blinded path by delegating to [`MessageRouter`] based on the path's intended + /// lifetime. + /// + /// Whether or not the path is compact depends on whether the path is short-lived or long-lived, + /// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See + /// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. + fn create_blinded_path_using_absolute_expiry( + &self, absolute_expiry: Option + ) -> Result { + let now = self.duration_since_epoch(); + let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY); + + if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry { + self.create_compact_blinded_path() + } else { + self.create_blinded_path() + } + } + + pub(super) fn duration_since_epoch(&self) -> Duration { + #[cfg(not(feature = "std"))] + let now = Duration::from_secs( + self.highest_seen_timestamp.load(Ordering::Acquire) as u64 + ); + #[cfg(feature = "std")] + let now = std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"); + + now + } + /// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`]. /// /// Errors if the `MessageRouter` errors or returns an empty `Vec`. @@ -8696,6 +8748,27 @@ where let peers = self.per_peer_state.read().unwrap() .iter() .map(|(node_id, peer_state)| (node_id, peer_state.lock().unwrap())) + .filter(|(_, peer)| peer.is_connected) + .filter(|(_, peer)| peer.latest_features.supports_onion_messages()) + .map(|(node_id, _)| *node_id) + .collect::>(); + + self.router + .create_blinded_paths(recipient, peers, secp_ctx) + .and_then(|paths| paths.into_iter().next().ok_or(())) + } + + /// Creates a blinded path by delegating to [`MessageRouter::create_compact_blinded_paths`]. + /// + /// Errors if the `MessageRouter` errors or returns an empty `Vec`. + fn create_compact_blinded_path(&self) -> Result { + let recipient = self.get_our_node_id(); + let secp_ctx = &self.secp_ctx; + + let peers = self.per_peer_state.read().unwrap() + .iter() + .map(|(node_id, peer_state)| (node_id, peer_state.lock().unwrap())) + .filter(|(_, peer)| peer.is_connected) .filter(|(_, peer)| peer.latest_features.supports_onion_messages()) .map(|(node_id, peer)| ForwardNode { node_id: *node_id, @@ -8708,7 +8781,7 @@ where .collect::>(); self.router - .create_blinded_paths(recipient, peers, secp_ctx) + .create_compact_blinded_paths(recipient, peers, secp_ctx) .and_then(|paths| paths.into_iter().next().ok_or(())) } diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index c0f3458b3d6..7e57f20595a 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -2455,18 +2455,11 @@ pub fn expect_payment_failed_conditions_event<'a, 'b, 'c, 'd, 'e>( if let Some(chan_closed) = conditions.expected_blamed_chan_closed { if let PathFailure::OnPath { network_update: Some(upd) } = failure { match upd { - NetworkUpdate::ChannelUpdateMessage { ref msg } if !chan_closed => { - if let Some(scid) = conditions.expected_blamed_scid { - assert_eq!(msg.contents.short_channel_id, scid); - } - const CHAN_DISABLED_FLAG: u8 = 2; - assert_eq!(msg.contents.flags & CHAN_DISABLED_FLAG, 0); - }, - NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } if chan_closed => { + NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } => { if let Some(scid) = conditions.expected_blamed_scid { assert_eq!(*short_channel_id, scid); } - assert!(is_permanent); + assert_eq!(*is_permanent, chan_closed); }, _ => panic!("Unexpected update type"), } @@ -3259,30 +3252,34 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>) { + let node_id_a = node_a.node.get_our_node_id(); + let node_id_b = node_b.node.get_our_node_id(); + + let init_a = msgs::Init { + features: node_a.init_features(&node_id_b), + networks: None, + remote_network_address: None, + }; + let init_b = msgs::Init { + features: node_b.init_features(&node_id_a), + networks: None, + remote_network_address: None, + }; + + node_a.node.peer_connected(&node_id_b, &init_b, true).unwrap(); + node_b.node.peer_connected(&node_id_a, &init_a, false).unwrap(); + node_a.onion_messenger.peer_connected(&node_id_b, &init_b, true).unwrap(); + node_b.onion_messenger.peer_connected(&node_id_a, &init_a, false).unwrap(); +} + pub fn connect_dummy_node<'a, 'b: 'a, 'c: 'b>(node: &Node<'a, 'b, 'c>) { let node_id_dummy = PublicKey::from_slice(&[2; 33]).unwrap(); @@ -3643,13 +3640,8 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) { pending_cell_htlc_claims, pending_cell_htlc_fails, pending_raa, pending_responding_commitment_signed, pending_responding_commitment_signed_dup_monitor, } = args; - node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { - features: node_b.node.init_features(), networks: None, remote_network_address: None - }, true).unwrap(); + connect_nodes(node_a, node_b); let reestablish_1 = get_chan_reestablish_msgs!(node_a, node_b); - node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { - features: node_a.node.init_features(), networks: None, remote_network_address: None - }, false).unwrap(); let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a); if send_channel_ready.0 { diff --git a/lightning/src/ln/offers_tests.rs b/lightning/src/ln/offers_tests.rs index eedd82c569b..c7fb5f8fd59 100644 --- a/lightning/src/ln/offers_tests.rs +++ b/lightning/src/ln/offers_tests.rs @@ -46,7 +46,7 @@ use core::time::Duration; use crate::blinded_path::{BlindedPath, IntroductionNode}; use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentContext}; use crate::events::{Event, MessageSendEventsProvider, PaymentPurpose}; -use crate::ln::channelmanager::{PaymentId, RecentPaymentDetails, Retry, self}; +use crate::ln::channelmanager::{MAX_SHORT_LIVED_RELATIVE_EXPIRY, PaymentId, RecentPaymentDetails, Retry, self}; use crate::ln::functional_test_utils::*; use crate::ln::msgs::{ChannelMessageHandler, Init, NodeAnnouncement, OnionMessage, OnionMessageHandler, RoutingMessageHandler, SocketAddress, UnsignedGossipMessage, UnsignedNodeAnnouncement}; use crate::offers::invoice::Bolt12Invoice; @@ -274,7 +274,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() { announce_node_address(charlie, &[alice, bob, david, &nodes[4], &nodes[5]], tor.clone()); let offer = bob.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .amount_msats(10_000_000) .build().unwrap(); assert_ne!(offer.signing_pubkey(), Some(bob_id)); @@ -290,7 +290,7 @@ fn prefers_non_tor_nodes_in_blinded_paths() { announce_node_address(&nodes[5], &[alice, bob, charlie, david, &nodes[4]], tor.clone()); let offer = bob.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .amount_msats(10_000_000) .build().unwrap(); assert_ne!(offer.signing_pubkey(), Some(bob_id)); @@ -341,7 +341,7 @@ fn prefers_more_connected_nodes_in_blinded_paths() { disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]); let offer = bob.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .amount_msats(10_000_000) .build().unwrap(); assert_ne!(offer.signing_pubkey(), Some(bob_id)); @@ -352,6 +352,124 @@ fn prefers_more_connected_nodes_in_blinded_paths() { } } +/// Checks that blinded paths are compact for short-lived offers. +#[test] +fn creates_short_lived_offer() { + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000); + + let alice = &nodes[0]; + let alice_id = alice.node.get_our_node_id(); + let bob = &nodes[1]; + + let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY; + let offer = alice.node + .create_offer_builder(Some(absolute_expiry)).unwrap() + .build().unwrap(); + assert_eq!(offer.absolute_expiry(), Some(absolute_expiry)); + assert!(!offer.paths().is_empty()); + for path in offer.paths() { + let introduction_node_id = resolve_introduction_node(bob, &path); + assert_eq!(introduction_node_id, alice_id); + assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + } +} + +/// Checks that blinded paths are not compact for long-lived offers. +#[test] +fn creates_long_lived_offer() { + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000); + + let alice = &nodes[0]; + let alice_id = alice.node.get_our_node_id(); + + let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY + + Duration::from_secs(1); + let offer = alice.node + .create_offer_builder(Some(absolute_expiry)) + .unwrap() + .build().unwrap(); + assert_eq!(offer.absolute_expiry(), Some(absolute_expiry)); + assert!(!offer.paths().is_empty()); + for path in offer.paths() { + assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id)); + } + + let offer = alice.node + .create_offer_builder(None).unwrap() + .build().unwrap(); + assert_eq!(offer.absolute_expiry(), None); + assert!(!offer.paths().is_empty()); + for path in offer.paths() { + assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id)); + } +} + +/// Checks that blinded paths are compact for short-lived refunds. +#[test] +fn creates_short_lived_refund() { + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000); + + let alice = &nodes[0]; + let bob = &nodes[1]; + let bob_id = bob.node.get_our_node_id(); + + let absolute_expiry = bob.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY; + let payment_id = PaymentId([1; 32]); + let refund = bob.node + .create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None) + .unwrap() + .build().unwrap(); + assert_eq!(refund.absolute_expiry(), Some(absolute_expiry)); + assert!(!refund.paths().is_empty()); + for path in refund.paths() { + let introduction_node_id = resolve_introduction_node(alice, &path); + assert_eq!(introduction_node_id, bob_id); + assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + } +} + +/// Checks that blinded paths are not compact for long-lived refunds. +#[test] +fn creates_long_lived_refund() { + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000); + + let bob = &nodes[1]; + let bob_id = bob.node.get_our_node_id(); + + let absolute_expiry = bob.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY + + Duration::from_secs(1); + let payment_id = PaymentId([1; 32]); + let refund = bob.node + .create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None) + .unwrap() + .build().unwrap(); + assert_eq!(refund.absolute_expiry(), Some(absolute_expiry)); + assert!(!refund.paths().is_empty()); + for path in refund.paths() { + assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id)); + } +} + /// Checks that an offer can be paid through blinded paths and that ephemeral pubkeys are used /// rather than exposing a node's pubkey. #[test] @@ -391,16 +509,14 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() { disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]); let offer = alice.node - .create_offer_builder() + .create_offer_builder(None) .unwrap() .amount_msats(10_000_000) .build().unwrap(); assert_ne!(offer.signing_pubkey(), Some(alice_id)); assert!(!offer.paths().is_empty()); for path in offer.paths() { - let introduction_node_id = resolve_introduction_node(david, &path); - assert_eq!(introduction_node_id, bob_id); - assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id)); } let payment_id = PaymentId([1; 32]); @@ -427,11 +543,9 @@ fn creates_and_pays_for_offer_using_two_hop_blinded_path() { payer_note_truncated: None, }, }); - let introduction_node_id = resolve_introduction_node(alice, &reply_path); assert_eq!(invoice_request.amount_msats(), None); assert_ne!(invoice_request.payer_id(), david_id); - assert_eq!(introduction_node_id, charlie_id); - assert!(matches!(reply_path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + assert_eq!(reply_path.introduction_node, IntroductionNode::NodeId(charlie_id)); let onion_message = alice.onion_messenger.next_onion_message_for_peer(charlie_id).unwrap(); charlie.onion_messenger.handle_onion_message(&alice_id, &onion_message); @@ -503,9 +617,7 @@ fn creates_and_pays_for_refund_using_two_hop_blinded_path() { assert_ne!(refund.payer_id(), david_id); assert!(!refund.paths().is_empty()); for path in refund.paths() { - let introduction_node_id = resolve_introduction_node(alice, &path); - assert_eq!(introduction_node_id, charlie_id); - assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + assert_eq!(path.introduction_node, IntroductionNode::NodeId(charlie_id)); } expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id); @@ -555,15 +667,13 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() { let bob_id = bob.node.get_our_node_id(); let offer = alice.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .amount_msats(10_000_000) .build().unwrap(); assert_ne!(offer.signing_pubkey(), Some(alice_id)); assert!(!offer.paths().is_empty()); for path in offer.paths() { - let introduction_node_id = resolve_introduction_node(bob, &path); - assert_eq!(introduction_node_id, alice_id); - assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id)); } let payment_id = PaymentId([1; 32]); @@ -582,11 +692,9 @@ fn creates_and_pays_for_offer_using_one_hop_blinded_path() { payer_note_truncated: None, }, }); - let introduction_node_id = resolve_introduction_node(alice, &reply_path); assert_eq!(invoice_request.amount_msats(), None); assert_ne!(invoice_request.payer_id(), bob_id); - assert_eq!(introduction_node_id, bob_id); - assert!(matches!(reply_path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + assert_eq!(reply_path.introduction_node, IntroductionNode::NodeId(bob_id)); let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap(); bob.onion_messenger.handle_onion_message(&alice_id, &onion_message); @@ -634,9 +742,7 @@ fn creates_and_pays_for_refund_using_one_hop_blinded_path() { assert_ne!(refund.payer_id(), bob_id); assert!(!refund.paths().is_empty()); for path in refund.paths() { - let introduction_node_id = resolve_introduction_node(alice, &path); - assert_eq!(introduction_node_id, bob_id); - assert!(matches!(path.introduction_node, IntroductionNode::DirectedShortChannelId(..))); + assert_eq!(path.introduction_node, IntroductionNode::NodeId(bob_id)); } expect_recent_payment!(bob, RecentPaymentDetails::AwaitingInvoice, payment_id); @@ -681,7 +787,7 @@ fn pays_for_offer_without_blinded_paths() { let bob_id = bob.node.get_our_node_id(); let offer = alice.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .clear_paths() .amount_msats(10_000_000) .build().unwrap(); @@ -769,7 +875,7 @@ fn fails_creating_offer_without_blinded_paths() { create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000); - match nodes[0].node.create_offer_builder() { + match nodes[0].node.create_offer_builder(None) { Ok(_) => panic!("Expected error"), Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), } @@ -798,6 +904,129 @@ fn fails_creating_refund_without_blinded_paths() { assert!(nodes[0].node.list_recent_payments().is_empty()); } +/// Fails creating or paying an offer when a blinded path cannot be created because no peers are +/// connected. +#[test] +fn fails_creating_or_paying_for_offer_without_connected_peers() { + let chanmon_cfgs = create_chanmon_cfgs(6); + let node_cfgs = create_node_cfgs(6, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(6, &node_cfgs, &[None, None, None, None, None, None]); + let nodes = create_network(6, &node_cfgs, &node_chanmgrs); + + create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000); + create_unannounced_chan_between_nodes_with_value(&nodes, 2, 3, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 1, 4, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 1, 5, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 2, 4, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 2, 5, 10_000_000, 1_000_000_000); + + let (alice, bob, charlie, david) = (&nodes[0], &nodes[1], &nodes[2], &nodes[3]); + + disconnect_peers(alice, &[bob, charlie, david, &nodes[4], &nodes[5]]); + disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]); + + let absolute_expiry = alice.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY; + match alice.node.create_offer_builder(Some(absolute_expiry)) { + Ok(_) => panic!("Expected error"), + Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), + } + + let mut args = ReconnectArgs::new(alice, bob); + args.send_channel_ready = (true, true); + reconnect_nodes(args); + + let offer = alice.node + .create_offer_builder(Some(absolute_expiry)).unwrap() + .amount_msats(10_000_000) + .build().unwrap(); + + let payment_id = PaymentId([1; 32]); + + match david.node.pay_for_offer(&offer, None, None, None, payment_id, Retry::Attempts(0), None) { + Ok(_) => panic!("Expected error"), + Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), + } + + assert!(nodes[0].node.list_recent_payments().is_empty()); + + let mut args = ReconnectArgs::new(charlie, david); + args.send_channel_ready = (true, true); + reconnect_nodes(args); + + assert!( + david.node.pay_for_offer( + &offer, None, None, None, payment_id, Retry::Attempts(0), None + ).is_ok() + ); + + expect_recent_payment!(david, RecentPaymentDetails::AwaitingInvoice, payment_id); +} + +/// Fails creating or sending an invoice for a refund when a blinded path cannot be created because +/// no peers are connected. +#[test] +fn fails_creating_refund_or_sending_invoice_without_connected_peers() { + let mut accept_forward_cfg = test_default_channel_config(); + accept_forward_cfg.accept_forwards_to_priv_channels = true; + + let mut features = channelmanager::provided_init_features(&accept_forward_cfg); + features.set_onion_messages_optional(); + features.set_route_blinding_optional(); + + let chanmon_cfgs = create_chanmon_cfgs(6); + let node_cfgs = create_node_cfgs(6, &chanmon_cfgs); + + *node_cfgs[1].override_init_features.borrow_mut() = Some(features); + + let node_chanmgrs = create_node_chanmgrs( + 6, &node_cfgs, &[None, Some(accept_forward_cfg), None, None, None, None] + ); + let nodes = create_network(6, &node_cfgs, &node_chanmgrs); + + create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 1_000_000_000); + create_unannounced_chan_between_nodes_with_value(&nodes, 2, 3, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 1, 4, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 1, 5, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 2, 4, 10_000_000, 1_000_000_000); + create_announced_chan_between_nodes_with_value(&nodes, 2, 5, 10_000_000, 1_000_000_000); + + let (alice, bob, charlie, david) = (&nodes[0], &nodes[1], &nodes[2], &nodes[3]); + + disconnect_peers(alice, &[bob, charlie, david, &nodes[4], &nodes[5]]); + disconnect_peers(david, &[bob, charlie, &nodes[4], &nodes[5]]); + + let absolute_expiry = david.node.duration_since_epoch() + MAX_SHORT_LIVED_RELATIVE_EXPIRY; + let payment_id = PaymentId([1; 32]); + match david.node.create_refund_builder( + 10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None + ) { + Ok(_) => panic!("Expected error"), + Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), + } + + let mut args = ReconnectArgs::new(charlie, david); + args.send_channel_ready = (true, true); + reconnect_nodes(args); + + let refund = david.node + .create_refund_builder(10_000_000, absolute_expiry, payment_id, Retry::Attempts(0), None) + .unwrap() + .build().unwrap(); + + match alice.node.request_refund_payment(&refund) { + Ok(_) => panic!("Expected error"), + Err(e) => assert_eq!(e, Bolt12SemanticError::MissingPaths), + } + + let mut args = ReconnectArgs::new(alice, bob); + args.send_channel_ready = (true, true); + reconnect_nodes(args); + + assert!(alice.node.request_refund_payment(&refund).is_ok()); +} + /// Fails creating an invoice request when the offer contains an unsupported chain. #[test] fn fails_creating_invoice_request_for_unsupported_chain() { @@ -812,7 +1041,7 @@ fn fails_creating_invoice_request_for_unsupported_chain() { let bob = &nodes[1]; let offer = alice.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .clear_chains() .chain(Network::Signet) .build().unwrap(); @@ -872,7 +1101,7 @@ fn fails_creating_invoice_request_without_blinded_reply_path() { disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]); let offer = alice.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .amount_msats(10_000_000) .build().unwrap(); @@ -906,7 +1135,7 @@ fn fails_creating_invoice_request_with_duplicate_payment_id() { disconnect_peers(alice, &[charlie, david, &nodes[4], &nodes[5]]); let offer = alice.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .amount_msats(10_000_000) .build().unwrap(); @@ -992,7 +1221,7 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_offer() { disconnect_peers(david, &[bob, &nodes[4], &nodes[5]]); let offer = alice.node - .create_offer_builder().unwrap() + .create_offer_builder(None).unwrap() .amount_msats(10_000_000) .build().unwrap(); diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index c5ce3e051fd..02109c888f5 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -180,11 +180,6 @@ fn run_onion_failure_test_with_fail_intercept( if expected_channel_update.is_some() { match network_update { Some(update) => match update { - &NetworkUpdate::ChannelUpdateMessage { .. } => { - if let NetworkUpdate::ChannelUpdateMessage { .. } = expected_channel_update.unwrap() {} else { - panic!("channel_update not found!"); - } - }, &NetworkUpdate::ChannelFailure { ref short_channel_id, ref is_permanent } => { if let NetworkUpdate::ChannelFailure { short_channel_id: ref expected_short_channel_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() { assert!(*short_channel_id == *expected_short_channel_id); @@ -300,12 +295,13 @@ fn test_fee_failures() { claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_success); // If the hop gives fee_insufficient but enough fees were provided, then the previous hop - // malleated the payment before forwarding, taking funds when they shouldn't have. + // malleated the payment before forwarding, taking funds when they shouldn't have. However, + // because we ignore channel update contents, we will still blame the 2nd channel. let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]); - let short_channel_id = channels[0].0.contents.short_channel_id; + let short_channel_id = channels[1].0.contents.short_channel_id; run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.amount_msat -= 1; - }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: true}), Some(short_channel_id)); + }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false}), Some(short_channel_id)); // In an earlier version, we spuriously failed to forward payments if the expected feerate // changed between the channel open and the payment. @@ -478,7 +474,9 @@ fn test_onion_failure() { let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), UPDATE|7, &err_data); - }, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: chan_update.clone()}), Some(short_channel_id)); + }, ||{}, true, Some(UPDATE|7), + Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false }), + Some(short_channel_id)); // Check we can still handle onion failures that include channel updates without a type prefix let err_data_without_type = chan_update.encode_with_len(); @@ -488,7 +486,9 @@ fn test_onion_failure() { let session_priv = SecretKey::from_slice(&[3; 32]).unwrap(); let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap(); msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), UPDATE|7, &err_data_without_type); - }, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: chan_update}), Some(short_channel_id)); + }, ||{}, true, Some(UPDATE|7), + Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false }), + Some(short_channel_id)); let short_channel_id = channels[1].0.contents.short_channel_id; run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| { @@ -523,7 +523,9 @@ fn test_onion_failure() { let mut bogus_route = route.clone(); let route_len = bogus_route.paths[0].hops.len(); bogus_route.paths[0].hops[route_len-1].fee_msat = amt_to_forward; - run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id)); + run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), + Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false }), + Some(short_channel_id)); // Clear pending payments so that the following positive test has the correct payment hash. for node in nodes.iter() { @@ -535,16 +537,18 @@ fn test_onion_failure() { let preimage = send_along_route(&nodes[0], bogus_route, &[&nodes[1], &nodes[2]], amt_to_forward+1).0; claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], preimage); - let short_channel_id = channels[0].0.contents.short_channel_id; + // We ignore channel update contents in onion errors, so will blame the 2nd channel even though + // the first node is the one that messed up. + let short_channel_id = channels[1].0.contents.short_channel_id; run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.amount_msat -= 1; - }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: true}), Some(short_channel_id)); + }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false}), Some(short_channel_id)); - let short_channel_id = channels[0].0.contents.short_channel_id; + let short_channel_id = channels[1].0.contents.short_channel_id; run_onion_failure_test("incorrect_cltv_expiry", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { // need to violate: cltv_expiry - cltv_expiry_delta >= outgoing_cltv_value msg.cltv_expiry -= 1; - }, || {}, true, Some(UPDATE|13), Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: true}), Some(short_channel_id)); + }, || {}, true, Some(UPDATE|13), Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false}), Some(short_channel_id)); let short_channel_id = channels[1].0.contents.short_channel_id; run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { @@ -552,7 +556,9 @@ fn test_onion_failure() { connect_blocks(&nodes[0], height - nodes[0].best_block_info().1); connect_blocks(&nodes[1], height - nodes[1].best_block_info().1); connect_blocks(&nodes[2], height - nodes[2].best_block_info().1); - }, ||{}, true, Some(UPDATE|14), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id)); + }, ||{}, true, Some(UPDATE|14), + Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false }), + Some(short_channel_id)); run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || { nodes[2].node.fail_htlc_backwards(&payment_hash); @@ -596,7 +602,9 @@ fn test_onion_failure() { // disconnect event to the channel between nodes[1] ~ nodes[2] nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id()); nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id()); - }, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id)); + }, true, Some(UPDATE|7), + Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false }), + Some(short_channel_id)); run_onion_failure_test("channel_disabled", 0, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || { // disconnect event to the channel between nodes[1] ~ nodes[2] for _ in 0..DISABLE_GOSSIP_TICKS + 1 { @@ -605,7 +613,9 @@ fn test_onion_failure() { } nodes[1].node.get_and_clear_pending_msg_events(); nodes[2].node.get_and_clear_pending_msg_events(); - }, true, Some(UPDATE|20), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id)); + }, true, Some(UPDATE|20), + Some(NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false }), + Some(short_channel_id)); reconnect_nodes(ReconnectArgs::new(&nodes[1], &nodes[2])); run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { @@ -844,9 +854,9 @@ fn do_test_onion_failure_stale_channel_update(announced_channel: bool) { // We'll be attempting to route payments using the default ChannelUpdate for channels. This will // lead to onion failures at the first hop once we update the ChannelConfig for the // second hop. - let expect_onion_failure = |name: &str, error_code: u16, channel_update: &msgs::ChannelUpdate| { + let expect_onion_failure = |name: &str, error_code: u16| { let short_channel_id = channel_to_update.1; - let network_update = NetworkUpdate::ChannelUpdateMessage { msg: channel_update.clone() }; + let network_update = NetworkUpdate::ChannelFailure { short_channel_id, is_permanent: false }; run_onion_failure_test( name, 0, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {}, true, Some(error_code), Some(network_update), Some(short_channel_id), @@ -878,7 +888,7 @@ fn do_test_onion_failure_stale_channel_update(announced_channel: bool) { // Connect a block, which should expire the previous config, leading to a failure when // forwarding the HTLC. expire_prev_config(); - expect_onion_failure("fee_insufficient", UPDATE|12, &msg); + expect_onion_failure("fee_insufficient", UPDATE|12); // Redundant updates should not trigger a new ChannelUpdate. assert!(update_and_get_channel_update(&config, false, None, false).is_none()); @@ -891,15 +901,15 @@ fn do_test_onion_failure_stale_channel_update(announced_channel: bool) { // new ChannelUpdate. config.forwarding_fee_base_msat = default_config.forwarding_fee_base_msat; config.cltv_expiry_delta = u16::max_value(); - let msg = update_and_get_channel_update(&config, true, Some(&msg), true).unwrap(); - expect_onion_failure("incorrect_cltv_expiry", UPDATE|13, &msg); + assert!(update_and_get_channel_update(&config, true, Some(&msg), true).is_some()); + expect_onion_failure("incorrect_cltv_expiry", UPDATE|13); // Reset the proportional fee and increase the CLTV expiry delta which should trigger a new // ChannelUpdate. config.cltv_expiry_delta = default_config.cltv_expiry_delta; config.forwarding_fee_proportional_millionths = u32::max_value(); - let msg = update_and_get_channel_update(&config, true, Some(&msg), true).unwrap(); - expect_onion_failure("fee_insufficient", UPDATE|12, &msg); + assert!(update_and_get_channel_update(&config, true, Some(&msg), true).is_some()); + expect_onion_failure("fee_insufficient", UPDATE|12); // To test persistence of the updated config, we'll re-initialize the ChannelManager. let config_after_restart = { @@ -1530,10 +1540,10 @@ fn do_test_phantom_dust_exposure_failure(multiplier_dust_limit: bool) { err_data.extend_from_slice(&channel.1.encode()); let mut fail_conditions = PaymentFailedConditions::new() - .blamed_scid(channel.0.contents.short_channel_id) + .blamed_scid(route.paths[0].hops.last().as_ref().unwrap().short_channel_id) .blamed_chan_closed(false) .expected_htlc_error_data(0x1000 | 7, &err_data); - expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions); + expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions); } #[test] diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 9a207c9e52d..fab73cf73ec 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -15,7 +15,6 @@ use crate::ln::channelmanager::{HTLCSource, RecipientOnionFields}; use crate::ln::features::{ChannelFeatures, NodeFeatures}; use crate::ln::msgs; use crate::ln::types::{PaymentHash, PaymentPreimage}; -use crate::ln::wire::Encode; use crate::routing::gossip::NetworkUpdate; use crate::routing::router::{Path, RouteHop, RouteParameters}; use crate::sign::NodeSigner; @@ -806,106 +805,16 @@ where { let update_len = u16::from_be_bytes(update_len_slice.try_into().expect("len is 2")) as usize; - if let Some(mut update_slice) = err_packet + if err_packet .failuremsg .get(debug_field_size + 4..debug_field_size + 4 + update_len) + .is_some() { - // Historically, the BOLTs were unclear if the message type - // bytes should be included here or not. The BOLTs have now - // been updated to indicate that they *are* included, but many - // nodes still send messages without the type bytes, so we - // support both here. - // TODO: Switch to hard require the type prefix, as the current - // permissiveness introduces the (although small) possibility - // that we fail to decode legitimate channel updates that - // happen to start with ChannelUpdate::TYPE, i.e., [0x01, 0x02]. - if update_slice.len() > 2 - && update_slice[0..2] == msgs::ChannelUpdate::TYPE.to_be_bytes() - { - update_slice = &update_slice[2..]; - } else { - log_trace!(logger, "Failure provided features a channel update without type prefix. Deprecated, but allowing for now."); - } - let update_opt = msgs::ChannelUpdate::read(&mut Cursor::new(&update_slice)); - if update_opt.is_ok() || update_slice.is_empty() { - // if channel_update should NOT have caused the failure: - // MAY treat the channel_update as invalid. - let is_chan_update_invalid = match error_code & 0xff { - 7 => false, - 11 => { - update_opt.is_ok() - && amt_to_forward - > update_opt.as_ref().unwrap().contents.htlc_minimum_msat - }, - 12 => { - update_opt.is_ok() - && amt_to_forward - .checked_mul( - update_opt - .as_ref() - .unwrap() - .contents - .fee_proportional_millionths as u64, - ) - .map(|prop_fee| prop_fee / 1_000_000) - .and_then(|prop_fee| { - prop_fee.checked_add( - update_opt.as_ref().unwrap().contents.fee_base_msat - as u64, - ) - }) - .map(|fee_msats| route_hop.fee_msat >= fee_msats) - .unwrap_or(false) - }, - 13 => { - update_opt.is_ok() - && route_hop.cltv_expiry_delta as u16 - >= update_opt.as_ref().unwrap().contents.cltv_expiry_delta - }, - 14 => false, // expiry_too_soon; always valid? - 20 => update_opt.as_ref().unwrap().contents.flags & 2 == 0, - _ => false, // unknown error code; take channel_update as valid - }; - if is_chan_update_invalid { - // This probably indicates the node which forwarded - // to the node in question corrupted something. - network_update = Some(NetworkUpdate::ChannelFailure { - short_channel_id: route_hop.short_channel_id, - is_permanent: true, - }); - } else { - if let Ok(chan_update) = update_opt { - // Make sure the ChannelUpdate contains the expected - // short channel id. - if failing_route_hop.short_channel_id - == chan_update.contents.short_channel_id - { - short_channel_id = Some(failing_route_hop.short_channel_id); - } else { - log_info!(logger, "Node provided a channel_update for which it was not authoritative, ignoring."); - } - network_update = - Some(NetworkUpdate::ChannelUpdateMessage { msg: chan_update }) - } else { - // The node in question intentionally encoded a 0-length channel update. This is - // likely due to https://github.com/ElementsProject/lightning/issues/6200. - short_channel_id = Some(failing_route_hop.short_channel_id); - network_update = Some(NetworkUpdate::ChannelFailure { - short_channel_id: failing_route_hop.short_channel_id, - is_permanent: false, - }); - } - }; - } else { - // If the channel_update had a non-zero length (i.e. was - // present) but we couldn't read it, treat it as a total - // node failure. - log_info!( - logger, - "Failed to read a channel_update of len {} in an onion", - update_slice.len() - ); - } + network_update = Some(NetworkUpdate::ChannelFailure { + short_channel_id: failing_route_hop.short_channel_id, + is_permanent: false, + }); + short_channel_id = Some(failing_route_hop.short_channel_id); } } if network_update.is_none() { diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index d19928fa1fb..448dd213dad 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -23,7 +23,7 @@ use crate::events::{MessageSendEvent, MessageSendEventsProvider}; use crate::ln::types::ChannelId; use crate::ln::features::{InitFeatures, NodeFeatures}; use crate::ln::msgs; -use crate::ln::msgs::{ChannelMessageHandler, LightningError, SocketAddress, OnionMessageHandler, RoutingMessageHandler}; +use crate::ln::msgs::{ChannelMessageHandler, Init, LightningError, SocketAddress, OnionMessageHandler, RoutingMessageHandler}; use crate::util::ser::{VecWriter, Writeable, Writer}; use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor, NextNoiseStep, MessageBuf, MSG_BUF_ALLOC_SIZE}; use crate::ln::wire; @@ -79,6 +79,16 @@ pub trait CustomMessageHandler: wire::CustomMessageReader { /// connection to the node exists, then the message is simply not sent. fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)>; + /// Indicates a peer disconnected. + fn peer_disconnected(&self, their_node_id: &PublicKey); + + /// Handle a peer connecting. + /// + /// May return an `Err(())` if the features the peer supports are not sufficient to communicate + /// with us. Implementors should be somewhat conservative about doing so, however, as other + /// message handlers may still wish to communicate with this peer. + fn peer_connected(&self, their_node_id: &PublicKey, msg: &Init, inbound: bool) -> Result<(), ()>; + /// Gets the node feature flags which this handler itself supports. All available handlers are /// queried similarly and their feature flags are OR'd together to form the [`NodeFeatures`] /// which are broadcasted in our [`NodeAnnouncement`] message. @@ -190,6 +200,10 @@ impl CustomMessageHandler for IgnoringMessageHandler { fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> { Vec::new() } + fn peer_disconnected(&self, _their_node_id: &PublicKey) {} + + fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> { Ok(()) } + fn provided_node_features(&self) -> NodeFeatures { NodeFeatures::empty() } fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures { @@ -1680,6 +1694,10 @@ impl Vec<(PublicKey, Self::CustomMessage)> { Vec::new() } + + fn peer_disconnected(&self, _their_node_id: &PublicKey) {} + + fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> { Ok(()) } + fn provided_node_features(&self) -> NodeFeatures { NodeFeatures::empty() } fn provided_init_features(&self, _: &PublicKey) -> InitFeatures { diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index eb4a837feb6..ee49d00e99d 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -162,7 +162,7 @@ for OnionMessenger where /// # }) /// # } /// # fn create_blinded_paths( -/// # &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1 +/// # &self, _recipient: PublicKey, _peers: Vec, _secp_ctx: &Secp256k1 /// # ) -> Result, ()> { /// # unreachable!() /// # } @@ -426,11 +426,43 @@ pub trait MessageRouter { fn create_blinded_paths< T: secp256k1::Signing + secp256k1::Verification >( - &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, ) -> Result, ()>; + + /// Creates compact [`BlindedPath`]s to the `recipient` node. The nodes in `peers` are assumed + /// to be direct peers with the `recipient`. + /// + /// Compact blinded paths use short channel ids instead of pubkeys for a smaller serialization, + /// which is beneficial when a QR code is used to transport the data. The SCID is passed using a + /// [`ForwardNode`] but may be `None` for graceful degradation. + /// + /// Implementations using additional intermediate nodes are responsible for using a + /// [`ForwardNode`] with `Some` short channel id, if possible. Similarly, implementations should + /// call [`BlindedPath::use_compact_introduction_node`]. + /// + /// The provided implementation simply delegates to [`MessageRouter::create_blinded_paths`], + /// ignoring the short channel ids. + fn create_compact_blinded_paths< + T: secp256k1::Signing + secp256k1::Verification + >( + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + ) -> Result, ()> { + let peers = peers + .into_iter() + .map(|ForwardNode { node_id, short_channel_id: _ }| node_id) + .collect(); + self.create_blinded_paths(recipient, peers, secp_ctx) + } } /// A [`MessageRouter`] that can only route to a directly connected [`Destination`]. +/// +/// # Privacy +/// +/// Creating [`BlindedPath`]s may affect privacy since, if a suitable path cannot be found, it will +/// create a one-hop path using the recipient as the introduction node if it is a announced node. +/// Otherwise, there is no way to find a path to the introduction node in order to send a message, +/// and thus an `Err` is returned. pub struct DefaultMessageRouter>, L: Deref, ES: Deref> where L::Target: Logger, @@ -449,50 +481,12 @@ where pub fn new(network_graph: G, entropy_source: ES) -> Self { Self { network_graph, entropy_source } } -} - -impl>, L: Deref, ES: Deref> MessageRouter for DefaultMessageRouter -where - L::Target: Logger, - ES::Target: EntropySource, -{ - fn find_path( - &self, sender: PublicKey, peers: Vec, mut destination: Destination - ) -> Result { - let network_graph = self.network_graph.deref().read_only(); - destination.resolve(&network_graph); - - let first_node = match destination.first_node() { - Some(first_node) => first_node, - None => return Err(()), - }; - - if peers.contains(&first_node) || sender == first_node { - Ok(OnionMessagePath { - intermediate_nodes: vec![], destination, first_node_addresses: None - }) - } else { - let node_details = network_graph - .node(&NodeId::from_pubkey(&first_node)) - .and_then(|node_info| node_info.announcement_info.as_ref()) - .map(|announcement_info| (announcement_info.features(), announcement_info.addresses())); - - match node_details { - Some((features, addresses)) if features.supports_onion_messages() && addresses.len() > 0 => { - let first_node_addresses = Some(addresses.clone()); - Ok(OnionMessagePath { - intermediate_nodes: vec![], destination, first_node_addresses - }) - }, - _ => Err(()), - } - } - } - fn create_blinded_paths< + fn create_blinded_paths_from_iter< + I: Iterator, T: secp256k1::Signing + secp256k1::Verification >( - &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + &self, recipient: PublicKey, peers: I, secp_ctx: &Secp256k1, compact_paths: bool ) -> Result, ()> { // Limit the number of blinded paths that are computed. const MAX_PATHS: usize = 3; @@ -505,7 +499,7 @@ where let is_recipient_announced = network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)); - let mut peer_info = peers.into_iter() + let mut peer_info = peers // Limit to peers with announced channels .filter_map(|peer| network_graph @@ -540,14 +534,75 @@ where } }, }?; - for path in &mut paths { - path.use_compact_introduction_node(&network_graph); + + if compact_paths { + for path in &mut paths { + path.use_compact_introduction_node(&network_graph); + } } Ok(paths) } } +impl>, L: Deref, ES: Deref> MessageRouter for DefaultMessageRouter +where + L::Target: Logger, + ES::Target: EntropySource, +{ + fn find_path( + &self, sender: PublicKey, peers: Vec, mut destination: Destination + ) -> Result { + let network_graph = self.network_graph.deref().read_only(); + destination.resolve(&network_graph); + + let first_node = match destination.first_node() { + Some(first_node) => first_node, + None => return Err(()), + }; + + if peers.contains(&first_node) || sender == first_node { + Ok(OnionMessagePath { + intermediate_nodes: vec![], destination, first_node_addresses: None + }) + } else { + let node_details = network_graph + .node(&NodeId::from_pubkey(&first_node)) + .and_then(|node_info| node_info.announcement_info.as_ref()) + .map(|announcement_info| (announcement_info.features(), announcement_info.addresses())); + + match node_details { + Some((features, addresses)) if features.supports_onion_messages() && addresses.len() > 0 => { + let first_node_addresses = Some(addresses.clone()); + Ok(OnionMessagePath { + intermediate_nodes: vec![], destination, first_node_addresses + }) + }, + _ => Err(()), + } + } + } + + fn create_blinded_paths< + T: secp256k1::Signing + secp256k1::Verification + >( + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + ) -> Result, ()> { + let peers = peers + .into_iter() + .map(|node_id| ForwardNode { node_id, short_channel_id: None }); + self.create_blinded_paths_from_iter(recipient, peers, secp_ctx, false) + } + + fn create_compact_blinded_paths< + T: secp256k1::Signing + secp256k1::Verification + >( + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + ) -> Result, ()> { + self.create_blinded_paths_from_iter(recipient, peers.into_iter(), secp_ctx, true) + } +} + /// A path for sending an [`OnionMessage`]. #[derive(Clone)] pub struct OnionMessagePath { @@ -1081,10 +1136,7 @@ where let peers = self.message_recipients.lock().unwrap() .iter() .filter(|(_, peer)| matches!(peer, OnionMessageRecipient::ConnectedPeer(_))) - .map(|(node_id, _ )| ForwardNode { - node_id: *node_id, - short_channel_id: None, - }) + .map(|(node_id, _ )| *node_id) .collect::>(); self.message_router diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 25ee1b97ffd..c7908d0040c 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -12,39 +12,39 @@ use bitcoin::amount::Amount; use bitcoin::blockdata::constants::ChainHash; +use bitcoin::secp256k1; use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE; -use bitcoin::secp256k1::{PublicKey, Verification}; use bitcoin::secp256k1::Secp256k1; -use bitcoin::secp256k1; +use bitcoin::secp256k1::{PublicKey, Verification}; use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::hashes::Hash; use bitcoin::network::Network; use crate::events::{MessageSendEvent, MessageSendEventsProvider}; -use crate::ln::types::ChannelId; -use crate::ln::features::{ChannelFeatures, NodeFeatures, InitFeatures}; -use crate::ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, SocketAddress, MAX_VALUE_MSAT}; -use crate::ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, GossipTimestampFilter}; -use crate::ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, ReplyShortChannelIdsEnd}; +use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; use crate::ln::msgs; +use crate::ln::msgs::{ChannelAnnouncement, ChannelUpdate, GossipTimestampFilter, NodeAnnouncement}; +use crate::ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, SocketAddress, MAX_VALUE_MSAT}; +use crate::ln::msgs::{QueryChannelRange, QueryShortChannelIds, ReplyChannelRange, ReplyShortChannelIdsEnd}; +use crate::ln::types::ChannelId; use crate::routing::utxo::{self, UtxoLookup, UtxoResolver}; -use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, MaybeReadable}; -use crate::util::logger::{Logger, Level}; +use crate::util::indexed_map::{Entry as IndexedMapEntry, IndexedMap}; +use crate::util::logger::{Level, Logger}; use crate::util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK}; +use crate::util::ser::{MaybeReadable, Readable, ReadableArgs, RequiredWrapper, Writeable, Writer}; use crate::util::string::PrintableString; -use crate::util::indexed_map::{IndexedMap, Entry as IndexedMapEntry}; use crate::io; use crate::io_extras::{copy, sink}; use crate::prelude::*; -use core::{cmp, fmt}; -use crate::sync::{RwLock, RwLockReadGuard, LockTestExt}; -#[cfg(feature = "std")] -use core::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::Mutex; +use crate::sync::{LockTestExt, RwLock, RwLockReadGuard}; use core::ops::{Bound, Deref}; use core::str::FromStr; +#[cfg(feature = "std")] +use core::sync::atomic::{AtomicUsize, Ordering}; +use core::{cmp, fmt}; #[cfg(feature = "std")] use std::time::{SystemTime, UNIX_EPOCH}; @@ -219,12 +219,6 @@ pub struct ReadOnlyNetworkGraph<'a> { /// [BOLT #4]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md #[derive(Clone, Debug, PartialEq, Eq)] pub enum NetworkUpdate { - /// An error indicating a `channel_update` messages should be applied via - /// [`NetworkGraph::update_channel`]. - ChannelUpdateMessage { - /// The update to apply via [`NetworkGraph::update_channel`]. - msg: ChannelUpdate, - }, /// An error indicating that a channel failed to route a payment, which should be applied via /// [`NetworkGraph::channel_failed_permanent`] if permanent. ChannelFailure { @@ -245,19 +239,69 @@ pub enum NetworkUpdate { } } -impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate, - (0, ChannelUpdateMessage) => { - (0, msg, required), - }, - (2, ChannelFailure) => { - (0, short_channel_id, required), - (2, is_permanent, required), - }, - (4, NodeFailure) => { - (0, node_id, required), - (2, is_permanent, required), - }, -); +impl Writeable for NetworkUpdate { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { + match self { + Self::ChannelFailure { short_channel_id, is_permanent } => { + 2u8.write(writer)?; + write_tlv_fields!(writer, { + (0, short_channel_id, required), + (2, is_permanent, required), + }); + }, + Self::NodeFailure { node_id, is_permanent } => { + 4u8.write(writer)?; + write_tlv_fields!(writer, { + (0, node_id, required), + (2, is_permanent, required), + }); + } + } + Ok(()) + } +} + +impl MaybeReadable for NetworkUpdate { + fn read(reader: &mut R) -> Result, DecodeError> { + let id: u8 = Readable::read(reader)?; + match id { + 0 => { + // 0 was previously used for network updates containing a channel update, subsequently + // removed in LDK version 0.0.124. + let mut msg: RequiredWrapper = RequiredWrapper(None); + read_tlv_fields!(reader, { + (0, msg, required), + }); + Ok(Some(Self::ChannelFailure { + short_channel_id: msg.0.unwrap().contents.short_channel_id, + is_permanent: false + })) + }, + 2 => { + _init_and_read_len_prefixed_tlv_fields!(reader, { + (0, short_channel_id, required), + (2, is_permanent, required), + }); + Ok(Some(Self::ChannelFailure { + short_channel_id: short_channel_id.0.unwrap(), + is_permanent: is_permanent.0.unwrap(), + })) + }, + 4 => { + _init_and_read_len_prefixed_tlv_fields!(reader, { + (0, node_id, required), + (2, is_permanent, required), + }); + Ok(Some(Self::NodeFailure { + node_id: node_id.0.unwrap(), + is_permanent: is_permanent.0.unwrap(), + })) + } + t if t % 2 == 0 => Err(DecodeError::UnknownRequiredFeature), + _ => Ok(None), + } + } +} /// Receives and validates network updates from peers, /// stores authentic and relevant data as a network graph. @@ -354,19 +398,10 @@ where U::Target: UtxoLookup, L::Target: Logger impl NetworkGraph where L::Target: Logger { /// Handles any network updates originating from [`Event`]s. - // - /// Note that this will skip applying any [`NetworkUpdate::ChannelUpdateMessage`] to avoid - /// leaking possibly identifying information of the sender to the public network. /// /// [`Event`]: crate::events::Event pub fn handle_network_update(&self, network_update: &NetworkUpdate) { match *network_update { - NetworkUpdate::ChannelUpdateMessage { ref msg } => { - let short_channel_id = msg.contents.short_channel_id; - let is_enabled = msg.contents.flags & (1 << 1) != (1 << 1); - let status = if is_enabled { "enabled" } else { "disabled" }; - log_debug!(self.logger, "Skipping application of a channel update from a payment failure. Channel {} is {}.", short_channel_id, status); - }, NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } => { if is_permanent { log_debug!(self.logger, "Removing channel graph entry for {} due to a payment failure.", short_channel_id); @@ -2681,8 +2716,7 @@ pub(crate) mod tests { let short_channel_id; { - // Check we won't apply an update via `handle_network_update` for privacy reasons, but - // can continue fine if we manually apply it. + // Check that we can manually apply a channel update. let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); short_channel_id = valid_channel_announcement.contents.short_channel_id; let chain_source: Option<&test_utils::TestChainSource> = None; @@ -2690,14 +2724,10 @@ pub(crate) mod tests { assert!(network_graph.read_only().channels().get(&short_channel_id).is_some()); let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx); - assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none()); - - network_graph.handle_network_update(&NetworkUpdate::ChannelUpdateMessage { - msg: valid_channel_update.clone(), - }); assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none()); network_graph.update_channel(&valid_channel_update).unwrap(); + assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some()); } // Non-permanent failure doesn't touch the channel at all diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index e1b5b655719..5b202604e37 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -36,6 +36,11 @@ use core::{cmp, fmt}; use core::ops::Deref; /// A [`Router`] implemented using [`find_route`]. +/// +/// # Privacy +/// +/// Implements [`MessageRouter`] by delegating to [`DefaultMessageRouter`]. See those docs for +/// privacy implications. pub struct DefaultRouter> + Clone, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp> where L::Target: Logger, S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>, @@ -173,10 +178,18 @@ impl< G: Deref> + Clone, L: Deref, ES: Deref, S: Deref, fn create_blinded_paths< T: secp256k1::Signing + secp256k1::Verification > ( - &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, ) -> Result, ()> { self.message_router.create_blinded_paths(recipient, peers, secp_ctx) } + + fn create_compact_blinded_paths< + T: secp256k1::Signing + secp256k1::Verification + > ( + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + ) -> Result, ()> { + self.message_router.create_compact_blinded_paths(recipient, peers, secp_ctx) + } } /// A trait defining behavior for routing a payment. diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index a5363d32c76..f6616a8e5d2 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -250,10 +250,18 @@ impl<'a> MessageRouter for TestRouter<'a> { fn create_blinded_paths< T: secp256k1::Signing + secp256k1::Verification >( - &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, ) -> Result, ()> { self.router.create_blinded_paths(recipient, peers, secp_ctx) } + + fn create_compact_blinded_paths< + T: secp256k1::Signing + secp256k1::Verification + >( + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + ) -> Result, ()> { + self.router.create_compact_blinded_paths(recipient, peers, secp_ctx) + } } impl<'a> Drop for TestRouter<'a> { @@ -285,10 +293,16 @@ impl<'a> MessageRouter for TestMessageRouter<'a> { } fn create_blinded_paths( - &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, ) -> Result, ()> { self.inner.create_blinded_paths(recipient, peers, secp_ctx) } + + fn create_compact_blinded_paths( + &self, recipient: PublicKey, peers: Vec, secp_ctx: &Secp256k1, + ) -> Result, ()> { + self.inner.create_compact_blinded_paths(recipient, peers, secp_ctx) + } } pub struct OnlyReadsKeysInterface {} diff --git a/rustfmt_excluded_files b/rustfmt_excluded_files index 36d85ef2061..d4317eb0e89 100644 --- a/rustfmt_excluded_files +++ b/rustfmt_excluded_files @@ -1,136 +1,7 @@ ./bench/benches/bench.rs -./fuzz/src/base32.rs -./fuzz/src/bech32_parse.rs -./fuzz/src/bin/base32_target.rs -./fuzz/src/bin/bech32_parse_target.rs -./fuzz/src/bin/bolt11_deser_target.rs -./fuzz/src/bin/chanmon_consistency_target.rs -./fuzz/src/bin/chanmon_deser_target.rs -./fuzz/src/bin/fromstr_to_netaddress_target.rs -./fuzz/src/bin/full_stack_target.rs -./fuzz/src/bin/indexedmap_target.rs -./fuzz/src/bin/invoice_deser_target.rs -./fuzz/src/bin/invoice_request_deser_target.rs -./fuzz/src/bin/msg_accept_channel_target.rs -./fuzz/src/bin/msg_accept_channel_v2_target.rs -./fuzz/src/bin/msg_announcement_signatures_target.rs -./fuzz/src/bin/msg_channel_announcement_target.rs -./fuzz/src/bin/msg_channel_details_target.rs -./fuzz/src/bin/msg_channel_ready_target.rs -./fuzz/src/bin/msg_channel_reestablish_target.rs -./fuzz/src/bin/msg_channel_update_target.rs -./fuzz/src/bin/msg_closing_signed_target.rs -./fuzz/src/bin/msg_commitment_signed_target.rs -./fuzz/src/bin/msg_decoded_onion_error_packet_target.rs -./fuzz/src/bin/msg_error_message_target.rs -./fuzz/src/bin/msg_funding_created_target.rs -./fuzz/src/bin/msg_funding_signed_target.rs -./fuzz/src/bin/msg_gossip_timestamp_filter_target.rs -./fuzz/src/bin/msg_init_target.rs -./fuzz/src/bin/msg_node_announcement_target.rs -./fuzz/src/bin/msg_open_channel_target.rs -./fuzz/src/bin/msg_open_channel_v2_target.rs -./fuzz/src/bin/msg_ping_target.rs -./fuzz/src/bin/msg_pong_target.rs -./fuzz/src/bin/msg_query_channel_range_target.rs -./fuzz/src/bin/msg_query_short_channel_ids_target.rs -./fuzz/src/bin/msg_reply_channel_range_target.rs -./fuzz/src/bin/msg_reply_short_channel_ids_end_target.rs -./fuzz/src/bin/msg_revoke_and_ack_target.rs -./fuzz/src/bin/msg_shutdown_target.rs -./fuzz/src/bin/msg_splice_ack_target.rs -./fuzz/src/bin/msg_splice_locked_target.rs -./fuzz/src/bin/msg_splice_target.rs -./fuzz/src/bin/msg_stfu_target.rs -./fuzz/src/bin/msg_tx_abort_target.rs -./fuzz/src/bin/msg_tx_ack_rbf_target.rs -./fuzz/src/bin/msg_tx_add_input_target.rs -./fuzz/src/bin/msg_tx_add_output_target.rs -./fuzz/src/bin/msg_tx_complete_target.rs -./fuzz/src/bin/msg_tx_init_rbf_target.rs -./fuzz/src/bin/msg_tx_remove_input_target.rs -./fuzz/src/bin/msg_tx_remove_output_target.rs -./fuzz/src/bin/msg_tx_signatures_target.rs -./fuzz/src/bin/msg_update_add_htlc_target.rs -./fuzz/src/bin/msg_update_fail_htlc_target.rs -./fuzz/src/bin/msg_update_fail_malformed_htlc_target.rs -./fuzz/src/bin/msg_update_fee_target.rs -./fuzz/src/bin/msg_update_fulfill_htlc_target.rs -./fuzz/src/bin/offer_deser_target.rs -./fuzz/src/bin/onion_hop_data_target.rs -./fuzz/src/bin/onion_message_target.rs -./fuzz/src/bin/peer_crypt_target.rs -./fuzz/src/bin/process_network_graph_target.rs -./fuzz/src/bin/refund_deser_target.rs -./fuzz/src/bin/router_target.rs -./fuzz/src/bin/zbase32_target.rs ./fuzz/src/chanmon_consistency.rs -./fuzz/src/chanmon_deser.rs -./fuzz/src/fromstr_to_netaddress.rs ./fuzz/src/full_stack.rs -./fuzz/src/indexedmap.rs -./fuzz/src/invoice_deser.rs -./fuzz/src/invoice_request_deser.rs ./fuzz/src/lib.rs -./fuzz/src/msg_targets/mod.rs -./fuzz/src/msg_targets/msg_accept_channel.rs -./fuzz/src/msg_targets/msg_accept_channel_v2.rs -./fuzz/src/msg_targets/msg_announcement_signatures.rs -./fuzz/src/msg_targets/msg_channel_announcement.rs -./fuzz/src/msg_targets/msg_channel_details.rs -./fuzz/src/msg_targets/msg_channel_ready.rs -./fuzz/src/msg_targets/msg_channel_reestablish.rs -./fuzz/src/msg_targets/msg_channel_update.rs -./fuzz/src/msg_targets/msg_closing_signed.rs -./fuzz/src/msg_targets/msg_commitment_signed.rs -./fuzz/src/msg_targets/msg_decoded_onion_error_packet.rs -./fuzz/src/msg_targets/msg_error_message.rs -./fuzz/src/msg_targets/msg_funding_created.rs -./fuzz/src/msg_targets/msg_funding_signed.rs -./fuzz/src/msg_targets/msg_gossip_timestamp_filter.rs -./fuzz/src/msg_targets/msg_init.rs -./fuzz/src/msg_targets/msg_node_announcement.rs -./fuzz/src/msg_targets/msg_open_channel.rs -./fuzz/src/msg_targets/msg_open_channel_v2.rs -./fuzz/src/msg_targets/msg_ping.rs -./fuzz/src/msg_targets/msg_pong.rs -./fuzz/src/msg_targets/msg_query_channel_range.rs -./fuzz/src/msg_targets/msg_query_short_channel_ids.rs -./fuzz/src/msg_targets/msg_reply_channel_range.rs -./fuzz/src/msg_targets/msg_reply_short_channel_ids_end.rs -./fuzz/src/msg_targets/msg_revoke_and_ack.rs -./fuzz/src/msg_targets/msg_shutdown.rs -./fuzz/src/msg_targets/msg_splice.rs -./fuzz/src/msg_targets/msg_splice_ack.rs -./fuzz/src/msg_targets/msg_splice_locked.rs -./fuzz/src/msg_targets/msg_stfu.rs -./fuzz/src/msg_targets/msg_tx_abort.rs -./fuzz/src/msg_targets/msg_tx_ack_rbf.rs -./fuzz/src/msg_targets/msg_tx_add_input.rs -./fuzz/src/msg_targets/msg_tx_add_output.rs -./fuzz/src/msg_targets/msg_tx_complete.rs -./fuzz/src/msg_targets/msg_tx_init_rbf.rs -./fuzz/src/msg_targets/msg_tx_remove_input.rs -./fuzz/src/msg_targets/msg_tx_remove_output.rs -./fuzz/src/msg_targets/msg_tx_signatures.rs -./fuzz/src/msg_targets/msg_update_add_htlc.rs -./fuzz/src/msg_targets/msg_update_fail_htlc.rs -./fuzz/src/msg_targets/msg_update_fail_malformed_htlc.rs -./fuzz/src/msg_targets/msg_update_fee.rs -./fuzz/src/msg_targets/msg_update_fulfill_htlc.rs -./fuzz/src/msg_targets/msg_warning_message.rs -./fuzz/src/msg_targets/utils.rs -./fuzz/src/offer_deser.rs -./fuzz/src/onion_hop_data.rs -./fuzz/src/onion_message.rs -./fuzz/src/peer_crypt.rs -./fuzz/src/process_network_graph.rs -./fuzz/src/refund_deser.rs -./fuzz/src/router.rs -./fuzz/src/utils/mod.rs -./fuzz/src/utils/test_logger.rs -./fuzz/src/utils/test_persister.rs -./fuzz/src/zbase32.rs ./lightning-background-processor/src/lib.rs ./lightning-block-sync/src/convert.rs ./lightning-block-sync/src/gossip.rs @@ -159,12 +30,6 @@ ./lightning-rapid-gossip-sync/src/error.rs ./lightning-rapid-gossip-sync/src/lib.rs ./lightning-rapid-gossip-sync/src/processing.rs -./lightning-transaction-sync/src/common.rs -./lightning-transaction-sync/src/electrum.rs -./lightning-transaction-sync/src/error.rs -./lightning-transaction-sync/src/esplora.rs -./lightning-transaction-sync/src/lib.rs -./lightning-transaction-sync/tests/integration_tests.rs ./lightning/src/blinded_path/message.rs ./lightning/src/blinded_path/mod.rs ./lightning/src/blinded_path/payment.rs