Merge pull request #1324 from valentinewallace/2022-02-phantom-followup
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Mon, 28 Feb 2022 18:16:21 +0000 (18:16 +0000)
committerGitHub <noreply@github.com>
Mon, 28 Feb 2022 18:16:21 +0000 (18:16 +0000)
#1199 Followup

57 files changed:
fuzz/Cargo.toml
fuzz/src/bin/chanmon_consistency_target.rs
fuzz/src/bin/chanmon_deser_target.rs
fuzz/src/bin/full_stack_target.rs
fuzz/src/bin/msg_accept_channel_target.rs
fuzz/src/bin/msg_announcement_signatures_target.rs
fuzz/src/bin/msg_channel_announcement_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_locked_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_onion_hop_data_target.rs
fuzz/src/bin/msg_open_channel_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_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/peer_crypt_target.rs
fuzz/src/bin/router_target.rs
fuzz/src/bin/target_template.txt
fuzz/src/bin/zbase32_target.rs
lightning-block-sync/Cargo.toml
lightning-invoice/fuzz/Cargo.toml
lightning-net-tokio/Cargo.toml
lightning-persister/src/lib.rs
lightning/Cargo.toml
lightning/src/chain/chainmonitor.rs
lightning/src/chain/channelmonitor.rs
lightning/src/lib.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/mod.rs
lightning/src/ln/msgs.rs
lightning/src/routing/router.rs
lightning/src/util/chacha20.rs
lightning/src/util/chacha20poly1305rfc.rs
lightning/src/util/fuzz_wrappers.rs
lightning/src/util/mod.rs

index 3b6d027df321e1c3ff50a73b51d2a0932aa75b31..bc1f0a479f1cb074937d689b33c398c73d2f6420 100644 (file)
@@ -5,7 +5,7 @@ authors = ["Automatically generated"]
 publish = false
 # Because the function is unused it gets dropped before we link lightning, so
 # we have to duplicate build.rs here. Note that this is only required for
-# fuzztarget mode.
+# fuzzing mode.
 
 [package.metadata]
 cargo-fuzz = true
@@ -18,7 +18,7 @@ stdin_fuzz = []
 
 [dependencies]
 afl = { version = "0.4", optional = true }
-lightning = { path = "../lightning", features = ["fuzztarget"] }
+lightning = { path = "../lightning", features = ["regex"] }
 bitcoin = { version = "0.27", features = ["fuzztarget", "secp-lowmemory"] }
 hex = "0.3"
 honggfuzz = { version = "0.5", optional = true }
index c480b3d17c133d5bcfc45d87d1feb93e35bdbb92..25fe23b58caeb4e1fd5c29fd8894833ec70255ef 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::chanmon_consistency::*;
 
index 8b57874cf6c6e37adda6892a30ad081d47492d54..9e9b17626768388ed6d4fefa369a40c09c2b3769 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::chanmon_deser::*;
 
index 7dae655316b08e63ba2606f2556d298d53e57052..bebb7fdcd81ebdd2f558154b661a4a7c95a77f35 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::full_stack::*;
 
index d28895a0fe97dd1d6f6244ed91e9526794c1eedd..0018d09abd3986af33219eb422b52768cacd15a3 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_accept_channel::*;
 
index dcfc006eb0ce41ea98751a9f2f8471750c4d17e5..593908f41751904d7dd8e36c299be5a9ae5507db 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_announcement_signatures::*;
 
index 0efc0b41fc6ec12add2ee2e3b94bf3873705071f..f9946314254b7c5d9faa9c06d15464ee52d16bbf 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_channel_announcement::*;
 
index 0111d2b27544160979ea8275d111ec2be082ab8d..ba1a76d9941eab3e1b596afc619d1395f1d3b83e 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_channel_reestablish::*;
 
index 4bfb9860c8c302d4ae0488f3acd207a049537ceb..0198ddc0092e4fe60962c58b484b48186c7adb47 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_channel_update::*;
 
index 12dbb31cd20c21fc99965ad98b57c5264af3ffc7..abd69fc95029f3e3b689a815b4035a18e7ea1924 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_closing_signed::*;
 
index 407f0288cf56806e864d6b8a0e4f48851f2712b1..0324301fea79b554e4d50d8e3c7e32ae26c2b8b0 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_commitment_signed::*;
 
index 9f76e69679adeb210fd60bcb4723238c7d6c2f93..1f99bab2bbb82675937001e5cbb192752c9d66b8 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_decoded_onion_error_packet::*;
 
index dc418c93d6920b8590445badf807aa3e6af841bb..8609bf65ada5f783660b3807e455625d92d28d9b 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_error_message::*;
 
index 6fb87c4082a98ec34e6dd0b67057f2684e6e78ad..51ac425d7e5899756f6aa2ae28bea8ae3f812c70 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_funding_created::*;
 
index 7b8f21f8a0b199140241b9d236862149d5c9c451..986f7f89856833eef01f3941e2a2131f473c9b67 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_funding_locked::*;
 
index ea05acdcee1425cae380f116699f2a12365a2cf4..bfee1f5aee934cfe4dd2084231d4ea9beda37cb8 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_funding_signed::*;
 
index 1aba4e3fefe37f73497a0583d93607125853df5e..aa94f2001cfaab1bd5782c4d75fb6977a2a51b8f 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_gossip_timestamp_filter::*;
 
index dd7b197a42ee0cb74001cfbe91676a71174bfb4f..342ceaf3f796b5c4378c3637b226f10c14800157 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_init::*;
 
index 63b23bd669d786e3c3207888895a343c71788e97..32012633747ed1ce9d6bd3f9d16697a0d20a3580 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_node_announcement::*;
 
index 493817c7eea62f656efe955445304becc3cb5717..ae21e9bd9cfdca7fe35c0a0fa2defadc49fdb49c 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_onion_hop_data::*;
 
