From e41e7564baccc229e17701ebd98e8ff8a4619497 Mon Sep 17 00:00:00 2001 From: Devrandom Date: Tue, 1 Oct 2024 14:58:36 +0200 Subject: [PATCH] Expose functional tests under _externalize_tests feature flag Also, introduce TestSignerFactory, a factory for dynamic signers and ext-functional-test-demo crate for testing this machinery. --- .gitignore | 1 + Cargo.toml | 1 + ci/ci-tests.sh | 7 + ext-functional-test-demo/Cargo.toml | 7 + ext-functional-test-demo/src/main.rs | 31 ++ fuzz/src/chanmon_consistency.rs | 2 + fuzz/src/full_stack.rs | 5 +- lightning-background-processor/src/lib.rs | 4 + lightning-macros/src/lib.rs | 2 +- lightning/Cargo.toml | 4 +- lightning/src/chain/chainmonitor.rs | 2 +- lightning/src/chain/channelmonitor.rs | 19 +- lightning/src/chain/onchaintx.rs | 12 +- lightning/src/chain/package.rs | 4 +- lightning/src/events/mod.rs | 22 +- lightning/src/lib.rs | 3 + lightning/src/ln/bolt11_payment.rs | 8 +- lightning/src/ln/chan_utils.rs | 4 +- lightning/src/ln/channel.rs | 49 +- lightning/src/ln/channelmanager.rs | 28 +- lightning/src/ln/functional_test_utils.rs | 37 +- lightning/src/ln/functional_tests.rs | 631 +++++++++++----------- lightning/src/ln/invoice_utils.rs | 67 ++- lightning/src/ln/mod.rs | 4 +- lightning/src/ln/monitor_tests.rs | 4 +- lightning/src/ln/onion_utils.rs | 16 +- lightning/src/ln/outbound_payment.rs | 16 +- lightning/src/ln/wire.rs | 2 +- lightning/src/onion_message/messenger.rs | 2 +- lightning/src/routing/router.rs | 4 + lightning/src/util/test_channel_signer.rs | 9 +- lightning/src/util/test_utils.rs | 42 +- 32 files changed, 559 insertions(+), 490 deletions(-) create mode 100644 ext-functional-test-demo/Cargo.toml create mode 100644 ext-functional-test-demo/src/main.rs diff --git a/.gitignore b/.gitignore index 8507aea83..ed10eb143 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,6 @@ lightning-rapid-gossip-sync/res/full_graph.lngossip lightning-custom-message/target lightning-transaction-sync/target lightning-dns-resolver/target +ext-functional-test-demo/target no-std-check/target msrv-no-dev-deps-check/target diff --git a/Cargo.toml b/Cargo.toml index 1c42def79..8c0885244 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ members = [ exclude = [ "lightning-transaction-sync", + "ext-functional-test-demo", "no-std-check", "msrv-no-dev-deps-check", "bench", diff --git a/ci/ci-tests.sh b/ci/ci-tests.sh index 8e3edfa43..1f6ffe0a8 100755 --- a/ci/ci-tests.sh +++ b/ci/ci-tests.sh @@ -112,6 +112,13 @@ cargo check --verbose --color always [ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean popd +echo -e "\n\Running functional tests from outside the workspace" +pushd ext-functional-test-demo +[ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p regex --precise "1.9.6" --verbose +cargo test --color always +[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean +popd + # Test that we can build downstream code with only the "release pins". pushd msrv-no-dev-deps-check PIN_RELEASE_DEPS diff --git a/ext-functional-test-demo/Cargo.toml b/ext-functional-test-demo/Cargo.toml new file mode 100644 index 000000000..a3f6bde3d --- /dev/null +++ b/ext-functional-test-demo/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ext-functional-tester" +version = "0.1.0" +edition = "2021" + +[dependencies] +lightning = { path = "../lightning", features = ["_externalize_tests"] } diff --git a/ext-functional-test-demo/src/main.rs b/ext-functional-test-demo/src/main.rs new file mode 100644 index 000000000..4636e1150 --- /dev/null +++ b/ext-functional-test-demo/src/main.rs @@ -0,0 +1,31 @@ +fn main() { + println!("{} tests were exported", lightning::get_xtests().len()); +} + +#[cfg(test)] +mod tests { + use lightning::util::dyn_signer::{DynKeysInterfaceTrait, DynSigner}; + use lightning::util::test_utils::{TestSignerFactory, SIGNER_FACTORY}; + use std::panic::catch_unwind; + use std::sync::Arc; + use std::time::Duration; + + struct BrokenSignerFactory(); + + impl TestSignerFactory for BrokenSignerFactory { + fn make_signer( + &self, _seed: &[u8; 32], _now: Duration, + ) -> Box> { + panic!() + } + } + + #[test] + fn test_functional() { + lightning::ln::functional_tests::test_insane_channel_opens(); + lightning::ln::functional_tests::fake_network_test(); + + SIGNER_FACTORY.set(Arc::new(BrokenSignerFactory())); + catch_unwind(|| lightning::ln::functional_tests::fake_network_test()).unwrap_err(); + } +} diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 1dc274a3b..cf18fa83a 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -79,6 +79,7 @@ use bitcoin::secp256k1::schnorr; use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey}; use lightning::io::Cursor; +use lightning::util::dyn_signer::DynSigner; use std::cmp::{self, Ordering}; use std::mem; use std::sync::atomic; @@ -375,6 +376,7 @@ impl SignerProvider for KeyProvider { channel_keys_id, ); let revoked_commitment = self.make_enforcement_state_cell(keys.commitment_seed); + let keys = DynSigner::new(keys); TestChannelSigner::new_with_revoked(keys, revoked_commitment, false) } diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 802c10942..6594f4725 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -75,6 +75,7 @@ use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature}; use bitcoin::secp256k1::schnorr; use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey}; +use lightning::util::dyn_signer::DynSigner; use std::cell::RefCell; use std::cmp; use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}; @@ -439,7 +440,7 @@ impl SignerProvider for KeyProvider { let ctr = channel_keys_id[0]; let (inbound, state) = self.signer_state.borrow().get(&ctr).unwrap().clone(); TestChannelSigner::new_with_revoked( - if inbound { + DynSigner::new(if inbound { InMemorySigner::new( &secp_ctx, SecretKey::from_slice(&[ @@ -509,7 +510,7 @@ impl SignerProvider for KeyProvider { channel_keys_id, channel_keys_id, ) - }, + }), state, false, ) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index ef889d4e8..2e8c49ebd 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -2550,6 +2550,8 @@ mod tests { failure: PathFailure::OnPath { network_update: None }, path: path.clone(), short_channel_id: Some(scored_scid), + error_code: None, + error_data: None, }); let event = $receive.expect("PaymentPathFailed not handled within deadline"); match event { @@ -2567,6 +2569,8 @@ mod tests { failure: PathFailure::OnPath { network_update: None }, path: path.clone(), short_channel_id: None, + error_code: None, + error_data: None, }); let event = $receive.expect("PaymentPathFailed not handled within deadline"); match event { diff --git a/lightning-macros/src/lib.rs b/lightning-macros/src/lib.rs index a92079470..a1df4d49a 100644 --- a/lightning-macros/src/lib.rs +++ b/lightning-macros/src/lib.rs @@ -306,7 +306,7 @@ pub fn drop_legacy_field_definition(expr: TokenStream) -> TokenStream { /// /// fn f1() {} /// -/// #[xtest(feature = "_test_utils")] +/// #[xtest(feature = "_externalize_tests")] /// pub fn test_f1() { /// f1(); /// } diff --git a/lightning/Cargo.toml b/lightning/Cargo.toml index da0961f25..5fc763f7e 100644 --- a/lightning/Cargo.toml +++ b/lightning/Cargo.toml @@ -18,7 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"] [features] # Internal test utilities exposed to other repo crates _test_utils = ["regex", "bitcoin/bitcoinconsensus", "lightning-types/_test_utils"] - +_externalize_tests = ["inventory", "_test_utils"] # Allow signing of local transactions that may have been revoked or will be revoked, for functional testing (e.g. justice tx handling). # This is unsafe to use in production because it may result in the counterparty publishing taking our funds. unsafe_revoked_tx_signing = [] @@ -48,10 +48,12 @@ regex = { version = "1.5.6", optional = true } backtrace = { version = "0.3", optional = true } libm = { version = "0.2", default-features = false } +inventory = { version = "0.3", optional = true } [dev-dependencies] regex = "1.5.6" lightning-types = { version = "0.3.0", path = "../lightning-types", features = ["_test_utils"] } +lightning-macros = { path = "../lightning-macros" } [dev-dependencies.bitcoin] version = "0.32.2" diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index eec56ac36..5779e7597 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -469,7 +469,7 @@ where C::Target: chain::Filter, } - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub fn remove_monitor(&self, channel_id: &ChannelId) -> ChannelMonitor { self.monitors.write().unwrap().remove(channel_id).unwrap().monitor } diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 9a3c9265f..040ac6b3f 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -854,10 +854,7 @@ impl Readable for IrrevocablyResolvedHTLC { /// returned block hash and the the current chain and then reconnecting blocks to get to the /// best chain) upon deserializing the object! pub struct ChannelMonitor { - #[cfg(test)] pub(crate) inner: Mutex>, - #[cfg(not(test))] - pub(super) inner: Mutex>, } impl Clone for ChannelMonitor where Signer: Clone { @@ -965,9 +962,9 @@ pub(crate) struct ChannelMonitorImpl { // Obviously Correct (tm) if we just keep track of them explicitly. outputs_to_watch: HashMap>, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub onchain_tx_handler: OnchainTxHandler, - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] onchain_tx_handler: OnchainTxHandler, // This is set when the Channel[Manager] generated a ChannelMonitorUpdate which indicated the @@ -1818,7 +1815,7 @@ impl ChannelMonitor { /// Unsafe test-only version of `broadcast_latest_holder_commitment_txn` used by our test framework /// to bypass HolderCommitmentTransaction state update lockdown after signature and generate /// revoked commitment transaction. - #[cfg(any(test, feature = "unsafe_revoked_tx_signing"))] + #[cfg(any(test, feature = "_test_utils", feature = "unsafe_revoked_tx_signing"))] pub fn unsafe_get_latest_holder_commitment_txn(&self, logger: &L) -> Vec where L::Target: Logger { let mut inner = self.inner.lock().unwrap(); @@ -2132,7 +2129,7 @@ impl ChannelMonitor { self.inner.lock().unwrap().counterparty_payment_script = script; } - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub fn do_mut_signer_call ()>(&self, mut f: F) { let mut inner = self.inner.lock().unwrap(); f(&mut inner.onchain_tx_handler.signer); @@ -2773,7 +2770,7 @@ macro_rules! fail_unbroadcast_htlcs { // witness length match (ie is 136 bytes long). We generate one here which we also use in some // in-line tests later. -#[cfg(test)] +#[cfg(any(test, feature = "_test_utils"))] pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec { use bitcoin::opcodes; let mut ret = [opcodes::all::OP_NOP.to_u8(); 136]; @@ -2785,7 +2782,7 @@ pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec { Vec::from(&ret[..]) } -#[cfg(test)] +#[cfg(any(test, feature = "_test_utils"))] pub fn deliberately_bogus_accepted_htlc_witness() -> Vec> { vec![Vec::new(), Vec::new(), Vec::new(), Vec::new(), deliberately_bogus_accepted_htlc_witness_program().into()].into() } @@ -3947,7 +3944,7 @@ impl ChannelMonitorImpl { } } - #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))] + #[cfg(any(test, feature = "_test_utils", feature = "unsafe_revoked_tx_signing"))] /// Note that this includes possibly-locktimed-in-the-future transactions! fn unsafe_get_latest_holder_commitment_txn( &mut self, logger: &WithChannelMonitor @@ -5289,7 +5286,7 @@ mod tests { nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header, &[(0, broadcast_tx)], conf_height); - let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor)>::read( + let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<_>)>::read( &mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()), (&nodes[1].keys_manager.backing, &nodes[1].keys_manager.backing)).unwrap(); diff --git a/lightning/src/chain/onchaintx.rs b/lightning/src/chain/onchaintx.rs index 457d0512e..a52d0eaaf 100644 --- a/lightning/src/chain/onchaintx.rs +++ b/lightning/src/chain/onchaintx.rs @@ -250,9 +250,9 @@ pub struct OnchainTxHandler { // Key is identifier of the pending claim request, i.e the txid of the initial claiming transaction generated by // us and is immutable until all outpoint of the claimable set are post-anti-reorg-delay solved. // Entry is cache of elements need to generate a bumped claiming transaction (see ClaimTxBumpMaterial) - #[cfg(test)] // Used in functional_test to verify sanitization + #[cfg(any(test, feature = "_test_utils"))] pub(crate) pending_claim_requests: HashMap, - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] pending_claim_requests: HashMap, // Used to track external events that need to be forwarded to the `ChainMonitor`. This `Vec` @@ -273,9 +273,9 @@ pub struct OnchainTxHandler { // block height, and are immutable until the outpoint has enough confirmations to meet our // [`ANTI_REORG_DELAY`]. The initial confirmation block height is used to remove the entry if // the block gets disconnected. - #[cfg(test)] // Used in functional_test to verify sanitization - pub claimable_outpoints: HashMap, - #[cfg(not(test))] + #[cfg(any(test, feature = "_test_utils"))] + pub(crate) claimable_outpoints: HashMap, + #[cfg(not(any(test, feature = "_test_utils")))] claimable_outpoints: HashMap, locktimed_packages: BTreeMap>, @@ -1193,7 +1193,7 @@ impl OnchainTxHandler { MaybeSignedTransaction(tx) } - #[cfg(any(test, feature="unsafe_revoked_tx_signing"))] + #[cfg(any(test, feature="_test_utils", feature="unsafe_revoked_tx_signing"))] pub(crate) fn get_fully_signed_copy_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction { let sig = self.signer.unsafe_sign_holder_commitment(&self.channel_transaction_parameters, &self.holder_commitment, &self.secp_ctx).expect("sign holder commitment"); self.holder_commitment.add_holder_sig(funding_redeemscript, sig) diff --git a/lightning/src/chain/package.rs b/lightning/src/chain/package.rs index f7fe3fef9..1aa370fec 100644 --- a/lightning/src/chain/package.rs +++ b/lightning/src/chain/package.rs @@ -105,10 +105,10 @@ pub(crate) fn verify_channel_type_features(channel_type_features: &Option, -#[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_code: Option, -#[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_data: Option>, }, /// Indicates that a probe payment we sent returned successful, i.e., only failed at the destination. @@ -1569,15 +1569,15 @@ impl Writeable for Event { &Event::PaymentPathFailed { ref payment_id, ref payment_hash, ref payment_failed_permanently, ref failure, ref path, ref short_channel_id, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] ref error_code, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] ref error_data, } => { 3u8.write(writer)?; - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_code.write(writer)?; - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_data.write(writer)?; write_tlv_fields!(writer, { (0, payment_hash, required), @@ -1920,9 +1920,9 @@ impl MaybeReadable for Event { }, 3u8 => { let mut f = || { - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] let error_code = Readable::read(reader)?; - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] let error_data = Readable::read(reader)?; let mut payment_hash = PaymentHash([0; 32]); let mut payment_failed_permanently = false; @@ -1952,9 +1952,9 @@ impl MaybeReadable for Event { failure, path: Path { hops: path.unwrap(), blinded_tail }, short_channel_id, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_code, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_data, })) }; @@ -2364,7 +2364,7 @@ impl MaybeReadable for Event { /// broadcast to most peers). /// These events are handled by PeerManager::process_events if you are using a PeerManager. #[derive(Clone, Debug)] -#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))] pub enum MessageSendEvent { /// Used to indicate that we've accepted a channel open and should send the accept_channel /// message provided to the given peer. diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs index fa9badf87..392423b41 100644 --- a/lightning/src/lib.rs +++ b/lightning/src/lib.rs @@ -142,3 +142,6 @@ mod prelude { extern crate backtrace; mod sync; + +#[cfg(feature = "_externalize_tests")] +lightning_macros::xtest_inventory!(); diff --git a/lightning/src/ln/bolt11_payment.rs b/lightning/src/ln/bolt11_payment.rs index 232183cdb..9b26569f2 100644 --- a/lightning/src/ln/bolt11_payment.rs +++ b/lightning/src/ln/bolt11_payment.rs @@ -88,6 +88,7 @@ fn params_from_invoice( mod tests { use super::*; use crate::routing::router::Payee; + use crate::sign::{NodeSigner, Recipient}; use crate::types::payment::PaymentSecret; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; @@ -178,8 +179,6 @@ mod tests { let (payment_hash, payment_secret) = nodes[1].node.create_inbound_payment(None, 7200, None).unwrap(); - let secp_ctx = Secp256k1::new(); - let node_secret = nodes[1].keys_manager.backing.get_node_secret_key(); let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let invoice = InvoiceBuilder::new(Currency::Bitcoin) .description("test".into()) @@ -189,8 +188,11 @@ mod tests { .min_final_cltv_expiry_delta(144) .amount_milli_satoshis(50_000) .payment_metadata(payment_metadata.clone()) - .build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &node_secret)) + .build_raw() .unwrap(); + let sig = nodes[1].keys_manager.backing.sign_invoice(&invoice, Recipient::Node).unwrap(); + let invoice = invoice.sign::<_, ()>(|_| Ok(sig)).unwrap(); + let invoice = Bolt11Invoice::from_signed(invoice).unwrap(); let (hash, onion, params) = payment_parameters_from_invoice(&invoice).unwrap(); nodes[0] diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index 2447386b7..c72bd615f 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -176,9 +176,9 @@ impl HTLCClaim { } } -#[cfg(not(test))] +#[cfg(not(any(test, feature = "_test_utils")))] const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172; -#[cfg(test)] +#[cfg(any(test, feature = "_test_utils"))] pub const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172; pub(crate) fn commitment_tx_base_weight(channel_type_features: &ChannelTypeFeatures) -> u64 { diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index dd8da25ca..e08a07315 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -75,7 +75,8 @@ use crate::sign::type_resolver::ChannelSignerType; use super::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint}; -#[cfg(test)] +#[cfg(any(test, feature = "_test_utils"))] +#[allow(unused)] pub struct ChannelValueStat { pub value_to_self_msat: u64, pub channel_value_msat: u64, @@ -1112,9 +1113,9 @@ impl HolderCommitmentPoint { /// the channel. Sadly, there isn't really a good number for this - if we expect to have no new /// HTLCs for days we may need this to suffice for feerate increases across days, but that may /// leave the channel less usable as we hold a bigger reserve. -#[cfg(any(fuzzing, test))] +#[cfg(any(fuzzing, test, feature = "_test_utils"))] pub const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2; -#[cfg(not(any(fuzzing, test)))] +#[cfg(not(any(fuzzing, test, feature = "_test_utils")))] const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2; /// If we fail to see a funding transaction confirmed on-chain within this many blocks after the @@ -1220,7 +1221,7 @@ impl Channel where } } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub fn funding_mut(&mut self) -> &mut FundingScope { match &mut self.phase { ChannelPhase::Undefined => unreachable!(), @@ -1279,7 +1280,7 @@ impl Channel where } } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub fn is_unfunded_v1(&self) -> bool { matches!(self.phase, ChannelPhase::UnfundedOutboundV1(_) | ChannelPhase::UnfundedInboundV1(_)) } @@ -1628,9 +1629,9 @@ pub(super) struct FundingScope { /// minimum channel reserve for self to maintain - set by them. counterparty_selected_channel_reserve_satoshis: Option, - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(super) holder_selected_channel_reserve_satoshis: u64, - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_externalize_tests")))] holder_selected_channel_reserve_satoshis: u64, #[cfg(debug_assertions)] @@ -1851,9 +1852,9 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { /// The minimum and maximum absolute fee, in satoshis, we are willing to place on the closing /// transaction. These are set once we reach `closing_negotiation_ready`. - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub(crate) closing_fee_limits: Option<(u64, u64)>, - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] closing_fee_limits: Option<(u64, u64)>, /// If we remove an HTLC (or fee update), commit, and receive our counterparty's @@ -1880,26 +1881,26 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { counterparty_dust_limit_satoshis: u64, - #[cfg(test)] - pub(super) holder_dust_limit_satoshis: u64, - #[cfg(not(test))] + #[cfg(any(test, feature = "_test_utils"))] + pub(crate) holder_dust_limit_satoshis: u64, + #[cfg(not(any(test, feature = "_test_utils")))] holder_dust_limit_satoshis: u64, - #[cfg(test)] - pub(super) counterparty_max_htlc_value_in_flight_msat: u64, - #[cfg(not(test))] + #[cfg(any(test, feature = "_test_utils"))] + pub(crate) counterparty_max_htlc_value_in_flight_msat: u64, + #[cfg(not(any(test, feature = "_test_utils")))] counterparty_max_htlc_value_in_flight_msat: u64, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub(super) holder_max_htlc_value_in_flight_msat: u64, - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] holder_max_htlc_value_in_flight_msat: u64, counterparty_htlc_minimum_msat: u64, holder_htlc_minimum_msat: u64, - #[cfg(test)] + #[cfg(any(test, feature="_test_utils"))] pub counterparty_max_accepted_htlcs: u16, - #[cfg(not(test))] + #[cfg(not(any(test, feature="_test_utils")))] counterparty_max_accepted_htlcs: u16, holder_max_accepted_htlcs: u16, minimum_depth: Option, @@ -1987,9 +1988,9 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { /// The unique identifier used to re-derive the private key material for the channel through /// [`SignerProvider::derive_channel_signer`]. - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] channel_keys_id: [u8; 32], - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub channel_keys_id: [u8; 32], /// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we @@ -3130,7 +3131,7 @@ impl ChannelContext where SP::Target: SignerProvider { } /// Returns the holder signer for this channel. - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub fn get_mut_signer(&mut self) -> &mut ChannelSignerType { return &mut self.holder_signer } @@ -7616,12 +7617,12 @@ impl FundedChannel where self.context.cur_counterparty_commitment_transaction_number + 2 } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub fn get_signer(&self) -> &ChannelSignerType { &self.context.holder_signer } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub fn get_value_stat(&self) -> ChannelValueStat { ChannelValueStat { value_to_self_msat: self.funding.value_to_self_msat, diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 38e5ee14e..3771e3fc9 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -56,7 +56,9 @@ use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelType use crate::types::features::Bolt11InvoiceFeatures; #[cfg(trampoline)] use crate::routing::gossip::NodeId; -use crate::routing::router::{BlindedTail, FixedRouter, InFlightHtlcs, Path, Payee, PaymentParameters, Route, RouteParameters, RouteParametersConfig, Router}; +use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, Payee, PaymentParameters, RouteParameters, RouteParametersConfig, Router}; +#[cfg(any(feature = "_test_utils", test))] +use crate::routing::router::{FixedRouter, Route}; use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, InboundHTLCErr, NextPacketDetails}; use crate::ln::msgs; use crate::ln::onion_utils; @@ -128,7 +130,7 @@ use core::ops::Deref; use bitcoin::hex::impl_fmt_traits; // Re-export this for use in the public API. pub use crate::ln::outbound_payment::{Bolt12PaymentError, ProbeSendFailure, Retry, RetryableSendFailure, RecipientOnionFields}; -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] pub(crate) use crate::ln::outbound_payment::PaymentSendFailure; use crate::ln::script::ShutdownScript; @@ -2458,9 +2460,10 @@ where message_router: MR, /// See `ChannelManager` struct-level documentation for lock order requirements. - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub(super) best_block: RwLock, - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] + /// See `ChannelManager` struct-level documentation for lock order requirements. best_block: RwLock, secp_ctx: Secp256k1, @@ -2542,10 +2545,10 @@ where /// required to access the channel with the `counterparty_node_id`. /// /// See `ChannelManager` struct-level documentation for lock order requirements. - #[cfg(not(test))] - outpoint_to_peer: Mutex>, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub(crate) outpoint_to_peer: Mutex>, + #[cfg(not(any(test, feature = "_test_utils")))] + outpoint_to_peer: Mutex>, /// SCIDs (and outbound SCID aliases) -> `counterparty_node_id`s and `channel_id`s. /// @@ -4563,7 +4566,7 @@ where }) } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(crate) fn test_send_payment_along_path(&self, path: &Path, payment_hash: &PaymentHash, recipient_onion: RecipientOnionFields, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option, session_priv_bytes: [u8; 32]) -> Result<(), APIError> { let _lck = self.total_consistency_lock.read().unwrap(); self.send_payment_along_path(SendAlongPathArgs { @@ -4667,6 +4670,7 @@ where /// /// LDK will not automatically retry this payment, though it may be manually re-sent after an /// [`Event::PaymentFailed`] is generated. + #[cfg(any(test, feature = "_test_utils"))] pub fn send_payment_with_route( &self, mut route: Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, payment_id: PaymentId @@ -4737,7 +4741,7 @@ where &self.pending_events, |args| self.send_payment_along_path(args)) } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(super) fn test_send_payment_internal(&self, route: &Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, keysend_preimage: Option, payment_id: PaymentId, recv_value_msat: Option, onion_session_privs: Vec<[u8; 32]>) -> Result<(), PaymentSendFailure> { let best_block_height = self.best_block.read().unwrap().height; let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self); @@ -4746,7 +4750,7 @@ where best_block_height, |args| self.send_payment_along_path(args)) } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(crate) fn test_add_new_pending_payment(&self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, payment_id: PaymentId, route: &Route) -> Result, PaymentSendFailure> { let best_block_height = self.best_block.read().unwrap().height; self.pending_outbound_payments.test_add_new_pending_payment(payment_hash, recipient_onion, payment_id, route, None, &self.entropy_source, best_block_height) @@ -5204,7 +5208,7 @@ where Ok(()) } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(crate) fn funding_transaction_generated_unchecked(&self, temporary_channel_id: ChannelId, counterparty_node_id: PublicKey, funding_transaction: Transaction, output_index: u16) -> Result<(), APIError> { let txid = funding_transaction.compute_txid(); self.funding_transaction_generated_intern(temporary_channel_id, counterparty_node_id, funding_transaction, false, |_| { @@ -11406,7 +11410,7 @@ where // Most of our tests were written when we only broadcasted // `channel_announcement`s once and then never re-broadcasted // them again, so disable the re-broadcasting entirely in tests - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] { should_announce = announcement_sigs.is_some(); } diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 2d485a345..67470b0ce 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -28,11 +28,9 @@ use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate}; use crate::routing::router::{self, PaymentParameters, Route, RouteParameters}; use crate::sign::{EntropySource, RandomBytes}; use crate::util::config::{MaxDustHTLCExposure, UserConfig}; -#[cfg(test)] use crate::util::logger::Logger; use crate::util::scid_utils; use crate::util::test_channel_signer::TestChannelSigner; -#[cfg(test)] use crate::util::test_channel_signer::SignerOp; use crate::util::test_utils; use crate::util::test_utils::{TestChainMonitor, TestScorer, TestKeysInterface}; @@ -515,8 +513,7 @@ impl<'a, 'b, 'c> Node<'a, 'b, 'c> { /// Toggles this node's signer to be available for the given signer operation. /// This is useful for testing behavior for restoring an async signer that previously /// could not return a signature immediately. - #[cfg(test)] - pub fn enable_channel_signer_op(&self, peer_id: &PublicKey, chan_id: &ChannelId, signer_op: SignerOp) { + pub fn enable_channel_signer_op(&self, peer_id: &PublicKey, chan_id: &ChannelId, signer_op: SignerOp) { self.set_channel_signer_ops(peer_id, chan_id, signer_op, true); } @@ -535,8 +532,7 @@ impl<'a, 'b, 'c> Node<'a, 'b, 'c> { /// will behave normally, returning `Ok`. When set to `false`, and the channel signer will /// act like an off-line remote signer, returning `Err`. This applies to the signer in all /// relevant places, i.e. the channel manager, chain monitor, and the keys manager. - #[cfg(test)] - fn set_channel_signer_ops(&self, peer_id: &PublicKey, chan_id: &ChannelId, signer_op: SignerOp, available: bool) { + fn set_channel_signer_ops(&self, peer_id: &PublicKey, chan_id: &ChannelId, signer_op: SignerOp, available: bool) { use crate::sign::ChannelSigner; log_debug!(self.logger, "Setting channel signer for {} as available={}", chan_id, available); @@ -1002,7 +998,7 @@ pub fn remove_first_msg_event_to_node(msg_node_id: &PublicKey, msg_events: &mut } } -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] macro_rules! get_channel_ref { ($node: expr, $counterparty_node: expr, $per_peer_state_lock: ident, $peer_state_lock: ident, $channel_id: expr) => { { @@ -1013,7 +1009,7 @@ macro_rules! get_channel_ref { } } -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] macro_rules! get_feerate { ($node: expr, $counterparty_node: expr, $channel_id: expr) => { { @@ -1025,7 +1021,7 @@ macro_rules! get_feerate { } } -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] macro_rules! get_channel_type_features { ($node: expr, $counterparty_node: expr, $channel_id: expr) => { { @@ -1172,7 +1168,7 @@ pub fn _reload_node<'a, 'b, 'c>(node: &'a Node<'a, 'b, 'c>, default_config: User node_deserialized } -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] macro_rules! reload_node { ($node: expr, $new_config: expr, $chanman_encoded: expr, $monitors_encoded: expr, $persister: ident, $new_chain_monitor: ident, $new_channelmanager: ident) => { let chanman_encoded = $chanman_encoded; @@ -2011,7 +2007,7 @@ macro_rules! expect_pending_htlcs_forwardable_and_htlc_handling_failed { }} } -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] macro_rules! expect_pending_htlcs_forwardable_from_events { ($node: expr, $events: expr, $ignore: expr) => {{ assert_eq!($events.len(), 1); @@ -2209,7 +2205,6 @@ macro_rules! get_route { }} } -#[cfg(test)] #[macro_export] macro_rules! get_route_and_payment_hash { ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{ @@ -2345,7 +2340,6 @@ macro_rules! expect_payment_sent { } } -#[cfg(test)] #[macro_export] macro_rules! expect_payment_path_successful { ($node: expr) => { @@ -2433,7 +2427,6 @@ macro_rules! expect_payment_forwarded { } } -#[cfg(test)] #[macro_export] macro_rules! expect_channel_shutdown_state { ($node: expr, $chan_id: expr, $state: path) => { @@ -2468,7 +2461,6 @@ pub fn expect_channel_ready_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, ex } } -#[cfg(any(test, feature = "_test_utils"))] pub fn expect_probe_successful_events(node: &Node, mut probe_results: Vec<(PaymentHash, PaymentId)>) { let mut events = node.node.get_and_clear_pending_events(); @@ -2528,7 +2520,7 @@ impl<'a> PaymentFailedConditions<'a> { } } -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] macro_rules! expect_payment_failed_with_update { ($node: expr, $expected_payment_hash: expr, $payment_failed_permanently: expr, $scid: expr, $chan_closed: expr) => { $crate::ln::functional_test_utils::expect_payment_failed_conditions( @@ -2538,7 +2530,7 @@ macro_rules! expect_payment_failed_with_update { } } -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] macro_rules! expect_payment_failed { ($node: expr, $expected_payment_hash: expr, $payment_failed_permanently: expr $(, $expected_error_code: expr, $expected_error_data: expr)*) => { #[allow(unused_mut)] @@ -2557,14 +2549,11 @@ pub fn expect_payment_failed_conditions_event<'a, 'b, 'c, 'd, 'e>( if conditions.expected_mpp_parts_remain { assert_eq!(payment_failed_events.len(), 1); } else { assert_eq!(payment_failed_events.len(), 2); } let expected_payment_id = match &payment_failed_events[0] { Event::PaymentPathFailed { payment_hash, payment_failed_permanently, payment_id, failure, - #[cfg(test)] - error_code, - #[cfg(test)] - error_data, .. } => { + error_code, + error_data, .. } => { assert_eq!(*payment_hash, expected_payment_hash, "unexpected payment_hash"); assert_eq!(*payment_failed_permanently, expected_payment_failed_permanently, "unexpected payment_failed_permanently value"); - #[cfg(test)] - { + { assert!(error_code.is_some(), "expected error_code.is_some() = true"); assert!(error_data.is_some(), "expected error_data.is_some() = true"); if let Some((code, data)) = conditions.expected_htlc_error_data { @@ -3627,7 +3616,7 @@ pub fn get_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec {{ let peer_state_lock = $node.node.per_peer_state.read().unwrap(); diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index d0b89198d..91c67c7e4 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -58,13 +58,14 @@ use alloc::collections::BTreeSet; use core::iter::repeat; use bitcoin::hashes::Hash; use crate::sync::{Arc, Mutex, RwLock}; +use lightning_macros::xtest; use crate::ln::functional_test_utils::*; use crate::ln::chan_utils::CommitmentTransaction; use super::channel::UNFUNDED_CHANNEL_AGE_LIMIT_TICKS; -#[test] +#[xtest(feature = "_externalize_tests")] fn test_channel_resumption_fail_post_funding() { // If we fail to exchange funding with a peer prior to it disconnecting we'll resume the // channel open on reconnect, however if we do exchange funding we do not currently support @@ -96,8 +97,8 @@ fn test_channel_resumption_fail_post_funding() { assert_eq!(nodes[0].node.get_and_clear_pending_msg_events(), Vec::new()); } -#[test] -fn test_insane_channel_opens() { +#[xtest(feature = "_externalize_tests")] +pub fn test_insane_channel_opens() { // Stand up a network of 2 nodes use crate::ln::channel::TOTAL_BITCOIN_SUPPLY_SATOSHIS; let mut cfg = UserConfig::default(); @@ -157,8 +158,8 @@ fn test_insane_channel_opens() { insane_open_helper("max_accepted_htlcs was 484. It must not be larger than 483", |mut msg| { msg.common_fields.max_accepted_htlcs = 484; msg }); } -#[test] -fn test_funding_exceeds_no_wumbo_limit() { +#[xtest(feature = "_externalize_tests")] +pub fn test_funding_exceeds_no_wumbo_limit() { // Test that if a peer does not support wumbo channels, we'll refuse to open a wumbo channel to // them. use crate::ln::channel::MAX_FUNDING_SATOSHIS_NO_WUMBO; @@ -238,14 +239,14 @@ fn do_test_counterparty_no_reserve(send_from_initiator: bool) { } } -#[test] -fn test_counterparty_no_reserve() { +#[xtest(feature = "_externalize_tests")] +pub fn test_counterparty_no_reserve() { do_test_counterparty_no_reserve(true); do_test_counterparty_no_reserve(false); } -#[test] -fn test_async_inbound_update_fee() { +#[xtest(feature = "_externalize_tests")] +pub fn test_async_inbound_update_fee() { 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]); @@ -359,8 +360,8 @@ fn test_async_inbound_update_fee() { check_added_monitors!(nodes[1], 1); } -#[test] -fn test_update_fee_unordered_raa() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fee_unordered_raa() { // Just the intro to the previous test followed by an out-of-order RAA (which caused a // crash in an earlier version of the update_fee patch) let chanmon_cfgs = create_chanmon_cfgs(2); @@ -418,8 +419,8 @@ fn test_update_fee_unordered_raa() { // We can't continue, sadly, because our (1) now has a bogus signature } -#[test] -fn test_multi_flight_update_fee() { +#[xtest(feature = "_externalize_tests")] +pub fn test_multi_flight_update_fee() { 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]); @@ -607,8 +608,8 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) { expect_channel_ready_event(&nodes[0], &nodes[1].node.get_our_node_id()); } -#[test] -fn test_sanity_on_in_flight_opens() { +#[xtest(feature = "_externalize_tests")] +pub fn test_sanity_on_in_flight_opens() { do_test_sanity_on_in_flight_opens(0); do_test_sanity_on_in_flight_opens(0 | 0b1000_0000); do_test_sanity_on_in_flight_opens(1); @@ -629,8 +630,8 @@ fn test_sanity_on_in_flight_opens() { do_test_sanity_on_in_flight_opens(8 | 0b1000_0000); } -#[test] -fn test_update_fee_vanilla() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fee_vanilla() { 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]); @@ -672,8 +673,8 @@ fn test_update_fee_vanilla() { check_added_monitors!(nodes[1], 1); } -#[test] -fn test_update_fee_that_funder_cannot_afford() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fee_that_funder_cannot_afford() { 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]); @@ -804,8 +805,8 @@ fn test_update_fee_that_funder_cannot_afford() { [nodes[0].node.get_our_node_id()], channel_value); } -#[test] -fn test_update_fee_with_fundee_update_add_htlc() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fee_with_fundee_update_add_htlc() { 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]); @@ -904,8 +905,8 @@ fn test_update_fee_with_fundee_update_add_htlc() { check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_update_fee() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fee() { 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]); @@ -1018,8 +1019,8 @@ fn test_update_fee() { check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn fake_network_test() { +#[xtest(feature = "_externalize_tests")] +pub fn fake_network_test() { // Simple test which builds a network of ChannelManagers, connects them to each other, and // tests that payments get routed and transactions broadcast in semi-reasonable ways. let chanmon_cfgs = create_chanmon_cfgs(4); @@ -1150,8 +1151,8 @@ fn fake_network_test() { check_closed_event!(nodes[3], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn holding_cell_htlc_counting() { +#[xtest(feature = "_externalize_tests")] +pub fn holding_cell_htlc_counting() { // Tests that HTLCs in the holding cell count towards the pending HTLC limits on outbound HTLCs // to ensure we don't end up with HTLCs sitting around in our holding cell for several // commitment dance rounds. @@ -1268,8 +1269,8 @@ fn holding_cell_htlc_counting() { send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000); } -#[test] -fn duplicate_htlc_test() { +#[xtest(feature = "_externalize_tests")] +pub fn duplicate_htlc_test() { // Test that we accept duplicate payment_hash HTLCs across the network and that // claiming/failing them are all separate and don't affect each other let chanmon_cfgs = create_chanmon_cfgs(6); @@ -1297,8 +1298,8 @@ fn duplicate_htlc_test() { claim_payment(&nodes[1], &vec!(&nodes[3])[..], payment_preimage); } -#[test] -fn test_duplicate_htlc_different_direction_onchain() { +#[xtest(feature = "_externalize_tests")] +pub fn test_duplicate_htlc_different_direction_onchain() { // Test that ChannelMonitor doesn't generate 2 preimage txn // when we have 2 HTLCs with same preimage that go across a node // in opposite directions, even with the same payment secret. @@ -1389,8 +1390,8 @@ fn test_duplicate_htlc_different_direction_onchain() { } } -#[test] -fn test_basic_channel_reserve() { +#[xtest(feature = "_externalize_tests")] +pub fn test_basic_channel_reserve() { 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]); @@ -1414,8 +1415,8 @@ fn test_basic_channel_reserve() { send_payment(&nodes[0], &vec![&nodes[1]], max_can_send); } -#[test] -fn test_fee_spike_violation_fails_htlc() { +#[xtest(feature = "_externalize_tests")] +pub fn test_fee_spike_violation_fails_htlc() { 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]); @@ -1564,8 +1565,8 @@ fn test_fee_spike_violation_fails_htlc() { check_added_monitors!(nodes[1], 3); } -#[test] -fn test_chan_reserve_violation_outbound_htlc_inbound_chan() { +#[xtest(feature = "_externalize_tests")] +pub fn test_chan_reserve_violation_outbound_htlc_inbound_chan() { let mut chanmon_cfgs = create_chanmon_cfgs(2); // Set the fee rate for the channel very high, to the point where the fundee // sending any above-dust amount would result in a channel reserve violation. @@ -1599,8 +1600,8 @@ fn test_chan_reserve_violation_outbound_htlc_inbound_chan() { assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); } -#[test] -fn test_chan_reserve_violation_inbound_htlc_outbound_channel() { +#[xtest(feature = "_externalize_tests")] +pub fn test_chan_reserve_violation_inbound_htlc_outbound_channel() { let mut chanmon_cfgs = create_chanmon_cfgs(2); let feerate_per_kw = *chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap(); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -1656,8 +1657,8 @@ fn test_chan_reserve_violation_inbound_htlc_outbound_channel() { [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() { +#[xtest(feature = "_externalize_tests")] +pub fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() { // Test that if we receive many dust HTLCs over an outbound channel, they don't count when // calculating our commitment transaction fee (this was previously broken). let mut chanmon_cfgs = create_chanmon_cfgs(2); @@ -1698,8 +1699,8 @@ fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() { ), true, APIError::ChannelUnavailable { .. }, {}); } -#[test] -fn test_chan_init_feerate_unaffordability() { +#[xtest(feature = "_externalize_tests")] +pub fn test_chan_init_feerate_unaffordability() { // Test that we will reject channel opens which do not leave enough to pay for any HTLCs due to // channel reserve and feerate requirements. let mut chanmon_cfgs = create_chanmon_cfgs(2); @@ -1735,8 +1736,8 @@ fn test_chan_init_feerate_unaffordability() { } } -#[test] -fn test_chan_reserve_dust_inbound_htlcs_inbound_chan() { +#[xtest(feature = "_externalize_tests")] +pub fn test_chan_reserve_dust_inbound_htlcs_inbound_chan() { // Test that if we receive many dust HTLCs over an inbound channel, they don't count when // calculating our counterparty's commitment transaction fee (this was previously broken). let chanmon_cfgs = create_chanmon_cfgs(2); @@ -1765,8 +1766,8 @@ fn test_chan_reserve_dust_inbound_htlcs_inbound_chan() { route_payment(&nodes[0], &[&nodes[1]], payment_amt); } -#[test] -fn test_chan_reserve_violation_inbound_htlc_inbound_chan() { +#[xtest(feature = "_externalize_tests")] +pub fn test_chan_reserve_violation_inbound_htlc_inbound_chan() { let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); @@ -1836,8 +1837,8 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() { [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_inbound_outbound_capacity_is_not_zero() { +#[xtest(feature = "_externalize_tests")] +pub fn test_inbound_outbound_capacity_is_not_zero() { 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]); @@ -1861,8 +1862,8 @@ fn commit_tx_fee_msat(feerate: u32, num_htlcs: u64, channel_type_features: &Chan (commitment_tx_base_weight(channel_type_features) + num_htlcs * COMMITMENT_TX_WEIGHT_PER_HTLC) * feerate as u64 / 1000 * 1000 } -#[test] -fn test_channel_reserve_holding_cell_htlcs() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_reserve_holding_cell_htlcs() { let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); // When this test was written, the default base fee floated based on the HTLC count. @@ -2117,8 +2118,8 @@ fn test_channel_reserve_holding_cell_htlcs() { assert_eq!(stat2.value_to_self_msat, stat22.value_to_self_msat + recv_value_1 + recv_value_21 + recv_value_22 + recv_value_3); } -#[test] -fn channel_reserve_in_flight_removes() { +#[xtest(feature = "_externalize_tests")] +pub fn channel_reserve_in_flight_removes() { // In cases where one side claims an HTLC, it thinks it has additional available funds that it // can send to its counterparty, but due to update ordering, the other side may not yet have // considered those HTLCs fully removed. @@ -2404,8 +2405,8 @@ fn do_test_fail_back_before_backwards_timeout(post_fail_back_action: PostFailBac }; } -#[test] -fn channel_monitor_network_test() { +#[xtest(feature = "_externalize_tests")] +pub fn channel_monitor_network_test() { // Simple test which builds a network of ChannelManagers, connects them to each other, and // tests that ChannelMonitor is able to recover from various states. let chanmon_cfgs = create_chanmon_cfgs(5); @@ -2601,8 +2602,8 @@ fn channel_monitor_network_test() { check_closed_event!(nodes[3], 1, ClosureReason::HTLCsTimedOut, [node_id_4], 100000); } -#[test] -fn test_justice_tx_htlc_timeout() { +#[xtest(feature = "_externalize_tests")] +pub fn test_justice_tx_htlc_timeout() { // Test justice txn built on revoked HTLC-Timeout tx, against both sides let mut alice_config = test_default_channel_config(); alice_config.channel_handshake_config.announce_for_forwarding = true; @@ -2667,8 +2668,8 @@ fn test_justice_tx_htlc_timeout() { assert_eq!(nodes[1].node.list_channels().len(), 0); } -#[test] -fn test_justice_tx_htlc_success() { +#[xtest(feature = "_externalize_tests")] +pub fn test_justice_tx_htlc_success() { // Test justice txn built on revoked HTLC-Success tx, against both sides let mut alice_config = test_default_channel_config(); alice_config.channel_handshake_config.announce_for_forwarding = true; @@ -2724,8 +2725,8 @@ fn test_justice_tx_htlc_success() { assert_eq!(nodes[1].node.list_channels().len(), 0); } -#[test] -fn revoked_output_claim() { +#[xtest(feature = "_externalize_tests")] +pub fn revoked_output_claim() { // Simple test to ensure a node will claim a revoked output when a stale remote commitment // transaction is broadcast by its counterparty let chanmon_cfgs = create_chanmon_cfgs(2); @@ -2757,8 +2758,8 @@ fn revoked_output_claim() { check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed, [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_forming_justice_tx_from_monitor_updates() { +#[xtest(feature = "_externalize_tests")] +pub fn test_forming_justice_tx_from_monitor_updates() { do_test_forming_justice_tx_from_monitor_updates(true); do_test_forming_justice_tx_from_monitor_updates(false); } @@ -2822,8 +2823,8 @@ fn do_test_forming_justice_tx_from_monitor_updates(broadcast_initial_commitment: } -#[test] -fn claim_htlc_outputs() { +#[xtest(feature = "_externalize_tests")] +pub fn claim_htlc_outputs() { // Node revoked old state, htlcs haven't time out yet, claim them in shared justice tx let mut chanmon_cfgs = create_chanmon_cfgs(2); chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true; @@ -2897,7 +2898,7 @@ fn claim_htlc_outputs() { // transaction. // // This is a regression test for https://github.com/lightningdevkit/rust-lightning/issues/3537. -#[test] +#[xtest(feature = "_externalize_tests")] fn test_multiple_package_conflicts() { let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); @@ -3150,8 +3151,8 @@ fn test_multiple_package_conflicts() { ); } -#[test] -fn test_htlc_on_chain_success() { +#[xtest(feature = "_externalize_tests")] +pub fn test_htlc_on_chain_success() { // Test that in case of a unilateral close onchain, we detect the state of output and pass // the preimage backward accordingly. So here we test that ChannelManager is // broadcasting the right event to other nodes in payment path. @@ -3502,15 +3503,15 @@ fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) { assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); } -#[test] -fn test_htlc_on_chain_timeout() { +#[xtest(feature = "_externalize_tests")] +pub fn test_htlc_on_chain_timeout() { do_test_htlc_on_chain_timeout(ConnectStyle::BestBlockFirstSkippingBlocks); do_test_htlc_on_chain_timeout(ConnectStyle::TransactionsFirstSkippingBlocks); do_test_htlc_on_chain_timeout(ConnectStyle::FullBlockViaListen); } -#[test] -fn test_simple_commitment_revoked_fail_backward() { +#[xtest(feature = "_externalize_tests")] +pub fn test_simple_commitment_revoked_fail_backward() { // Test that in case of a revoked commitment tx, we detect the resolution of output by justice tx // and fail backward accordingly. @@ -3801,24 +3802,24 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use assert!(failed_htlcs.contains(&third_payment_hash.0)); } -#[test] -fn test_commitment_revoked_fail_backward_exhaustive_a() { +#[xtest(feature = "_externalize_tests")] +pub fn test_commitment_revoked_fail_backward_exhaustive_a() { do_test_commitment_revoked_fail_backward_exhaustive(false, true, false); do_test_commitment_revoked_fail_backward_exhaustive(true, true, false); do_test_commitment_revoked_fail_backward_exhaustive(false, false, false); do_test_commitment_revoked_fail_backward_exhaustive(true, false, false); } -#[test] -fn test_commitment_revoked_fail_backward_exhaustive_b() { +#[xtest(feature = "_externalize_tests")] +pub fn test_commitment_revoked_fail_backward_exhaustive_b() { do_test_commitment_revoked_fail_backward_exhaustive(false, true, true); do_test_commitment_revoked_fail_backward_exhaustive(true, true, true); do_test_commitment_revoked_fail_backward_exhaustive(false, false, true); do_test_commitment_revoked_fail_backward_exhaustive(true, false, true); } -#[test] -fn fail_backward_pending_htlc_upon_channel_failure() { +#[xtest(feature = "_externalize_tests")] +pub fn fail_backward_pending_htlc_upon_channel_failure() { 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]); @@ -3902,8 +3903,8 @@ fn fail_backward_pending_htlc_upon_channel_failure() { check_added_monitors!(nodes[0], 1); } -#[test] -fn test_htlc_ignore_latest_remote_commitment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_htlc_ignore_latest_remote_commitment() { // Test that HTLC transactions spending the latest remote commitment transaction are simply // ignored if we cannot claim them. This originally tickled an invalid unwrap(). let chanmon_cfgs = create_chanmon_cfgs(2); @@ -3941,8 +3942,8 @@ fn test_htlc_ignore_latest_remote_commitment() { connect_block(&nodes[1], &block); } -#[test] -fn test_force_close_fail_back() { +#[xtest(feature = "_externalize_tests")] +pub fn test_force_close_fail_back() { // Check which HTLCs are failed-backwards on channel force-closure let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); @@ -4023,8 +4024,8 @@ fn test_force_close_fail_back() { check_spends!(htlc_tx, commitment_tx); } -#[test] -fn test_dup_events_on_peer_disconnect() { +#[xtest(feature = "_externalize_tests")] +pub fn test_dup_events_on_peer_disconnect() { // Test that if we receive a duplicative update_fulfill_htlc message after a reconnect we do // not generate a corresponding duplicative PaymentSent event. This did not use to be the case // as we used to generate the event immediately upon receipt of the payment preimage in the @@ -4054,8 +4055,8 @@ fn test_dup_events_on_peer_disconnect() { expect_payment_path_successful!(nodes[0]); } -#[test] -fn test_peer_disconnected_before_funding_broadcasted() { +#[xtest(feature = "_externalize_tests")] +pub fn test_peer_disconnected_before_funding_broadcasted() { // Test that channels are closed with `ClosureReason::DisconnectedPeer` if the peer disconnects // before the funding transaction has been broadcasted, and doesn't reconnect back within time. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -4104,8 +4105,8 @@ fn test_peer_disconnected_before_funding_broadcasted() { , [nodes[0].node.get_our_node_id()], 1000000); } -#[test] -fn test_simple_peer_disconnect() { +#[xtest(feature = "_externalize_tests")] +pub fn test_simple_peer_disconnect() { // Test that we can reconnect when there are no lost messages let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); @@ -4437,24 +4438,24 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2); } -#[test] -fn test_drop_messages_peer_disconnect_a() { +#[xtest(feature = "_externalize_tests")] +pub fn test_drop_messages_peer_disconnect_a() { do_test_drop_messages_peer_disconnect(0, true); do_test_drop_messages_peer_disconnect(0, false); do_test_drop_messages_peer_disconnect(1, false); do_test_drop_messages_peer_disconnect(2, false); } -#[test] -fn test_drop_messages_peer_disconnect_b() { +#[xtest(feature = "_externalize_tests")] +pub fn test_drop_messages_peer_disconnect_b() { do_test_drop_messages_peer_disconnect(3, false); do_test_drop_messages_peer_disconnect(4, false); do_test_drop_messages_peer_disconnect(5, false); do_test_drop_messages_peer_disconnect(6, false); } -#[test] -fn test_channel_ready_without_best_block_updated() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_ready_without_best_block_updated() { // Previously, if we were offline when a funding transaction was locked in, and then we came // back online, calling best_block_updated once followed by transactions_confirmed, we'd not // generate a channel_ready until a later best_block_updated. This tests that we generate the @@ -4479,8 +4480,8 @@ fn test_channel_ready_without_best_block_updated() { nodes[1].node.handle_channel_ready(nodes[0].node.get_our_node_id(), &as_channel_ready); } -#[test] -fn test_channel_monitor_skipping_block_when_channel_manager_is_leading() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_monitor_skipping_block_when_channel_manager_is_leading() { 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]); @@ -4511,8 +4512,8 @@ fn test_channel_monitor_skipping_block_when_channel_manager_is_leading() { nodes[1].node.handle_channel_ready(nodes[0].node.get_our_node_id(), &as_channel_ready); } -#[test] -fn test_channel_monitor_skipping_block_when_channel_manager_is_lagging() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_monitor_skipping_block_when_channel_manager_is_lagging() { 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]); @@ -4546,8 +4547,8 @@ fn test_channel_monitor_skipping_block_when_channel_manager_is_lagging() { nodes[1].node.handle_channel_ready(nodes[0].node.get_our_node_id(), &as_channel_ready); } -#[test] -fn test_drop_messages_peer_disconnect_dual_htlc() { +#[xtest(feature = "_externalize_tests")] +pub fn test_drop_messages_peer_disconnect_dual_htlc() { // Test that we can handle reconnecting when both sides of a channel have pending // commitment_updates when we disconnect. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -4760,8 +4761,8 @@ fn do_test_htlc_timeout(send_partial_mpp: bool) { expect_payment_failed!(nodes[0], our_payment_hash, true, 0x4000 | 15, &expected_failure_data[..]); } -#[test] -fn test_htlc_timeout() { +#[xtest(feature = "_externalize_tests")] +pub fn test_htlc_timeout() { do_test_htlc_timeout(true); do_test_htlc_timeout(false); } @@ -4824,8 +4825,8 @@ fn do_test_holding_cell_htlc_add_timeouts(forwarded_htlc: bool) { } } -#[test] -fn test_holding_cell_htlc_add_timeouts() { +#[xtest(feature = "_externalize_tests")] +pub fn test_holding_cell_htlc_add_timeouts() { do_test_holding_cell_htlc_add_timeouts(false); do_test_holding_cell_htlc_add_timeouts(true); } @@ -4858,8 +4859,8 @@ macro_rules! check_spendable_outputs { } } -#[test] -fn test_claim_sizeable_push_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_claim_sizeable_push_msat() { // Incidentally test SpendableOutput event generation due to detection of to_local output on commitment tx let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -4887,8 +4888,8 @@ fn test_claim_sizeable_push_msat() { assert_eq!(spend_txn[0].input[0].sequence.0, BREAKDOWN_TIMEOUT as u32); } -#[test] -fn test_claim_on_remote_sizeable_push_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_claim_on_remote_sizeable_push_msat() { // Same test as previous, just test on remote commitment tx, as per_commitment_point registration changes following you're funder/fundee and // to_remote output is encumbered by a P2WPKH let chanmon_cfgs = create_chanmon_cfgs(2); @@ -4919,8 +4920,8 @@ fn test_claim_on_remote_sizeable_push_msat() { check_spends!(spend_txn[0], node_txn[0]); } -#[test] -fn test_claim_on_remote_revoked_sizeable_push_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_claim_on_remote_revoked_sizeable_push_msat() { // Same test as previous, just test on remote revoked commitment tx, as per_commitment_point registration changes following you're funder/fundee and // to_remote output is encumbered by a P2WPKH @@ -4952,8 +4953,8 @@ fn test_claim_on_remote_revoked_sizeable_push_msat() { check_spends!(spend_txn[2], revoked_local_txn[0], node_txn[0]); // Both outputs } -#[test] -fn test_static_spendable_outputs_preimage_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_static_spendable_outputs_preimage_tx() { 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]); @@ -4999,8 +5000,8 @@ fn test_static_spendable_outputs_preimage_tx() { check_spends!(spend_txn[0], node_txn[0]); } -#[test] -fn test_static_spendable_outputs_timeout_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_static_spendable_outputs_timeout_tx() { 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]); @@ -5046,7 +5047,7 @@ fn test_static_spendable_outputs_timeout_tx() { check_spends!(spend_txn[2], node_txn[0], commitment_tx[0]); // All outputs } -fn do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(split_tx: bool) { +pub fn do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(split_tx: bool) { 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]); @@ -5093,14 +5094,14 @@ fn do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(split_tx: b check_spends!(spend_txn[0], node_txn[0]); } -#[test] -fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() { do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(true); do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(false); } -#[test] -fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { let mut chanmon_cfgs = create_chanmon_cfgs(2); chanmon_cfgs[0].keys_manager.disable_revocation_policy_check = true; let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -5169,8 +5170,8 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { check_spends!(spend_txn[0], node_txn[0]); } -#[test] -fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { let mut chanmon_cfgs = create_chanmon_cfgs(2); chanmon_cfgs[1].keys_manager.disable_revocation_policy_check = true; let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -5240,8 +5241,8 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { check_spends!(spend_txn[2], revoked_local_txn[0], node_txn[1]); // Both outputs } -#[test] -fn test_onchain_to_onchain_claim() { +#[xtest(feature = "_externalize_tests")] +pub fn test_onchain_to_onchain_claim() { // Test that in case of channel closure, we detect the state of output and claim HTLC // on downstream peer's remote commitment tx. // First, have C claim an HTLC against its own latest commitment transaction. @@ -5358,8 +5359,8 @@ fn test_onchain_to_onchain_claim() { check_added_monitors!(nodes[1], 1); } -#[test] -fn test_duplicate_payment_hash_one_failure_one_success() { +#[xtest(feature = "_externalize_tests")] +pub fn test_duplicate_payment_hash_one_failure_one_success() { // Topology : A --> B --> C --> D // We route 2 payments with same hash between B and C, one will be timeout, the other successfully claim // Note that because C will refuse to generate two payment secrets for the same payment hash, @@ -5504,8 +5505,8 @@ fn test_duplicate_payment_hash_one_failure_one_success() { expect_payment_sent(&nodes[0], our_payment_preimage, None, true, true); } -#[test] -fn test_dynamic_spendable_outputs_local_htlc_success_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_dynamic_spendable_outputs_local_htlc_success_tx() { 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]); @@ -5846,25 +5847,25 @@ fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, anno assert_eq!(bs_updates, if deliver_last_raa { 2 } else if !announce_latest { 3 } else { 4 }); } -#[test] -fn test_fail_backwards_latest_remote_announce_a() { +#[xtest(feature = "_externalize_tests")] +pub fn test_fail_backwards_latest_remote_announce_a() { do_test_fail_backwards_unrevoked_remote_announce(false, true); } -#[test] -fn test_fail_backwards_latest_remote_announce_b() { +#[xtest(feature = "_externalize_tests")] +pub fn test_fail_backwards_latest_remote_announce_b() { do_test_fail_backwards_unrevoked_remote_announce(true, true); } -#[test] -fn test_fail_backwards_previous_remote_announce() { +#[xtest(feature = "_externalize_tests")] +pub fn test_fail_backwards_previous_remote_announce() { do_test_fail_backwards_unrevoked_remote_announce(false, false); // Note that true, true doesn't make sense as it implies we announce a revoked state, which is // tested for in test_commitment_revoked_fail_backward_exhaustive() } -#[test] -fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { 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]); @@ -5911,8 +5912,8 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { spend_txn[2].input[1].sequence.0 == BREAKDOWN_TIMEOUT as u32); } -#[test] -fn test_key_derivation_params() { +#[xtest(feature = "_externalize_tests")] +pub fn test_key_derivation_params() { // This test is a copy of test_dynamic_spendable_outputs_local_htlc_timeout_tx, with a key // manager rotation to test that `channel_keys_id` returned in // [`SpendableOutputDescriptor::DelayedPaymentOutput`] let us re-derive the channel key set to @@ -5999,8 +6000,8 @@ fn test_key_derivation_params() { spend_txn[2].input[1].sequence.0 == BREAKDOWN_TIMEOUT as u32); } -#[test] -fn test_static_output_closing_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_static_output_closing_tx() { 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]); @@ -6156,8 +6157,8 @@ fn do_htlc_claim_previous_remote_commitment_only(use_dust: bool, check_revoke_no // Note that we don't bother testing both outbound and inbound HTLC failures for each case, and we // assume they are handled the same across all six cases, as both outbound and inbound failures are // tested for at least one of the cases in other tests. -#[test] -fn htlc_claim_single_commitment_only_a() { +#[xtest(feature = "_externalize_tests")] +pub fn htlc_claim_single_commitment_only_a() { do_htlc_claim_local_commitment_only(true); do_htlc_claim_local_commitment_only(false); @@ -6165,17 +6166,17 @@ fn htlc_claim_single_commitment_only_a() { do_htlc_claim_current_remote_commitment_only(false); } -#[test] -fn htlc_claim_single_commitment_only_b() { +#[xtest(feature = "_externalize_tests")] +pub fn htlc_claim_single_commitment_only_b() { do_htlc_claim_previous_remote_commitment_only(true, false); do_htlc_claim_previous_remote_commitment_only(false, false); do_htlc_claim_previous_remote_commitment_only(true, true); do_htlc_claim_previous_remote_commitment_only(false, true); } -#[test] +#[xtest(feature = "_externalize_tests")] #[should_panic] -fn bolt2_open_channel_sending_node_checks_part1() { //This test needs to be on its own as we are catching a panic +pub fn bolt2_open_channel_sending_node_checks_part1() { //This test needs to be on its own as we are catching a panic 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]); @@ -6198,8 +6199,8 @@ fn bolt2_open_channel_sending_node_checks_part1() { //This test needs to be on i assert!(nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), channel_value_satoshis, push_msat, 42, None, None).is_err()); } -#[test] -fn bolt2_open_channel_sending_node_checks_part2() { +#[xtest(feature = "_externalize_tests")] +pub fn bolt2_open_channel_sending_node_checks_part2() { 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]); @@ -6243,8 +6244,8 @@ fn bolt2_open_channel_sending_node_checks_part2() { assert!(PublicKey::from_slice(&node0_to_1_send_open_channel.common_fields.delayed_payment_basepoint.serialize()).is_ok()); } -#[test] -fn bolt2_open_channel_sane_dust_limit() { +#[xtest(feature = "_externalize_tests")] +pub fn bolt2_open_channel_sane_dust_limit() { 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]); @@ -6272,8 +6273,8 @@ fn bolt2_open_channel_sane_dust_limit() { // originated from our node, its failure is surfaced to the user. We trigger this failure to // free the HTLC by increasing our fee while the HTLC is in the holding cell such that the HTLC // is no longer affordable once it's freed. -#[test] -fn test_fail_holding_cell_htlc_upon_free() { +#[xtest(feature = "_externalize_tests")] +pub fn test_fail_holding_cell_htlc_upon_free() { 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]); @@ -6352,8 +6353,8 @@ fn test_fail_holding_cell_htlc_upon_free() { // Test that if multiple HTLCs are released from the holding cell and one is // valid but the other is no longer valid upon release, the valid HTLC can be // successfully completed while the other one fails as expected. -#[test] -fn test_free_and_fail_holding_cell_htlcs() { +#[xtest(feature = "_externalize_tests")] +pub fn test_free_and_fail_holding_cell_htlcs() { 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]); @@ -6477,8 +6478,8 @@ fn test_free_and_fail_holding_cell_htlcs() { // HTLC is failed backwards. We trigger this failure to forward the freed HTLC by increasing // our fee while the HTLC is in the holding cell such that the HTLC is no longer affordable // once it's freed. -#[test] -fn test_fail_holding_cell_htlc_upon_free_multihop() { +#[xtest(feature = "_externalize_tests")] +pub fn test_fail_holding_cell_htlc_upon_free_multihop() { let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); // Avoid having to include routing fees in calculations @@ -6606,8 +6607,8 @@ fn test_fail_holding_cell_htlc_upon_free_multihop() { check_added_monitors!(nodes[0], 1); } -#[test] -fn test_payment_route_reaching_same_channel_twice() { +#[xtest(feature = "_externalize_tests")] +pub fn test_payment_route_reaching_same_channel_twice() { //A route should not go through the same channel twice //It is enforced when constructing a route. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -6635,8 +6636,8 @@ fn test_payment_route_reaching_same_channel_twice() { // BOLT 2 Requirement: MUST NOT offer amount_msat it cannot pay for in the remote commitment transaction at the current feerate_per_kw (see "Updating Fees") while maintaining its channel reserve. //TODO: I don't believe this is explicitly enforced when sending an HTLC but as the Fee aspect of the BOLT specs is in flux leaving this as a TODO. -#[test] -fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { //BOLT2 Requirement: MUST NOT offer amount_msat below the receiving node's htlc_minimum_msat (same validation check catches both of these) let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6653,8 +6654,8 @@ fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() { assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); } -#[test] -fn test_update_add_htlc_bolt2_sender_zero_value_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_sender_zero_value_msat() { //BOLT2 Requirement: MUST offer amount_msat greater than 0. let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6673,8 +6674,8 @@ fn test_update_add_htlc_bolt2_sender_zero_value_msat() { nodes[0].logger.assert_log_contains("lightning::ln::channelmanager", "Cannot send 0-msat HTLC", 2); } -#[test] -fn test_update_add_htlc_bolt2_receiver_zero_value_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_receiver_zero_value_msat() { //BOLT2 Requirement: MUST offer amount_msat greater than 0. let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6697,8 +6698,8 @@ fn test_update_add_htlc_bolt2_receiver_zero_value_msat() { [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { //BOLT 2 Requirement: MUST set cltv_expiry less than 500000000. //It is enforced when constructing a route. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -6717,8 +6718,8 @@ fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() { assert_eq!(err, &"Channel CLTV overflowed?")); } -#[test] -fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() { //BOLT 2 Requirement: if result would be offering more than the remote's max_accepted_htlcs HTLCs, in the remote commitment transaction: MUST NOT add an HTLC. //BOLT 2 Requirement: for the first HTLC it offers MUST set id to 0. //BOLT 2 Requirement: MUST increase the value of id by 1 for each successive offer. @@ -6762,8 +6763,8 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); } -#[test] -fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() { //BOLT 2 Requirement: if the sum of total offered HTLCs would exceed the remote's max_htlc_value_in_flight_msat: MUST NOT add an HTLC. let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6788,8 +6789,8 @@ fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() { } // BOLT 2 Requirements for the Receiver when handling an update_add_htlc message. -#[test] -fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() { //BOLT2 Requirement: receiving an amount_msat equal to 0, OR less than its own htlc_minimum_msat -> SHOULD fail the channel. let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6818,8 +6819,8 @@ fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() { check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() { //BOLT2 Requirement: receiving an amount_msat that the sending node cannot afford at the current feerate_per_kw (while maintaining its channel reserve): SHOULD fail the channel let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6854,8 +6855,8 @@ fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() { check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() { //BOLT 2 Requirement: if a sending node adds more than its max_accepted_htlcs HTLCs to its local commitment transaction: SHOULD fail the channel //BOLT 2 Requirement: MUST allow multiple HTLCs with the same payment_hash. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -6901,8 +6902,8 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() { check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() { //OR adds more than its max_htlc_value_in_flight_msat worth of offered HTLCs to its local commitment transaction: SHOULD fail the channel let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6925,8 +6926,8 @@ fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() { check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[0].node.get_our_node_id()], 1000000); } -#[test] -fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() { //BOLT2 Requirement: if sending node sets cltv_expiry to greater or equal to 500000000: SHOULD fail the channel. let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -6949,8 +6950,8 @@ fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() { check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { //BOLT 2 requirement: if the sender did not previously acknowledge the commitment of that HTLC: MUST ignore a repeated id value after a reconnection. // We test this by first testing that that repeated HTLCs pass commitment signature checks // after disconnect and that non-sequential htlc_ids result in a channel failure. @@ -7001,8 +7002,8 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() { //BOLT 2 Requirement: until the corresponding HTLC is irrevocably committed in both sides' commitment transactions: MUST NOT send an update_fulfill_htlc, update_fail_htlc, or update_fail_malformed_htlc. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -7033,8 +7034,8 @@ fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() { check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() { //BOLT 2 Requirement: until the corresponding HTLC is irrevocably committed in both sides' commitment transactions: MUST NOT send an update_fulfill_htlc, update_fail_htlc, or update_fail_malformed_htlc. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -7065,8 +7066,8 @@ fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() { check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() { //BOLT 2 Requirement: until the corresponding HTLC is irrevocably committed in both sides' commitment transactions: MUST NOT send an update_fulfill_htlc, update_fail_htlc, or update_fail_malformed_htlc. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -7097,8 +7098,8 @@ fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() { //BOLT 2 Requirement: A receiving node: if the id does not correspond to an HTLC in its current commitment transaction MUST fail the channel. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -7140,8 +7141,8 @@ fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() { check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_update_fulfill_htlc_bolt2_wrong_preimage() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fulfill_htlc_bolt2_wrong_preimage() { //BOLT 2 Requirement: A receiving node: if the payment_preimage value in update_fulfill_htlc doesn't SHA256 hash to the corresponding HTLC payment_hash MUST fail the channel. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -7183,8 +7184,8 @@ fn test_update_fulfill_htlc_bolt2_wrong_preimage() { check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_message() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_message() { //BOLT 2 Requirement: A receiving node: if the BADONION bit in failure_code is not set for update_fail_malformed_htlc MUST fail the channel. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -7233,8 +7234,8 @@ fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_messag check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: err_msg.data }, [nodes[1].node.get_our_node_id()], 1000000); } -#[test] -fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_update_fail_htlc() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_update_fail_htlc() { //BOLT 2 Requirement: a receiving node which has an outgoing HTLC canceled by update_fail_malformed_htlc: // * MUST return an error in the update_fail_htlc sent to the link which originally sent the HTLC, using the failure_code given and setting the data to sha256_of_onion. @@ -7314,8 +7315,8 @@ fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_upda check_added_monitors!(nodes[1], 1); } -#[test] -fn test_channel_failed_after_message_with_badonion_node_perm_bits_set() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_failed_after_message_with_badonion_node_perm_bits_set() { let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); @@ -7487,8 +7488,8 @@ fn do_test_failure_delay_dust_htlc_local_commitment(announce_latest: bool) { } } -#[test] -fn test_failure_delay_dust_htlc_local_commitment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_failure_delay_dust_htlc_local_commitment() { do_test_failure_delay_dust_htlc_local_commitment(true); do_test_failure_delay_dust_htlc_local_commitment(false); } @@ -7570,15 +7571,15 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { } } -#[test] -fn test_sweep_outbound_htlc_failure_update() { +#[xtest(feature = "_externalize_tests")] +pub fn test_sweep_outbound_htlc_failure_update() { do_test_sweep_outbound_htlc_failure_update(false, true); do_test_sweep_outbound_htlc_failure_update(false, false); do_test_sweep_outbound_htlc_failure_update(true, false); } -#[test] -fn test_user_configurable_csv_delay() { +#[xtest(feature = "_externalize_tests")] +pub fn test_user_configurable_csv_delay() { // We test our channel constructors yield errors when we pass them absurd csv delay let mut low_our_to_self_config = UserConfig::default(); @@ -7656,8 +7657,8 @@ fn test_user_configurable_csv_delay() { } else { assert!(false); } } -#[test] -fn test_check_htlc_underpaying() { +#[xtest(feature = "_externalize_tests")] +pub fn test_check_htlc_underpaying() { // Send payment through A -> B but A is maliciously // sending a probe payment (i.e less than expected value0 // to B, B should refuse payment. @@ -7722,8 +7723,8 @@ fn test_check_htlc_underpaying() { expect_payment_failed!(nodes[0], our_payment_hash, true, 0x4000|15, &expected_failure_data[..]); } -#[test] -fn test_announce_disable_channels() { +#[xtest(feature = "_externalize_tests")] +pub fn test_announce_disable_channels() { // Create 2 channels between A and B. Disconnect B. Call timer_tick_occurred and check for generated // ChannelUpdate. Reconnect B, reestablish and check there is non-generated ChannelUpdate. @@ -7814,8 +7815,8 @@ fn test_announce_disable_channels() { assert!(chans_disabled.is_empty()); } -#[test] -fn test_bump_penalty_txn_on_revoked_commitment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_bump_penalty_txn_on_revoked_commitment() { // In case of penalty txn with too low feerates for getting into mempools, RBF-bump them to be sure // we're able to claim outputs on revoked commitment transaction before timelocks expiration @@ -7909,8 +7910,8 @@ fn test_bump_penalty_txn_on_revoked_commitment() { nodes[1].node.get_and_clear_pending_msg_events(); } -#[test] -fn test_bump_penalty_txn_on_revoked_htlcs() { +#[xtest(feature = "_externalize_tests")] +pub fn test_bump_penalty_txn_on_revoked_htlcs() { // In case of penalty txn with too low feerates for getting into mempools, RBF-bump them to sure // we're able to claim outputs on revoked HTLC transactions before timelocks expiration @@ -8065,8 +8066,8 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { check_added_monitors!(nodes[0], 1); } -#[test] -fn test_bump_penalty_txn_on_remote_commitment() { +#[xtest(feature = "_externalize_tests")] +pub fn test_bump_penalty_txn_on_remote_commitment() { // In case of claim txn with too low feerates for getting into mempools, RBF-bump them to be sure // we're able to claim outputs on remote commitment transaction before timelocks expiration @@ -8177,8 +8178,8 @@ fn test_bump_penalty_txn_on_remote_commitment() { nodes[1].node.get_and_clear_pending_msg_events(); } -#[test] -fn test_counterparty_raa_skip_no_crash() { +#[xtest(feature = "_externalize_tests")] +pub fn test_counterparty_raa_skip_no_crash() { // Previously, if our counterparty sent two RAAs in a row without us having provided a // commitment transaction, we would have happily carried on and provided them the next // commitment transaction based on one RAA forward. This would probably eventually have led to @@ -8230,8 +8231,8 @@ fn test_counterparty_raa_skip_no_crash() { , [nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_bump_txn_sanitize_tracking_maps() { +#[xtest(feature = "_externalize_tests")] +pub fn test_bump_txn_sanitize_tracking_maps() { // Sanitizing pending_claim_request and claimable_outpoints used to be buggy, // verify we clean then right after expiration of ANTI_REORG_DELAY. @@ -8284,8 +8285,8 @@ fn test_bump_txn_sanitize_tracking_maps() { } } -#[test] -fn test_channel_conf_timeout() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_conf_timeout() { // Tests that, for inbound channels, we give up on them if the funding transaction does not // confirm within 2016 blocks, as recommended by BOLT 2. let chanmon_cfgs = create_chanmon_cfgs(2); @@ -8320,8 +8321,8 @@ fn test_channel_conf_timeout() { } } -#[test] -fn test_override_channel_config() { +#[xtest(feature = "_externalize_tests")] +pub fn test_override_channel_config() { 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]); @@ -8339,8 +8340,8 @@ fn test_override_channel_config() { assert_eq!(res.common_fields.to_self_delay, 200); } -#[test] -fn test_override_0msat_htlc_minimum() { +#[xtest(feature = "_externalize_tests")] +pub fn test_override_0msat_htlc_minimum() { let mut zero_config = UserConfig::default(); zero_config.channel_handshake_config.our_htlc_minimum_msat = 0; let chanmon_cfgs = create_chanmon_cfgs(2); @@ -8357,8 +8358,8 @@ fn test_override_0msat_htlc_minimum() { assert_eq!(res.common_fields.htlc_minimum_msat, 1); } -#[test] -fn test_channel_update_has_correct_htlc_maximum_msat() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_update_has_correct_htlc_maximum_msat() { // Tests that the `ChannelUpdate` message has the correct values for `htlc_maximum_msat` set. // Bolt 7 specifies that if present `htlc_maximum_msat`: // 1. MUST be set to less than or equal to the channel capacity. In LDK, this is capped to @@ -8409,8 +8410,8 @@ fn test_channel_update_has_correct_htlc_maximum_msat() { assert_eq!(node_3_chan_update.contents.htlc_maximum_msat, channel_value_90_percent_msat); } -#[test] -fn test_manually_accept_inbound_channel_request() { +#[xtest(feature = "_externalize_tests")] +pub fn test_manually_accept_inbound_channel_request() { let mut manually_accept_conf = UserConfig::default(); manually_accept_conf.manually_accept_inbound_channels = true; manually_accept_conf.channel_handshake_config.minimum_depth = 1; @@ -8519,8 +8520,8 @@ fn test_manually_accept_inbound_channel_request() { get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id()); } -#[test] -fn test_manually_reject_inbound_channel_request() { +#[xtest(feature = "_externalize_tests")] +pub fn test_manually_reject_inbound_channel_request() { let mut manually_accept_conf = UserConfig::default(); manually_accept_conf.manually_accept_inbound_channels = true; let chanmon_cfgs = create_chanmon_cfgs(2); @@ -8559,8 +8560,8 @@ fn test_manually_reject_inbound_channel_request() { assert!(nodes[1].node.get_and_clear_pending_events().is_empty()); } -#[test] -fn test_can_not_accept_inbound_channel_twice() { +#[xtest(feature = "_externalize_tests")] +pub fn test_can_not_accept_inbound_channel_twice() { let mut manually_accept_conf = UserConfig::default(); manually_accept_conf.manually_accept_inbound_channels = true; let chanmon_cfgs = create_chanmon_cfgs(2); @@ -8605,8 +8606,8 @@ fn test_can_not_accept_inbound_channel_twice() { } } -#[test] -fn test_can_not_accept_unknown_inbound_channel() { +#[xtest(feature = "_externalize_tests")] +pub fn test_can_not_accept_unknown_inbound_channel() { let chanmon_cfg = create_chanmon_cfgs(2); let node_cfg = create_node_cfgs(2, &chanmon_cfg); let node_chanmgr = create_node_chanmgrs(2, &node_cfg, &[None, None]); @@ -8623,8 +8624,8 @@ fn test_can_not_accept_unknown_inbound_channel() { } } -#[test] -fn test_onion_value_mpp_set_calculation() { +#[xtest(feature = "_externalize_tests")] +pub fn test_onion_value_mpp_set_calculation() { // Test that we use the onion value `amt_to_forward` when // calculating whether we've reached the `total_msat` of an MPP // by having a routing node forward more than `amt_to_forward` @@ -8796,14 +8797,14 @@ fn do_test_overshoot_mpp(msat_amounts: &[u64], total_msat: u64) { ); } -#[test] -fn test_overshoot_mpp() { +#[xtest(feature = "_externalize_tests")] +pub fn test_overshoot_mpp() { do_test_overshoot_mpp(&[100_000, 101_000], 200_000); do_test_overshoot_mpp(&[100_000, 10_000, 100_000], 200_000); } -#[test] -fn test_simple_mpp() { +#[xtest(feature = "_externalize_tests")] +pub fn test_simple_mpp() { // Simple test of sending a multi-path payment. let chanmon_cfgs = create_chanmon_cfgs(4); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); @@ -8830,8 +8831,8 @@ fn test_simple_mpp() { ); } -#[test] -fn test_preimage_storage() { +#[xtest(feature = "_externalize_tests")] +pub fn test_preimage_storage() { // Simple test of payment preimage storage allowing no client-side storage to claim payments let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -8869,8 +8870,8 @@ fn test_preimage_storage() { } } -#[test] -fn test_bad_secret_hash() { +#[xtest(feature = "_externalize_tests")] +pub fn test_bad_secret_hash() { // Simple test of unregistered payment hash/invalid payment secret handling let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -8935,8 +8936,8 @@ fn test_bad_secret_hash() { expect_payment_failed!(nodes[0], random_payment_hash, true, expected_error_code, expected_error_data); } -#[test] -fn test_update_err_monitor_lockdown() { +#[xtest(feature = "_externalize_tests")] +pub fn test_update_err_monitor_lockdown() { // Our monitor will lock update of local commitment transaction if a broadcastion condition // has been fulfilled (either force-close from Channel or block height requiring a HTLC- // timeout). Trying to update monitor after lockdown should return a ChannelMonitorUpdateStatus @@ -9008,8 +9009,8 @@ fn test_update_err_monitor_lockdown() { assert_eq!(events.len(), 1); } -#[test] -fn test_concurrent_monitor_claim() { +#[xtest(feature = "_externalize_tests")] +pub fn test_concurrent_monitor_claim() { // Watchtower A receives block, broadcasts state N, then channel receives new state N+1, // sending it to both watchtowers, Bob accepts N+1, then receives block and broadcasts // the latest state N+1, Alice rejects state N+1, but Bob has already broadcast it, @@ -9134,8 +9135,8 @@ fn test_concurrent_monitor_claim() { } } -#[test] -fn test_pre_lockin_no_chan_closed_update() { +#[xtest(feature = "_externalize_tests")] +pub fn test_pre_lockin_no_chan_closed_update() { // Test that if a peer closes a channel in response to a funding_created message we don't // generate a channel update (as the channel cannot appear on chain without a funding_signed // message). @@ -9173,8 +9174,8 @@ fn test_pre_lockin_no_chan_closed_update() { [nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_htlc_no_detection() { +#[xtest(feature = "_externalize_tests")] +pub fn test_htlc_no_detection() { // This test is a mutation to underscore the detection logic bug we had // before #653. HTLC value routed is above the remaining balance, thus // inverting HTLC and `to_remote` output. HTLC will come second and @@ -9405,16 +9406,16 @@ fn do_test_onchain_htlc_settlement_after_close(broadcast_alice: bool, go_onchain } } -#[test] -fn test_onchain_htlc_settlement_after_close() { +#[xtest(feature = "_externalize_tests")] +pub fn test_onchain_htlc_settlement_after_close() { do_test_onchain_htlc_settlement_after_close(true, true); do_test_onchain_htlc_settlement_after_close(false, true); // Technically redundant, but may as well do_test_onchain_htlc_settlement_after_close(true, false); do_test_onchain_htlc_settlement_after_close(false, false); } -#[test] -fn test_duplicate_temporary_channel_id_from_different_peers() { +#[xtest(feature = "_externalize_tests")] +pub fn test_duplicate_temporary_channel_id_from_different_peers() { // Tests that we can accept two different `OpenChannel` requests with the same // `temporary_channel_id`, as long as they are from different peers. let chanmon_cfgs = create_chanmon_cfgs(3); @@ -9463,8 +9464,8 @@ fn test_duplicate_temporary_channel_id_from_different_peers() { } } -#[test] -fn test_peer_funding_sidechannel() { +#[xtest(feature = "_externalize_tests")] +pub fn test_peer_funding_sidechannel() { // Test that if a peer somehow learns which txid we'll use for our channel funding before we // receive `funding_transaction_generated` the peer cannot cause us to crash. We'd previously // assumed that LDK would receive `funding_transaction_generated` prior to our peer learning @@ -9518,8 +9519,8 @@ fn test_peer_funding_sidechannel() { get_err_msg(&nodes[0], &nodes[1].node.get_our_node_id()); } -#[test] -fn test_duplicate_conflicting_funding_from_second_peer() { +#[xtest(feature = "_externalize_tests")] +pub fn test_duplicate_conflicting_funding_from_second_peer() { // Test that if a user tries to fund a channel with a channel ID they'd previously used // we don't try to remove the previous ChannelMonitor. This is largely a test to ensure we // don't regress in the fuzzer, as such funding getting passed our channel_id-matches checks @@ -9559,8 +9560,8 @@ fn test_duplicate_conflicting_funding_from_second_peer() { check_closed_events(&nodes[0], &[ExpectedCloseEvent::from_id_reason(temp_chan_id, true, err_reason)]); } -#[test] -fn test_duplicate_funding_err_in_funding() { +#[xtest(feature = "_externalize_tests")] +pub fn test_duplicate_funding_err_in_funding() { // Test that if we have a live channel with one peer, then another peer comes along and tries // to create a second channel with the same txid we'll fail and not overwrite the // outpoint_to_peer map in `ChannelManager`. @@ -9607,8 +9608,8 @@ fn test_duplicate_funding_err_in_funding() { ); } -#[test] -fn test_duplicate_chan_id() { +#[xtest(feature = "_externalize_tests")] +pub fn test_duplicate_chan_id() { // Test that if a given peer tries to open a channel with the same channel_id as one that is // already open we reject it and keep the old channel. // @@ -9765,8 +9766,8 @@ fn test_duplicate_chan_id() { send_payment(&nodes[0], &[&nodes[1]], 8000000); } -#[test] -fn test_error_chans_closed() { +#[xtest(feature = "_externalize_tests")] +pub fn test_error_chans_closed() { // Test that we properly handle error messages, closing appropriate channels. // // Prior to #787 we'd allow a peer to make us force-close a channel we had with a different @@ -9831,8 +9832,8 @@ fn test_error_chans_closed() { assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2); } -#[test] -fn test_invalid_funding_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_invalid_funding_tx() { // Test that we properly handle invalid funding transactions sent to us from a peer. // // Previously, all other major lightning implementations had failed to properly sanitize @@ -9919,8 +9920,8 @@ fn test_invalid_funding_tx() { mine_transaction(&nodes[1], &spend_tx); } -#[test] -fn test_coinbase_funding_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_coinbase_funding_tx() { // Miners are able to fund channels directly from coinbase transactions, however // by consensus rules, outputs of a coinbase transaction are encumbered by a 100 // block maturity timelock. To ensure that a (non-0conf) channel like this is enforceable @@ -10071,8 +10072,8 @@ fn do_test_tx_confirmed_skipping_blocks_immediate_broadcast(test_height_before_t } } -#[test] -fn test_tx_confirmed_skipping_blocks_immediate_broadcast() { +#[xtest(feature = "_externalize_tests")] +pub fn test_tx_confirmed_skipping_blocks_immediate_broadcast() { do_test_tx_confirmed_skipping_blocks_immediate_broadcast(false); do_test_tx_confirmed_skipping_blocks_immediate_broadcast(true); } @@ -10164,8 +10165,8 @@ fn do_test_dup_htlc_second_rejected(test_for_second_fail_panic: bool) { } } -#[test] -fn test_dup_htlc_second_fail_panic() { +#[xtest(feature = "_externalize_tests")] +pub 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 `PaymentClaimable` event. // Then, if the user failed the second payment, they'd hit a "tried to fail an already failed @@ -10173,15 +10174,15 @@ fn test_dup_htlc_second_fail_panic() { do_test_dup_htlc_second_rejected(true); } -#[test] -fn test_dup_htlc_second_rejected() { +#[xtest(feature = "_externalize_tests")] +pub fn test_dup_htlc_second_rejected() { // Test that if we receive a second HTLC for an MPP payment that overruns the payment amount we // simply reject the second HTLC but are still able to claim the first HTLC. do_test_dup_htlc_second_rejected(false); } -#[test] -fn test_inconsistent_mpp_params() { +#[xtest(feature = "_externalize_tests")] +pub fn test_inconsistent_mpp_params() { // Test that if we recieve two HTLCs with different payment parameters we fail back the first // such HTLC and allow the second to stay. let chanmon_cfgs = create_chanmon_cfgs(4); @@ -10291,8 +10292,8 @@ fn test_inconsistent_mpp_params() { expect_payment_sent(&nodes[0], our_payment_preimage, Some(None), true, true); } -#[test] -fn test_double_partial_claim() { +#[xtest(feature = "_externalize_tests")] +pub fn test_double_partial_claim() { // Test what happens if a node receives a payment, generates a PaymentClaimable event, the HTLCs // time out, the sender resends only some of the MPP parts, then the user processes the // PaymentClaimable event, ensuring they don't inadvertently claim only part of the full payment @@ -10593,15 +10594,15 @@ fn do_test_max_dust_htlc_exposure_by_threshold_type(multiplier_dust_limit: bool, } } -#[test] -fn test_max_dust_htlc_exposure() { +#[xtest(feature = "_externalize_tests")] +pub fn test_max_dust_htlc_exposure() { do_test_max_dust_htlc_exposure_by_threshold_type(false, false); do_test_max_dust_htlc_exposure_by_threshold_type(false, true); do_test_max_dust_htlc_exposure_by_threshold_type(true, false); do_test_max_dust_htlc_exposure_by_threshold_type(true, true); } -#[test] +#[xtest(feature = "_externalize_tests")] fn test_nondust_htlc_excess_fees_are_dust() { // Test that the excess transaction fees paid in nondust HTLCs count towards our dust limit const DEFAULT_FEERATE: u32 = 253; @@ -10955,8 +10956,8 @@ fn test_nondust_htlc_fees_dust_exposure_delta() { do_test_nondust_htlc_fees_dust_exposure_delta(ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies()); } -#[test] -fn test_non_final_funding_tx() { +#[xtest(feature = "_externalize_tests")] +pub fn test_non_final_funding_tx() { 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]); @@ -10995,8 +10996,8 @@ fn test_non_final_funding_tx() { assert_eq!(get_err_msg(&nodes[0], &nodes[1].node.get_our_node_id()).data, "Failed to fund channel"); } -#[test] -fn test_non_final_funding_tx_within_headroom() { +#[xtest(feature = "_externalize_tests")] +pub fn test_non_final_funding_tx_within_headroom() { 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]); @@ -11029,8 +11030,8 @@ fn test_non_final_funding_tx_within_headroom() { get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); } -#[test] -fn accept_busted_but_better_fee() { +#[xtest(feature = "_externalize_tests")] +pub fn accept_busted_but_better_fee() { // If a peer sends us a fee update that is too low, but higher than our previous channel // feerate, we should accept it. In the future we may want to consider closing the channel // later, but for now we only accept the update. @@ -11158,16 +11159,16 @@ fn do_payment_with_custom_min_final_cltv_expiry(valid_delta: bool, use_user_hash } } -#[test] -fn test_payment_with_custom_min_cltv_expiry_delta() { +#[xtest(feature = "_externalize_tests")] +pub fn test_payment_with_custom_min_cltv_expiry_delta() { do_payment_with_custom_min_final_cltv_expiry(false, false); do_payment_with_custom_min_final_cltv_expiry(false, true); do_payment_with_custom_min_final_cltv_expiry(true, false); do_payment_with_custom_min_final_cltv_expiry(true, true); } -#[test] -fn test_disconnects_peer_awaiting_response_ticks() { +#[xtest(feature = "_externalize_tests")] +pub fn test_disconnects_peer_awaiting_response_ticks() { // Tests that nodes which are awaiting on a response critical for channel responsiveness // disconnect their counterparty after `DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`. let mut chanmon_cfgs = create_chanmon_cfgs(2); @@ -11295,8 +11296,8 @@ fn test_disconnects_peer_awaiting_response_ticks() { } } -#[test] -fn test_remove_expired_outbound_unfunded_channels() { +#[xtest(feature = "_externalize_tests")] +pub fn test_remove_expired_outbound_unfunded_channels() { 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]); @@ -11346,8 +11347,8 @@ fn test_remove_expired_outbound_unfunded_channels() { check_closed_event(&nodes[0], 1, ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }, false, &[nodes[1].node.get_our_node_id()], 100000); } -#[test] -fn test_remove_expired_inbound_unfunded_channels() { +#[xtest(feature = "_externalize_tests")] +pub fn test_remove_expired_inbound_unfunded_channels() { 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]); @@ -11397,8 +11398,8 @@ fn test_remove_expired_inbound_unfunded_channels() { check_closed_event(&nodes[1], 1, ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }, false, &[nodes[0].node.get_our_node_id()], 100000); } -#[test] -fn test_channel_close_when_not_timely_accepted() { +#[xtest(feature = "_externalize_tests")] +pub fn test_channel_close_when_not_timely_accepted() { // Create network of two nodes let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -11440,8 +11441,8 @@ fn test_channel_close_when_not_timely_accepted() { } } -#[test] -fn test_rebroadcast_open_channel_when_reconnect_mid_handshake() { +#[xtest(feature = "_externalize_tests")] +pub fn test_rebroadcast_open_channel_when_reconnect_mid_handshake() { // Create network of two nodes let chanmon_cfgs = create_chanmon_cfgs(2); let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); @@ -11562,14 +11563,14 @@ fn do_test_multi_post_event_actions(do_reload: bool) { check_added_monitors(&nodes[0], 3); } -#[test] -fn test_multi_post_event_actions() { +#[xtest(feature = "_externalize_tests")] +pub fn test_multi_post_event_actions() { do_test_multi_post_event_actions(true); do_test_multi_post_event_actions(false); } -#[test] -fn test_batch_channel_open() { +#[xtest(feature = "_externalize_tests")] +pub fn test_batch_channel_open() { let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); @@ -11636,8 +11637,8 @@ fn test_batch_channel_open() { ))); } -#[test] -fn test_close_in_funding_batch() { +#[xtest(feature = "_externalize_tests")] +pub fn test_close_in_funding_batch() { // This test ensures that if one of the channels // in the batch closes, the complete batch will close. let chanmon_cfgs = create_chanmon_cfgs(3); @@ -11718,8 +11719,8 @@ fn test_close_in_funding_batch() { assert!(nodes[0].node.list_channels().is_empty()); } -#[test] -fn test_batch_funding_close_after_funding_signed() { +#[xtest(feature = "_externalize_tests")] +pub fn test_batch_funding_close_after_funding_signed() { let chanmon_cfgs = create_chanmon_cfgs(3); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); @@ -11860,14 +11861,14 @@ fn do_test_funding_and_commitment_tx_confirm_same_block(confirm_remote_commitmen assert!(nodes[1].node.list_channels().is_empty()); } -#[test] -fn test_funding_and_commitment_tx_confirm_same_block() { +#[xtest(feature = "_externalize_tests")] +pub fn test_funding_and_commitment_tx_confirm_same_block() { do_test_funding_and_commitment_tx_confirm_same_block(false); do_test_funding_and_commitment_tx_confirm_same_block(true); } -#[test] -fn test_accept_inbound_channel_errors_queued() { +#[xtest(feature = "_externalize_tests")] +pub fn test_accept_inbound_channel_errors_queued() { // For manually accepted inbound channels, tests that a close error is correctly handled // and the channel fails for the initiator. let mut config0 = test_default_channel_config(); @@ -11899,8 +11900,8 @@ fn test_accept_inbound_channel_errors_queued() { open_channel_msg.common_fields.temporary_channel_id); } -#[test] -fn test_manual_funding_abandon() { +#[xtest(feature = "_externalize_tests")] +pub fn test_manual_funding_abandon() { let mut cfg = UserConfig::default(); cfg.channel_handshake_config.minimum_depth = 1; let chanmon_cfgs = create_chanmon_cfgs(2); @@ -11941,7 +11942,7 @@ fn test_manual_funding_abandon() { })); } -#[test] +#[xtest(feature = "_externalize_tests")] fn test_funding_signed_event() { let mut cfg = UserConfig::default(); cfg.channel_handshake_config.minimum_depth = 1; diff --git a/lightning/src/ln/invoice_utils.rs b/lightning/src/ln/invoice_utils.rs index 5be0b3f4b..da3d370d7 100644 --- a/lightning/src/ln/invoice_utils.rs +++ b/lightning/src/ln/invoice_utils.rs @@ -720,6 +720,7 @@ mod test { use crate::util::test_utils; use crate::util::config::UserConfig; use std::collections::HashSet; + use crate::util::dyn_signer::{DynKeysInterface, DynPhantomKeysInterface}; #[test] fn test_prefer_current_channel() { @@ -1239,6 +1240,13 @@ mod test { do_test_multi_node_receive(false); } + fn make_dyn_keys_interface(seed: &[u8; 32]) -> DynKeysInterface { + let cross_node_seed = [44u8; 32]; + let inner = PhantomKeysManager::new(&seed, 43, 44, &cross_node_seed); + let dyn_inner = DynPhantomKeysInterface::new(inner); + DynKeysInterface::new(Box::new(dyn_inner)) + } + fn do_test_multi_node_receive(user_generated_pmt_hash: bool) { use crate::events::{Event, EventsProvider}; use core::cell::RefCell; @@ -1246,9 +1254,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(3); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); let nodes = create_network(3, &node_cfgs, &node_chanmgrs); @@ -1350,9 +1357,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(3); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); let nodes = create_network(3, &node_cfgs, &node_chanmgrs); @@ -1441,9 +1447,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(3); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); let nodes = create_network(3, &node_cfgs, &node_chanmgrs); @@ -1469,9 +1474,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(4); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[3].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[3].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); @@ -1499,9 +1503,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(4); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[3].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[3].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); @@ -1556,9 +1559,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(3); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); let nodes = create_network(3, &node_cfgs, &node_chanmgrs); @@ -1588,9 +1590,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(4); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); @@ -1621,9 +1622,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(3); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); let nodes = create_network(3, &node_cfgs, &node_chanmgrs); @@ -1651,9 +1651,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(4); let seed_1 = [42u8; 32]; let seed_2 = [43u8; 32]; - let cross_node_seed = [44u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(4, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]); let nodes = create_network(4, &node_cfgs, &node_chanmgrs); @@ -1726,11 +1725,10 @@ mod test { let seed_2 = [43 as u8; 32]; let seed_3 = [44 as u8; 32]; let seed_4 = [45 as u8; 32]; - let cross_node_seed = [44 as u8; 32]; - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[3].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); - chanmon_cfgs[4].keys_manager.backing = PhantomKeysManager::new(&seed_3, 43, 44, &cross_node_seed); - chanmon_cfgs[5].keys_manager.backing = PhantomKeysManager::new(&seed_4, 43, 44, &cross_node_seed); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[3].keys_manager.backing = make_dyn_keys_interface(&seed_2); + chanmon_cfgs[4].keys_manager.backing = make_dyn_keys_interface(&seed_3); + chanmon_cfgs[4].keys_manager.backing = make_dyn_keys_interface(&seed_4); 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); @@ -1783,9 +1781,8 @@ mod test { let mut chanmon_cfgs = create_chanmon_cfgs(5); let seed_1 = [42 as u8; 32]; let seed_2 = [43 as u8; 32]; - let cross_node_seed = [44 as u8; 32]; - chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); - chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); + chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); + chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2); let node_cfgs = create_node_cfgs(5, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(5, &node_cfgs, &[None, None, None, None, None]); let nodes = create_network(5, &node_cfgs, &node_chanmgrs); diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index b55ae8ac5..da8efeb17 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -58,9 +58,9 @@ mod blinded_payment_tests; #[cfg(all(test, async_payments))] #[allow(unused_mut)] mod async_payments_tests; -#[cfg(test)] +#[cfg(any(test, feature = "_externalize_tests"))] #[allow(unused_mut)] -mod functional_tests; +pub mod functional_tests; #[cfg(test)] #[allow(unused_mut)] mod max_payment_path_len_tests; diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index d5b60b00e..eed522690 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -2324,8 +2324,8 @@ fn do_test_restored_packages_retry(check_old_monitor_retries_after_upgrade: bool let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); // Reset our RNG counters to mirror the RNG output from when this test was written. - nodes[0].keys_manager.backing.inner.entropy_source.set_counter(0x1_0000_0004); - nodes[1].keys_manager.backing.inner.entropy_source.set_counter(0x1_0000_0004); + nodes[0].keys_manager.backing.inner.set_counter(0x1_0000_0004); + nodes[1].keys_manager.backing.inner.set_counter(0x1_0000_0004); // Open a channel, lock in an HTLC, and immediately broadcast the commitment transaction. This // ensures that the HTLC timeout package is held until we reach its expiration height. diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index a76cd5caa..9c01ce08c 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -925,9 +925,9 @@ pub(crate) struct DecodedOnionFailure { pub(crate) short_channel_id: Option, pub(crate) payment_failed_permanently: bool, pub(crate) failed_within_blinded_path: bool, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub(crate) onion_error_code: Option, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub(crate) onion_error_data: Option>, } @@ -1211,9 +1211,9 @@ where short_channel_id, payment_failed_permanently, failed_within_blinded_path, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] onion_error_code: error_code_ret, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] onion_error_data: error_packet_ret, } } else { @@ -1224,9 +1224,9 @@ where short_channel_id: None, payment_failed_permanently: is_from_final_node, failed_within_blinded_path: false, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] onion_error_code: None, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] onion_error_data: None, } } @@ -1382,9 +1382,9 @@ impl HTLCFailReason { payment_failed_permanently: false, short_channel_id: Some(path.hops[0].short_channel_id), failed_within_blinded_path: false, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] onion_error_code: Some(*failure_code), - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] onion_error_data: Some(data.clone()), } } else { diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index f56795cf5..15a370592 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -1546,9 +1546,9 @@ impl OutboundPayments { failure: events::PathFailure::InitialSend { err: e }, path, short_channel_id: failed_scid, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_code: None, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_data: None, }, None)); } @@ -1643,7 +1643,7 @@ impl OutboundPayments { } } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(super) fn test_add_new_pending_payment( &self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, payment_id: PaymentId, route: &Route, retry_strategy: Option, entropy_source: &ES, best_block_height: u32 @@ -1901,7 +1901,7 @@ impl OutboundPayments { } } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(super) fn test_send_payment_internal( &self, route: &Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, keysend_preimage: Option, payment_id: PaymentId, recv_value_msat: Option, @@ -2099,12 +2099,12 @@ impl OutboundPayments { probing_cookie_secret: [u8; 32], secp_ctx: &Secp256k1, pending_events: &Mutex)>>, logger: &L, ) -> bool where L::Target: Logger { - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] let DecodedOnionFailure { network_update, short_channel_id, payment_failed_permanently, onion_error_code, onion_error_data, failed_within_blinded_path } = onion_error.decode_onion_failure(secp_ctx, logger, &source); - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] let DecodedOnionFailure { network_update, short_channel_id, payment_failed_permanently, failed_within_blinded_path } = onion_error.decode_onion_failure(secp_ctx, logger, &source); @@ -2212,9 +2212,9 @@ impl OutboundPayments { failure: events::PathFailure::OnPath { network_update }, path: path.clone(), short_channel_id, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_code: onion_error_code, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] error_data: onion_error_data } } diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index f56f85eaf..d3442674b 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -47,7 +47,7 @@ impl TestEq for T {} /// variant contains a message from [`msgs`] or otherwise the message type if unknown. #[allow(missing_docs)] #[derive(Debug)] -#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))] pub(crate) enum Message { Init(msgs::Init), Error(msgs::ErrorMessage), diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 012b79780..ce5a37f1b 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -1293,7 +1293,7 @@ where } } - #[cfg(test)] + #[cfg(any(test, feature = "_externalize_tests"))] pub(crate) fn set_offers_handler(&mut self, offers_handler: OMH) { self.offers_handler = offers_handler; } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 017496f26..f4efe5b8c 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -25,6 +25,7 @@ use crate::offers::invoice::Bolt12Invoice; use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId}; use crate::routing::scoring::{ChannelUsage, LockableScore, ScoreLookUp}; use crate::sign::EntropySource; +#[cfg(any(test, feature = "_test_utils"))] use crate::sync::Mutex; use crate::util::ser::{Writeable, Readable, ReadableArgs, Writer}; use crate::util::logger::Logger; @@ -189,17 +190,20 @@ impl>, L: Deref, ES: Deref, S: Deref, SP: Size /// A `Router` that returns a fixed route one time, erroring otherwise. Useful for /// `ChannelManager::send_payment_with_route` to support sending to specific routes without /// requiring a custom `Router` implementation. +#[cfg(any(test, feature = "_test_utils"))] pub(crate) struct FixedRouter { // Use an `Option` to avoid needing to clone the route when `find_route` is called. route: Mutex>, } +#[cfg(any(test, feature = "_test_utils"))] impl FixedRouter { pub(crate) fn new(route: Route) -> Self { Self { route: Mutex::new(Some(route)) } } } +#[cfg(any(test, feature = "_test_utils"))] impl Router for FixedRouter { fn find_route( &self, _payer: &PublicKey, _route_params: &RouteParameters, diff --git a/lightning/src/util/test_channel_signer.rs b/lightning/src/util/test_channel_signer.rs index b65560fb9..c439ac66c 100644 --- a/lightning/src/util/test_channel_signer.rs +++ b/lightning/src/util/test_channel_signer.rs @@ -15,7 +15,7 @@ use crate::ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSH use crate::ln::channel_keys::HtlcKey; use crate::ln::msgs; use crate::sign::ecdsa::EcdsaChannelSigner; -use crate::sign::{ChannelSigner, InMemorySigner}; +use crate::sign::ChannelSigner; use crate::types::payment::PaymentPreimage; #[allow(unused_imports)] @@ -36,6 +36,7 @@ use crate::ln::msgs::PartialSignatureWithNonce; #[cfg(taproot)] use crate::sign::taproot::TaprootChannelSigner; use crate::sign::HTLCDescriptor; +use crate::util::dyn_signer::DynSigner; use bitcoin::secp256k1; #[cfg(taproot)] use bitcoin::secp256k1::All; @@ -68,7 +69,7 @@ pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48; /// forwards-compatibility prefix/suffixes! #[derive(Clone)] pub struct TestChannelSigner { - pub inner: InMemorySigner, + pub inner: DynSigner, /// Channel state used for policy enforcement pub state: Arc>, pub disable_revocation_policy_check: bool, @@ -119,7 +120,7 @@ impl PartialEq for TestChannelSigner { impl TestChannelSigner { /// Construct an TestChannelSigner - pub fn new(inner: InMemorySigner) -> Self { + pub fn new(inner: DynSigner) -> Self { let state = Arc::new(Mutex::new(EnforcementState::new())); Self { inner, state, disable_revocation_policy_check: false } } @@ -130,7 +131,7 @@ impl TestChannelSigner { /// so that all copies are aware of enforcement state. A pointer to this state is provided /// here, usually by an implementation of KeysInterface. pub fn new_with_revoked( - inner: InMemorySigner, state: Arc>, + inner: DynSigner, state: Arc>, disable_revocation_policy_check: bool, ) -> Self { Self { inner, state, disable_revocation_policy_check } diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index b214e9d94..cfe96666c 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -13,7 +13,7 @@ use crate::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs}; use crate::chain; use crate::chain::chaininterface; use crate::chain::chaininterface::ConfirmationTarget; -#[cfg(any(test, feature = "_test_utils"))] +#[cfg(any(test, feature = "_externalize_tests"))] use crate::chain::chaininterface::FEERATE_FLOOR_SATS_PER_KW; use crate::chain::chainmonitor::{ChainMonitor, Persist}; use crate::chain::channelmonitor::{ @@ -23,7 +23,7 @@ use crate::chain::transaction::OutPoint; use crate::chain::WatchedOutput; use crate::events; use crate::events::bump_transaction::{Utxo, WalletSource}; -#[cfg(any(test, feature = "_test_utils"))] +#[cfg(any(test, feature = "_externalize_tests"))] use crate::ln::chan_utils::CommitmentTransaction; use crate::ln::channel_state::ChannelDetails; use crate::ln::channelmanager; @@ -50,13 +50,15 @@ use crate::sign::ChannelSigner; use crate::sync::RwLock; use crate::types::features::{ChannelFeatures, InitFeatures, NodeFeatures}; use crate::util::config::UserConfig; +use crate::util::dyn_signer::{ + DynKeysInterface, DynKeysInterfaceTrait, DynPhantomKeysInterface, DynSigner, +}; use crate::util::logger::{Logger, Record}; #[cfg(feature = "std")] use crate::util::mut_global::MutGlobal; use crate::util::persist::{KVStore, MonitorName}; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer}; use crate::util::test_channel_signer::{EnforcementState, TestChannelSigner}; -use crate::util::dyn_signer::{DynPhantomKeysInterface, DynSigner, DynKeysInterfaceTrait}; use bitcoin::amount::Amount; use bitcoin::block::Block; @@ -509,14 +511,14 @@ impl<'a> chain::Watch for TestChainMonitor<'a> { } } -#[cfg(any(test, feature = "_test_utils"))] +#[cfg(any(test, feature = "_externalize_tests"))] struct JusticeTxData { justice_tx: Transaction, value: Amount, commitment_number: u64, } -#[cfg(any(test, feature = "_test_utils"))] +#[cfg(any(test, feature = "_externalize_tests"))] pub(crate) struct WatchtowerPersister { persister: TestPersister, /// Upon a new commitment_signed, we'll get a @@ -530,7 +532,7 @@ pub(crate) struct WatchtowerPersister { destination_script: ScriptBuf, } -#[cfg(any(test, feature = "_test_utils"))] +#[cfg(any(test, feature = "_externalize_tests"))] impl WatchtowerPersister { pub(crate) fn new(destination_script: ScriptBuf) -> Self { let unsigned_justice_tx_data = Mutex::new(new_hash_map()); @@ -573,7 +575,7 @@ impl WatchtowerPersister { } } -#[cfg(any(test, feature = "_test_utils"))] +#[cfg(any(test, feature = "_externalize_tests"))] impl Persist for WatchtowerPersister { fn persist_new_channel( &self, monitor_name: MonitorName, data: &ChannelMonitor, @@ -951,7 +953,7 @@ impl TestChannelMessageHandler { !msgs.as_ref().unwrap().is_empty(), "Received message when we weren't expecting one" ); - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] assert_eq!(msgs.as_ref().unwrap()[0], _ev); msgs.as_mut().unwrap().remove(0); } @@ -1487,7 +1489,7 @@ impl NodeSigner for TestNodeSigner { } pub struct TestKeysInterface { - pub backing: sign::PhantomKeysManager, + pub backing: DynKeysInterface, pub override_random_bytes: Mutex>, pub disable_revocation_policy_check: bool, enforcement_states: Mutex>>>, @@ -1581,30 +1583,42 @@ impl SignerProvider for TestKeysInterface { } #[cfg(feature = "std")] -pub static SIGNER_FACTORY: MutGlobal> = MutGlobal::new(|| { Arc::new(DefaultSignerFactory()) }); +pub static SIGNER_FACTORY: MutGlobal> = + MutGlobal::new(|| Arc::new(DefaultSignerFactory())); pub trait TestSignerFactory: Send + Sync { /// Make a dynamic signer - fn make_signer(&self, seed: &[u8; 32], now: Duration) -> Box>; + fn make_signer( + &self, seed: &[u8; 32], now: Duration, + ) -> Box>; } #[derive(Clone)] struct DefaultSignerFactory(); impl TestSignerFactory for DefaultSignerFactory { - fn make_signer(&self, seed: &[u8; 32], now: Duration) -> Box> { + fn make_signer( + &self, seed: &[u8; 32], now: Duration, + ) -> Box> { let phantom = sign::PhantomKeysManager::new(seed, now.as_secs(), now.subsec_nanos(), seed); let dphantom = DynPhantomKeysInterface::new(phantom); - let backing = Box::new(dphantom) as Box>; + let backing = Box::new(dphantom) as Box>; backing } } impl TestKeysInterface { pub fn new(seed: &[u8; 32], network: Network) -> Self { + #[cfg(feature = "std")] + let factory = SIGNER_FACTORY.get(); + + #[cfg(not(feature = "std"))] + let factory = DefaultSignerFactory(); + let now = Duration::from_secs(genesis_block(network).header.time as u64); + let backing = factory.make_signer(seed, now); Self { - backing: sign::PhantomKeysManager::new(seed, now.as_secs(), now.subsec_nanos(), seed), + backing: DynKeysInterface::new(backing), override_random_bytes: Mutex::new(None), disable_revocation_policy_check: false, enforcement_states: Mutex::new(new_hash_map()),