index d6c9de48f287b0168cf0e96a0aa482060f5d62c5..cee4c0d07efedd4c4342adf9fe9a4ebb98482f44 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_open_channel::*;
 
index e739cd58052413645943eb07811a4b2e3bb01b68..19e8abe24f9a7bdd19d2f2be50beca13a2f9c0fb 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_ping::*;
 
index 73113472c33ffff416a736f901609d39e552df3a..429550bd1864df484f24e6e0e7376be3328dc66b 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_pong::*;
 
index db22fa525b82a72beb076fd048d4bbcbd5c1a7b7..c2ce1fd5f52195130806f998d765ea08e8a70d7e 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_query_channel_range::*;
 
index 6c470e3b12ed6ce68227d9a97ab3eaba363a87b6..af3d37065e5655f58ac45337ecc0a6476ca318b6 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_query_short_channel_ids::*;
 
index 68651347b6f7f86640b65d8f3574eb4128927655..0cddbcaf83de9a796f5c7bd680e5258252c754a0 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_reply_channel_range::*;
 
index de3e9f1cce3ae49e9736dd2c968d436a793ec89e..d802299b28102e6ca62620857d0e642916d878cd 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_reply_short_channel_ids_end::*;
 
index e0f781986d46a916013659661cd076457f178c4b..d72d63cc32723eab28d05dcc86a98bc3fa9eb312 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_revoke_and_ack::*;
 
index 6220fc92803b473dd0d10d8d2aa1d71929cd9fb9..1959a8cfa858c9fff0558779fef9710b23ee74eb 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_shutdown::*;
 
index dffdb830939d04f8aff0cfc13279432a497ff053..47faa7b1bbb989b1cb379fbddface77d5bdd4bdd 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_update_add_htlc::*;
 
index 2828b396ad461d899856317b0a54f97ba7fd1fa2..0c47190f72ced5ff645d8c2592190bfaf5c22d47 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_update_fail_htlc::*;
 
index 8bf82a517cf7d0bbf656fd4b7c794d3a6d1207c4..917fad9ce600d4f315d2cf968b99fdc7349f7238 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_update_fail_malformed_htlc::*;
 
index e9e63f28a8cdc3229990bca3645efdaa70243ae2..f7baec58a170141d9b0d7c7ed5d986fd65c10b6c 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_update_fee::*;
 
index 4820b0adf9fa3d4e50e4a8220340999bd6a67fb4..23197b38eec8704e4faee85eb04e988131e4d8fa 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::msg_targets::msg_update_fulfill_htlc::*;
 
index 8f62626983c0c4a0733856535d89e2953b620fad..c7cbe8c2c2f30389e34265176cca430d0e2ef19c 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::peer_crypt::*;
 
index 4df8b2a0065e430fa3994beaaef68c825bba78c1..2082f115ae0572f39b9662f6cf64b762d4e9078d 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::router::*;
 
index 7db3bc80b9b139e47fbb44fa50413cf733b0c340..7b0ec0eebce154ee3454201b688024f50e2885d3 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::TARGET_MOD::*;
 
index 0b9d629151d626fc5b2420d175c7250231533ad6..1553d6d2b66d60cab4cc899e0f7494abfccf6e5b 100644 (file)
@@ -12,6 +12,9 @@
 
 #![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
 
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
 extern crate lightning_fuzz;
 use lightning_fuzz::zbase32::*;
 
index d12428409f7676ce18a0dc549b75cbf945e40c62..0a395e8b99da0f557f14a0379494faa1d36242b3 100644 (file)
@@ -22,4 +22,4 @@ serde_json = { version = "1.0", optional = true }
 chunked_transfer = { version = "1.4", optional = true }
 
 [dev-dependencies]
-tokio = { version = "1.0", features = [ "macros", "rt" ] }
+tokio = { version = "~1.14", features = [ "macros", "rt" ] }
index eb583a41c7e87dd4e73cfb27b2e26ac2c1476b38..d741864aea2ec8d55a824f725d8e875e9a9d6c0c 100644 (file)
@@ -14,7 +14,8 @@ honggfuzz_fuzz = ["honggfuzz"]
 [dependencies]
 honggfuzz = { version = "0.5", optional = true }
 afl = { version = "0.4", optional = true }
-lightning-invoice = { path = ".."}
+lightning-invoice = { path = ".." }
+lightning = { path = "../../lightning", features = ["regex"] }
 bech32 = "0.8"
 
 # Prevent this from interfering with workspaces
index 185e5d128d5e0e0a2fdc853bf7cc939f1412f90d..370e3cc4261d0eaa3fc11ccc34a4d25e4d683e01 100644 (file)
@@ -16,4 +16,4 @@ lightning = { version = "0.0.104", path = "../lightning" }
 tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net", "time" ] }
 
 [dev-dependencies]
-tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] }
+tokio = { version = "~1.14", features = [ "io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] }
index 558f4b8fe3cee9d56b75b2230f203ccca6608e9c..b8212f0fc705b3bac8e6925df3f0a1deb375116b 100644 (file)
@@ -122,6 +122,12 @@ impl FilesystemPersister {
                                        "Invalid ChannelMonitor file name",
                                ));
                        }
+                       if filename.unwrap().ends_with(".tmp") {
+                               // If we were in the middle of committing an new update and crashed, it should be
+                               // safe to ignore the update - we should never have returned to the caller and
+                               // irrevocably committed to the new state in any way.
+                               continue;
+                       }
 
                        let txid = Txid::from_hex(filename.unwrap().split_at(64).0);
                        if txid.is_err() {
index c5d0c5564afb9249784276c2df2567a57ebcf084..5f6f2ef655da402c77c132dd1d8061c9658ece9f 100644 (file)
@@ -11,7 +11,6 @@ Still missing tons of error-handling. See GitHub issues for suggested projects i
 """
 
 [features]
-fuzztarget = ["bitcoin/fuzztarget", "regex"]
 # Internal test utilities exposed to other repo crates
 _test_utils = ["hex", "regex", "bitcoin/bitcoinconsensus"]
 # Unlog messages superior at targeted level.
index 05f8832917603095cfc72693a2f4bd1034bf0092..19095fa2375a6d8c3a52a61262736af9ac2fd61c 100644 (file)
@@ -474,7 +474,7 @@ where C::Target: chain::Filter,
        /// This wrapper avoids having to update some of our tests for now as they assume the direct
        /// chain::Watch API wherein we mark a monitor fully-updated by just calling
        /// channel_monitor_updated once with the highest ID.
-       #[cfg(any(test, feature = "fuzztarget"))]
+       #[cfg(any(test, fuzzing))]
        pub fn force_channel_monitor_updated(&self, funding_txo: OutPoint, monitor_update_id: u64) {
                self.pending_monitor_events.lock().unwrap().push(MonitorEvent::UpdateCompleted {
                        funding_txo,
@@ -482,7 +482,7 @@ where C::Target: chain::Filter,
                });
        }
 
-       #[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
+       #[cfg(any(test, fuzzing, feature = "_test_utils"))]
        pub fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
                use util::events::EventsProvider;
                let events = core::cell::RefCell::new(Vec::new());
@@ -630,9 +630,9 @@ where C::Target: chain::Filter,
                                // We should never ever trigger this from within ChannelManager. Technically a
                                // user could use this object with some proxying in between which makes this
                                // possible, but in tests and fuzzing, this should be a panic.
-                               #[cfg(any(test, feature = "fuzztarget"))]
+                               #[cfg(any(test, fuzzing))]
                                panic!("ChannelManager generated a channel update for a channel that was not yet registered!");
-                               #[cfg(not(any(test, feature = "fuzztarget")))]
+                               #[cfg(not(any(test, fuzzing)))]
                                Err(ChannelMonitorUpdateErr::PermanentFailure)
                        },
                        Some(monitor_state) => {
index e6f6ceda2b0b16f712963843a23fe4a478490f29..96caaad27636acdfe5ebc18044e9a74ff69ce080 100644 (file)
@@ -59,7 +59,7 @@ use sync::Mutex;
 
 /// An update generated by the underlying Channel itself which contains some new information the
 /// ChannelMonitor should be made aware of.
-#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq))]
 #[derive(Clone)]
 #[must_use]
 pub struct ChannelMonitorUpdate {
@@ -441,7 +441,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
 
 );
 
-#[cfg_attr(any(test, feature = "fuzztarget", feature = "_test_utils"), derive(PartialEq))]
+#[cfg_attr(any(test, fuzzing, feature = "_test_utils"), derive(PartialEq))]
 #[derive(Clone)]
 pub(crate) enum ChannelMonitorUpdateStep {
        LatestHolderCommitmentTXInfo {
@@ -711,9 +711,9 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
 /// Transaction outputs to watch for on-chain spends.
 pub type TransactionOutputs = (Txid, Vec<(u32, TxOut)>);
 
-#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
-/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
-/// underlying object
+#[cfg(any(test, fuzzing, feature = "_test_utils"))]
+/// Used only in testing and fuzzing to check serialization roundtrips don't change the underlying
+/// object
 impl<Signer: Sign> PartialEq for ChannelMonitor<Signer> {
        fn eq(&self, other: &Self) -> bool {
                let inner = self.inner.lock().unwrap();
@@ -722,9 +722,9 @@ impl<Signer: Sign> PartialEq for ChannelMonitor<Signer> {
        }
 }
 
-#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
-/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
-/// underlying object
+#[cfg(any(test, fuzzing, feature = "_test_utils"))]
+/// Used only in testing and fuzzing to check serialization roundtrips don't change the underlying
+/// object
 impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
        fn eq(&self, other: &Self) -> bool {
                if self.latest_update_id != other.latest_update_id ||
index 8fdf63ffad0e7f370359a9a3922490f939d05587..2798f78adf23aa0a52cde63fa86fb30270600b34 100644 (file)
@@ -18,8 +18,8 @@
 //! generated/etc. This makes it a good candidate for tight integration into an existing wallet
 //! instead of having a rather-separate lightning appendage to a wallet.
 
-#![cfg_attr(not(any(test, feature = "fuzztarget", feature = "_test_utils")), deny(missing_docs))]
-#![cfg_attr(not(any(test, feature = "fuzztarget", feature = "_test_utils")), forbid(unsafe_code))]
+#![cfg_attr(not(any(test, fuzzing, feature = "_test_utils")), deny(missing_docs))]
+#![cfg_attr(not(any(test, fuzzing, feature = "_test_utils")), forbid(unsafe_code))]
 #![deny(broken_intra_doc_links)]
 
 // In general, rust is absolutely horrid at supporting users doing things like,
@@ -36,6 +36,9 @@
 #[cfg(not(any(feature = "std", feature = "no-std")))]
 compile_error!("at least one of the `std` or `no-std` features must be enabled");
 
+#[cfg(all(fuzzing, test))]
+compile_error!("Tests will always fail with cfg=fuzzing");
+
 #[macro_use]
 extern crate alloc;
 extern crate bitcoin;
@@ -43,7 +46,7 @@ extern crate bitcoin;
 extern crate core;
 
 #[cfg(any(test, feature = "_test_utils"))] extern crate hex;
-#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] extern crate regex;
+#[cfg(any(test, fuzzing, feature = "_test_utils"))] extern crate regex;
 
 #[cfg(not(feature = "std"))] extern crate core2;
 
index e1661763d5356b052c6c54189f6956b26eb2e005..6dc05c2ef3c09e2fcd5fc16ad8a2ebe2427343d3 100644 (file)
@@ -1251,7 +1251,7 @@ impl CommitmentTransaction {
                                if let &Some(ref b_htlcout) = b {
                                        a_htlcout.cltv_expiry.cmp(&b_htlcout.cltv_expiry)
                                                // Note that due to hash collisions, we have to have a fallback comparison
-                                               // here for fuzztarget mode (otherwise at least chanmon_fail_consistency
+                                               // here for fuzzing mode (otherwise at least chanmon_fail_consistency
                                                // may fail)!
                                                .then(a_htlcout.payment_hash.0.cmp(&b_htlcout.payment_hash.0))
                                // For non-HTLC outputs, if they're copying our SPK we don't really care if we
index fb9213142ae740e4b487786be3e50c7a9268807b..dd9fcbea9a8fa2bf05c21c9cf34c04b5e8698660 100644 (file)
@@ -46,7 +46,7 @@ use io;
 use prelude::*;
 use core::{cmp,mem,fmt};
 use core::ops::Deref;
-#[cfg(any(test, feature = "fuzztarget", debug_assertions))]
+#[cfg(any(test, fuzzing, debug_assertions))]
 use sync::Mutex;
 use bitcoin::hashes::hex::ToHex;
 
@@ -670,9 +670,9 @@ pub(super) struct Channel<Signer: Sign> {
        // `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
        // be, by comparing the cached values to the fee of the tranaction generated by
        // `build_commitment_transaction`.
-       #[cfg(any(test, feature = "fuzztarget"))]
+       #[cfg(any(test, fuzzing))]
        next_local_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
-       #[cfg(any(test, feature = "fuzztarget"))]
+       #[cfg(any(test, fuzzing))]
        next_remote_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
 
        /// lnd has a long-standing bug where, upon reconnection, if the channel is not yet confirmed
@@ -684,7 +684,7 @@ pub(super) struct Channel<Signer: Sign> {
        /// See-also <https://github.com/lightningnetwork/lnd/issues/4006>
        pub workaround_lnd_bug_4006: Option<msgs::FundingLocked>,
 
-       #[cfg(any(test, feature = "fuzztarget"))]
+       #[cfg(any(test, fuzzing))]
        // When we receive an HTLC fulfill on an outbound path, we may immediately fulfill the
        // corresponding HTLC on the inbound path. If, then, the outbound path channel is
        // disconnected and reconnected (before we've exchange commitment_signed and revoke_and_ack
@@ -697,7 +697,7 @@ pub(super) struct Channel<Signer: Sign> {
        channel_type: ChannelTypeFeatures,
 }
 
-#[cfg(any(test, feature = "fuzztarget"))]
+#[cfg(any(test, fuzzing))]
 struct CommitmentTxInfoCached {
        fee: u64,
        total_pending_htlcs: usize,
@@ -940,14 +940,14 @@ impl<Signer: Sign> Channel<Signer> {
 
                        announcement_sigs: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_local_commitment_tx_fee_info_cached: Mutex::new(None),
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
                        // We currently only actually support one channel type, so don't retry with new types
@@ -1245,14 +1245,14 @@ impl<Signer: Sign> Channel<Signer> {
 
                        announcement_sigs: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_local_commitment_tx_fee_info_cached: Mutex::new(None),
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
                        channel_type,
@@ -1650,7 +1650,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
                if pending_idx == core::usize::MAX {
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        // If we failed to find an HTLC to fulfill, make sure it was previously fulfilled and
                        // this is simply a duplicate claim, not previously failed and we lost funds.
                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
@@ -1676,7 +1676,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                if htlc_id_arg == htlc_id {
                                                        // Make sure we don't leave latest_monitor_update_id incremented here:
                                                        self.latest_monitor_update_id -= 1;
-                                                       #[cfg(any(test, feature = "fuzztarget"))]
+                                                       #[cfg(any(test, fuzzing))]
                                                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
                                                        return UpdateFulfillFetch::DuplicateClaim {};
                                                }
@@ -1697,11 +1697,11 @@ impl<Signer: Sign> Channel<Signer> {
                        self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::ClaimHTLC {
                                payment_preimage: payment_preimage_arg, htlc_id: htlc_id_arg,
                        });
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
                        return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
                }
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
 
                {
@@ -1782,7 +1782,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
                if pending_idx == core::usize::MAX {
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        // If we failed to find an HTLC to fail, make sure it was previously fulfilled and this
                        // is simply a duplicate fail, not previously failed and we failed-back too early.
                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
@@ -1795,7 +1795,7 @@ impl<Signer: Sign> Channel<Signer> {
                                match pending_update {
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => {
                                                if htlc_id_arg == htlc_id {
-                                                       #[cfg(any(test, feature = "fuzztarget"))]
+                                                       #[cfg(any(test, fuzzing))]
                                                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
                                                        return Ok(None);
                                                }
@@ -1895,6 +1895,16 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ChannelError::Close("Minimum confirmation depth must be at least 1".to_owned()));
                }
 
+               if let Some(ty) = &msg.channel_type {
+                       if *ty != self.channel_type {
+                               return Err(ChannelError::Close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
+                       }
+               } else if their_features.supports_channel_type() {
+                       // Assume they've accepted the channel type as they said they understand it.
+               } else {
+                       self.channel_type = ChannelTypeFeatures::from_counterparty_init(&their_features)
+               }
+
                let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
                        match &msg.shutdown_scriptpubkey {
                                &OptionalField::Present(ref script) => {
@@ -2174,11 +2184,11 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Returns transaction if there is pending funding transaction that is yet to broadcast
        pub fn unbroadcasted_funding(&self) -> Option<Transaction> {
-                if self.channel_state & (ChannelState::FundingCreated as u32) != 0 {
-                        self.funding_transaction.clone()
-                } else {
-                        None
-                }
+               if self.channel_state & (ChannelState::FundingCreated as u32) != 0 {
+                       self.funding_transaction.clone()
+               } else {
+                       None
+               }
        }
 
        /// Returns a HTLCStats about inbound pending htlcs
@@ -2367,7 +2377,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                let num_htlcs = included_htlcs + addl_htlcs;
                let res = Self::commit_tx_fee_msat(self.feerate_per_kw, num_htlcs, self.opt_anchors());
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        let mut fee = res;
                        if fee_spike_buffer_htlc.is_some() {
@@ -2445,7 +2455,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                let num_htlcs = included_htlcs + addl_htlcs;
                let res = Self::commit_tx_fee_msat(self.feerate_per_kw, num_htlcs, self.opt_anchors());
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        let mut fee = res;
                        if fee_spike_buffer_htlc.is_some() {
@@ -2728,7 +2738,7 @@ impl<Signer: Sign> Channel<Signer> {
                                return Err((None, ChannelError::Close("Funding remote cannot afford proposed new fee".to_owned())));
                        }
                }
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        if self.is_outbound() {
                                let projected_commit_tx_info = self.next_local_commitment_tx_fee_info_cached.lock().unwrap().take();
@@ -3035,7 +3045,7 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ChannelError::Close("Received an unexpected revoke_and_ack".to_owned()));
                }
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        *self.next_local_commitment_tx_fee_info_cached.lock().unwrap() = None;
                        *self.next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
@@ -4466,9 +4476,9 @@ impl<Signer: Sign> Channel<Signer> {
                                                                // If we generated the funding transaction and it doesn't match what it
                                                                // should, the client is really broken and we should just panic and
                                                                // tell them off. That said, because hash collisions happen with high
-                                                               // probability in fuzztarget mode, if we're fuzzing we just close the
+                                                               // probability in fuzzing mode, if we're fuzzing we just close the
                                                                // channel and move on.
-                                                               #[cfg(not(feature = "fuzztarget"))]
+                                                               #[cfg(not(fuzzing))]
                                                                panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
                                                        }
                                                        self.update_time_counter += 1;
@@ -4480,7 +4490,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                                        if input.witness.is_empty() {
                                                                                // We generated a malleable funding transaction, implying we've
                                                                                // just exposed ourselves to funds loss to our counterparty.
-                                                                               #[cfg(not(feature = "fuzztarget"))]
+                                                                               #[cfg(not(fuzzing))]
                                                                                panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
                                                                        }
                                                                }
@@ -4720,6 +4730,7 @@ impl<Signer: Sign> Channel<Signer> {
                                Some(script) => script.clone().into_inner(),
                                None => Builder::new().into_script(),
                        }),
+                       channel_type: Some(self.channel_type.clone()),
                }
        }
 
@@ -4937,9 +4948,9 @@ impl<Signer: Sign> Channel<Signer> {
                // Prior to static_remotekey, my_current_per_commitment_point was critical to claiming
                // current to_remote balances. However, it no longer has any use, and thus is now simply
                // set to a dummy (but valid, as required by the spec) public key.
-               // fuzztarget mode marks a subset of pubkeys as invalid so that we can hit "invalid pubkey"
+               // fuzzing mode marks a subset of pubkeys as invalid so that we can hit "invalid pubkey"
                // branches, but we unwrap it below, so we arbitrarily select a dummy pubkey which is both
-               // valid, and valid in fuzztarget mode's arbitrary validity criteria:
+               // valid, and valid in fuzzing mode's arbitrary validity criteria:
                let mut pk = [2; 33]; pk[1] = 0xff;
                let dummy_pubkey = PublicKey::from_slice(&pk).unwrap();
                let data_loss_protect = if self.cur_counterparty_commitment_transaction_number + 1 < INITIAL_COMMITMENT_NUMBER {
@@ -5225,7 +5236,7 @@ impl<Signer: Sign> Channel<Signer> {
                let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
                let (signature, htlc_signatures);
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        if !self.is_outbound() {
                                let projected_commit_tx_info = self.next_remote_commitment_tx_fee_info_cached.lock().unwrap().take();
@@ -5711,9 +5722,9 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 
                self.channel_update_status.write(writer)?;
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                (self.historical_inbound_htlc_fulfills.len() as u64).write(writer)?;
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                for htlc in self.historical_inbound_htlc_fulfills.iter() {
                        htlc.write(writer)?;
                }
@@ -5975,9 +5986,9 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
                let channel_update_status = Readable::read(reader)?;
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                let mut historical_inbound_htlc_fulfills = HashSet::new();
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        let htlc_fulfills_len: u64 = Readable::read(reader)?;
                        for _ in 0..htlc_fulfills_len {
@@ -6151,14 +6162,14 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
                        announcement_sigs,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_local_commitment_tx_fee_info_cached: Mutex::new(None),
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills,
 
                        channel_type: channel_type.unwrap(),
index 14e47e71d4b321fa30f2aa2b1f5c6ebd0018243a..674977faaebc2ecd519682ea8f5edb17589fc81b 100644 (file)
@@ -1790,7 +1790,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                let mut channel_state = self.channel_state.lock().unwrap();
                match channel_state.by_id.entry(temporary_channel_id) {
                        hash_map::Entry::Occupied(_) => {
-                               if cfg!(feature = "fuzztarget") {
+                               if cfg!(fuzzing) {
                                        return Err(APIError::APIMisuseError { err: "Fuzzy bad RNG".to_owned() });
                                } else {
                                        panic!("RNG is bad???");
@@ -3257,7 +3257,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
 
                                                                macro_rules! check_total_value {
                                                                        ($payment_data_total_msat: expr, $payment_secret: expr, $payment_preimage: expr) => {{
-                                                                               let mut total_value = 0;
                                                                                let mut payment_received_generated = false;
                                                                                let htlcs = channel_state.claimable_htlcs.entry(payment_hash)
                                                                                        .or_insert(Vec::new());
@@ -3268,7 +3267,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                                continue
                                                                                        }
                                                                                }
-                                                                               htlcs.push(claimable_htlc);
+                                                                               let mut total_value = claimable_htlc.value;
                                                                                for htlc in htlcs.iter() {
                                                                                        total_value += htlc.value;
                                                                                        match &htlc.onion_payload {
@@ -3286,10 +3285,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                if total_value >= msgs::MAX_VALUE_MSAT || total_value > $payment_data_total_msat {
                                                                                        log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the total value {} ran over expected value {} (or HTLCs were inconsistent)",
                                                                                                log_bytes!(payment_hash.0), total_value, $payment_data_total_msat);
-                                                                                       for htlc in htlcs.iter() {
-                                                                                               fail_htlc!(htlc);
-                                                                                       }
+                                                                                       fail_htlc!(claimable_htlc);
                                                                                } else if total_value == $payment_data_total_msat {
+                                                                                       htlcs.push(claimable_htlc);
                                                                                        new_events.push(events::Event::PaymentReceived {
                                                                                                payment_hash,
                                                                                                purpose: events::PaymentPurpose::InvoicePayment {
@@ -3303,6 +3301,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                        // Nothing to do - we haven't reached the total
                                                                                        // payment value yet, wait until we receive more
                                                                                        // MPP parts.
+                                                                                       htlcs.push(claimable_htlc);
                                                                                }
                                                                                payment_received_generated
                                                                        }}
@@ -4932,7 +4931,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        /// In chanmon_consistency_target, we'd like to be able to restore monitor updating without
        /// handling all pending events (i.e. not PendingHTLCsForwardable). Thus, we expose monitor
        /// update events as a separate process method here.
-       #[cfg(feature = "fuzztarget")]
+       #[cfg(fuzzing)]
        pub fn process_monitor_events(&self) {
                self.process_pending_monitor_events();
        }
@@ -5254,7 +5253,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                }
        }
 
-       #[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
+       #[cfg(any(test, fuzzing, feature = "_test_utils"))]
        pub fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
                let events = core::cell::RefCell::new(Vec::new());
                let event_handler = |event: &events::Event| events.borrow_mut().push(event.clone());
index ad416fbffc34177b29e9d0005c0f5a8b101f0ea1..3c7174a9d71a63a8f74116229ee46f6da5f42f4a 100644 (file)
@@ -9601,6 +9601,77 @@ fn test_forwardable_regen() {
        claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_2);
 }
 
+#[test]
+fn test_dup_htlc_second_fail_panic() {
+       // Previously, if we received two HTLCs back-to-back, where the second overran the expected
+       // value for the payment, we'd fail back both HTLCs after generating a `PaymentReceived` event.
+       // Then, if the user failed the second payment, they'd hit a "tried to fail an already failed
+       // HTLC" debug panic. This tests for this behavior, checking that only one HTLC is auto-failed.
+       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);
+
+       let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
+
+       let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id())
+               .with_features(InvoiceFeatures::known());
+       let scorer = test_utils::TestScorer::with_penalty(0);
+       let route = get_route(
+               &nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph,
+               Some(&nodes[0].node.list_usable_channels().iter().collect::<Vec<_>>()),
+               10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer).unwrap();
+
+       let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(&nodes[1]);
+
+       {
+               nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
+               check_added_monitors!(nodes[0], 1);
+               let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               let mut payment_event = SendEvent::from_event(events.pop().unwrap());
+               nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
+               commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
+       }
+       expect_pending_htlcs_forwardable!(nodes[1]);
+       expect_payment_received!(nodes[1], our_payment_hash, our_payment_secret, 10_000);
+
+       {
+               nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
+               check_added_monitors!(nodes[0], 1);
+               let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+               assert_eq!(events.len(), 1);
+               let mut payment_event = SendEvent::from_event(events.pop().unwrap());
+               nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
+               commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
+               // At this point, nodes[1] would notice it has too much value for the payment. It will
+               // assume the second is a privacy attack (no longer particularly relevant
+               // post-payment_secrets) and fail back the new HTLC. Previously, it'd also have failed back
+               // the first HTLC delivered above.
+       }
+
+       // Now we go fail back the first HTLC from the user end.
+       expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+       nodes[1].node.process_pending_htlc_forwards();
+       nodes[1].node.fail_htlc_backwards(&our_payment_hash);
+
+       expect_pending_htlcs_forwardable_ignore!(nodes[1]);
+       nodes[1].node.process_pending_htlc_forwards();
+
+       check_added_monitors!(nodes[1], 1);
+       let fail_updates_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+       assert_eq!(fail_updates_1.update_fail_htlcs.len(), 2);
+
+       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_updates_1.update_fail_htlcs[0]);
+       nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_updates_1.update_fail_htlcs[1]);
+       commitment_signed_dance!(nodes[0], nodes[1], fail_updates_1.commitment_signed, false);
+
+       let failure_events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(failure_events.len(), 2);
+       if let Event::PaymentPathFailed { .. } = failure_events[0] {} else { panic!(); }
+       if let Event::PaymentPathFailed { .. } = failure_events[1] {} else { panic!(); }
+}
+
 #[test]
 fn test_keysend_payments_to_public_node() {
        let chanmon_cfgs = create_chanmon_cfgs(2);
index 41d978e8d046aa95bd93597011733b94a5b9b9dc..44704ae5040f44ee58e21b853be05a41252a1e2e 100644 (file)
@@ -29,14 +29,14 @@ pub mod chan_utils;
 pub mod features;
 pub mod script;
 
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 pub mod peer_channel_encryptor;
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub(crate) mod peer_channel_encryptor;
 
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 pub mod channel;
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub(crate) mod channel;
 
 mod onion_utils;
index 131c4fb54d2c51a4698a9e390b9456d08b07a2e4..7295c40d5442dd87639d08bbe6a6a3b2c1d5a873 100644 (file)
@@ -204,6 +204,12 @@ pub struct AcceptChannel {
        pub first_per_commitment_point: PublicKey,
        /// Optionally, a request to pre-set the to-sender output's scriptPubkey for when we collaboratively close
        pub shutdown_scriptpubkey: OptionalField<Script>,
+       /// The channel type that this channel will represent. If none is set, we derive the channel
+       /// type from the intersection of our feature bits with our counterparty's feature bits from
+       /// the Init message.
+       ///
+       /// This is required to match the equivalent field in [`OpenChannel::channel_type`].
+       pub channel_type: Option<ChannelTypeFeatures>,
 }
 
 /// A funding_created message to be sent or received from a peer
@@ -937,9 +943,9 @@ mod fuzzy_internal_msgs {
                pub(crate) pad: Vec<u8>,
        }
 }
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 pub use self::fuzzy_internal_msgs::*;
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub(crate) use self::fuzzy_internal_msgs::*;
 
 #[derive(Clone)]
@@ -1064,7 +1070,9 @@ impl_writeable_msg!(AcceptChannel, {
        htlc_basepoint,
        first_per_commitment_point,
        shutdown_scriptpubkey
-}, {});
+}, {
+       (1, channel_type, option),
+});
 
 impl_writeable_msg!(AnnouncementSignatures, {
        channel_id,
@@ -2184,7 +2192,8 @@ mod tests {
                        delayed_payment_basepoint: pubkey_4,
                        htlc_basepoint: pubkey_5,
                        first_per_commitment_point: pubkey_6,
-                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent }
+                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
+                       channel_type: None,
                };
                let encoded_value = accept_channel.encode();
                let mut target_value = hex::decode("020202020202020202020202020202020202020202020202020202020202020212345678901234562334032891223698321446687011447600083a840000034d000c89d4c0bcc0bc031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d076602531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe33703462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f703f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a").unwrap();
index dc2f8fd1196a1848af7390af2bc7642c9265f1df..d661a7813a35a6d28253c8d05c83be8a0c7f5395 100644 (file)
@@ -423,7 +423,7 @@ impl<'a> CandidateRouteHop<'a> {
 /// so that we can choose cheaper paths (as per Dijkstra's algorithm).
 /// Fee values should be updated only in the context of the whole path, see update_value_and_recompute_fees.
 /// These fee values are useful to choose hops as we traverse the graph "payee-to-payer".
-#[derive(Clone, Debug)]
+#[derive(Clone)]
 struct PathBuildingHop<'a> {
        // Note that this should be dropped in favor of loading it from CandidateRouteHop, but doing so
        // is a larger refactor and will require careful performance analysis.
@@ -455,7 +455,7 @@ struct PathBuildingHop<'a> {
        /// decrease as well. Thus, we have to explicitly track which nodes have been processed and
        /// avoid processing them again.
        was_processed: bool,
-       #[cfg(all(not(feature = "_bench_unstable"), any(test, feature = "fuzztarget")))]
+       #[cfg(all(not(feature = "_bench_unstable"), any(test, fuzzing)))]
        // In tests, we apply further sanity checks on cases where we skip nodes we already processed
        // to ensure it is specifically in cases where the fee has gone down because of a decrease in
        // value_contribution_msat, which requires tracking it here. See comments below where it is
@@ -463,6 +463,22 @@ struct PathBuildingHop<'a> {
        value_contribution_msat: u64,
 }
 
+impl<'a> core::fmt::Debug for PathBuildingHop<'a> {
+       fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
+               f.debug_struct("PathBuildingHop")
+                       .field("node_id", &self.node_id)
+                       .field("short_channel_id", &self.candidate.short_channel_id())
+                       .field("total_fee_msat", &self.total_fee_msat)
+                       .field("next_hops_fee_msat", &self.next_hops_fee_msat)
+                       .field("hop_use_fee_msat", &self.hop_use_fee_msat)
+                       .field("total_fee_msat - (next_hops_fee_msat + hop_use_fee_msat)", &(&self.total_fee_msat - (&self.next_hops_fee_msat + &self.hop_use_fee_msat)))
+                       .field("path_penalty_msat", &self.path_penalty_msat)
+                       .field("path_htlc_minimum_msat", &self.path_htlc_minimum_msat)
+                       .field("cltv_expiry_delta", &self.candidate.cltv_expiry_delta())
+                       .finish()
+       }
+}
+
 // Instantiated with a list of hops with correct data in them collected during path finding,
 // an instance of this struct should be further modified only via given methods.
 #[derive(Clone)]
@@ -719,8 +735,9 @@ where L::Target: Logger {
                        node_info.features.supports_basic_mpp()
                } else { false }
        } else { false };
-       log_trace!(logger, "Searching for a route from payer {} to payee {} {} MPP", our_node_pubkey,
-               payment_params.payee_pubkey, if allow_mpp { "with" } else { "without" });
+       log_trace!(logger, "Searching for a route from payer {} to payee {} {} MPP and {} first hops {}overriding the network graph", our_node_pubkey,
+               payment_params.payee_pubkey, if allow_mpp { "with" } else { "without" },
+               first_hops.map(|hops| hops.len()).unwrap_or(0), if first_hops.is_some() { "" } else { "not " });
 
        // Step (1).
        // Prepare the data we'll use for payee-to-payer search by
@@ -896,14 +913,14 @@ where L::Target: Logger {
                                                                path_htlc_minimum_msat,
                                                                path_penalty_msat: u64::max_value(),
                                                                was_processed: false,
-                                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, feature = "fuzztarget")))]
+                                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, fuzzing)))]
                                                                value_contribution_msat,
                                                        }
                                                });
 
                                                #[allow(unused_mut)] // We only use the mut in cfg(test)
                                                let mut should_process = !old_entry.was_processed;
-                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, feature = "fuzztarget")))]
+                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, fuzzing)))]
                                                {
                                                        // In test/fuzzing builds, we do extra checks to make sure the skipping
                                                        // of already-seen nodes only happens in cases we expect (see below).
@@ -992,13 +1009,13 @@ where L::Target: Logger {
                                                                old_entry.fee_msat = 0; // This value will be later filled with hop_use_fee_msat of the following channel
                                                                old_entry.path_htlc_minimum_msat = path_htlc_minimum_msat;
                                                                old_entry.path_penalty_msat = path_penalty_msat;
-                                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, feature = "fuzztarget")))]
+                                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, fuzzing)))]
                                                                {
                                                                        old_entry.value_contribution_msat = value_contribution_msat;
                                                                }
                                                                did_add_update_path_to_src_node = true;
                                                        } else if old_entry.was_processed && new_cost < old_cost {
-                                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, feature = "fuzztarget")))]
+                                                               #[cfg(all(not(feature = "_bench_unstable"), any(test, fuzzing)))]
                                                                {
                                                                        // If we're skipping processing a node which was previously
                                                                        // processed even though we found another path to it with a
@@ -1299,8 +1316,8 @@ where L::Target: Logger {
                                ordered_hops.last_mut().unwrap().0.fee_msat = value_contribution_msat;
                                ordered_hops.last_mut().unwrap().0.hop_use_fee_msat = 0;
 
-                               log_trace!(logger, "Found a path back to us from the target with {} hops contributing up to {} msat: {:?}",
-                                       ordered_hops.len(), value_contribution_msat, ordered_hops);
+                               log_trace!(logger, "Found a path back to us from the target with {} hops contributing up to {} msat: \n {:#?}",
+                                       ordered_hops.len(), value_contribution_msat, ordered_hops.iter().map(|h| &(h.0)).collect::<Vec<&PathBuildingHop>>());
 
                                let mut payment_path = PaymentPath {hops: ordered_hops};
 
index 85c0a47d4a5064f2fabe22e51829a7d1b60ed052..3578fb36626f494053decf24c96d4633bdc412b8 100644 (file)
@@ -11,7 +11,7 @@
 
 use io;
 
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 mod real_chacha {
        use core::cmp;
        use core::convert::TryInto;
@@ -272,10 +272,10 @@ mod real_chacha {
                }
        }
 }
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub use self::real_chacha::ChaCha20;
 
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 mod fuzzy_chacha {
        pub struct ChaCha20 {}
 
@@ -297,7 +297,7 @@ mod fuzzy_chacha {
                pub fn process_in_place(&mut self, _input_output: &mut [u8]) {}
        }
 }
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 pub use self::fuzzy_chacha::ChaCha20;
 
 pub(crate) struct ChaChaReader<'a, R: io::Read> {
index fdd51e757b5bd12f1b973db7737efb802c3d2284..e0e155ced4cdf0499fd4e7ede0feb41174c40543 100644 (file)
@@ -10,7 +10,7 @@
 // This is a port of Andrew Moons poly1305-donna
 // https://github.com/floodyberry/poly1305-donna
 
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 mod real_chachapoly {
        use util::chacha20::ChaCha20;
        use util::poly1305::Poly1305;
@@ -94,10 +94,10 @@ mod real_chachapoly {
                }
        }
 }
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub use self::real_chachapoly::ChaCha20Poly1305RFC;
 
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 mod fuzzy_chachapoly {
        #[derive(Clone, Copy)]
        pub struct ChaCha20Poly1305RFC {
@@ -141,5 +141,5 @@ mod fuzzy_chachapoly {
                }
        }
 }
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 pub use self::fuzzy_chachapoly::ChaCha20Poly1305RFC;
index 8f15844e10188cafa2d17cd9da692e5d1c797ab6..afe9c402c713981a5860002655aa101442fad37e 100644 (file)
 macro_rules! hash_to_message {
        ($slice: expr) => {
                {
-                       #[cfg(not(feature = "fuzztarget"))]
+                       #[cfg(not(fuzzing))]
                        {
                                ::bitcoin::secp256k1::Message::from_slice($slice).unwrap()
                        }
-                       #[cfg(feature = "fuzztarget")]
+                       #[cfg(fuzzing)]
                        {
                                match ::bitcoin::secp256k1::Message::from_slice($slice) {
                                        Ok(msg) => msg,
index 6e04f85682dd7fb59da7b50c7a6322660ebf0e96..a1e92a0f8cfe29ce2f72ff300b65f021645ab616 100644 (file)
@@ -24,11 +24,11 @@ pub mod invoice;
 pub(crate) mod atomic_counter;
 pub(crate) mod byte_utils;
 pub(crate) mod chacha20;
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 pub mod zbase32;
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub(crate) mod zbase32;
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub(crate) mod poly1305;
 pub(crate) mod chacha20poly1305rfc;
 pub(crate) mod transaction_utils;
@@ -45,11 +45,11 @@ pub(crate) mod crypto;
 pub mod logger;
 pub mod config;
 
-#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
+#[cfg(any(test, fuzzing, feature = "_test_utils"))]
 pub mod test_utils;
 
 /// impls of traits that add exra enforcement on the way they're called. Useful for detecting state
 /// machine errors and used in fuzz targets and tests.
-#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
+#[cfg(any(test, fuzzing, feature = "_test_utils"))]
 pub mod enforcing_trait_impls;