From 683e849286bf622445795918e05744032c3d20e6 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 2 Feb 2025 16:17:01 +0000 Subject: [PATCH 1/5] Correct `ChannelManager` `in_flight_monitor_updates` serialization In e8854f9a0713c63967b5ec1aae3fbb7e4dcc8eaf we changed the type of `ChannelManager::in_flight_monitor_updates`, writing a legacy version and reading the new version as a new TLV field. Sadly, we spuriously marked the new TLV as `required`, breaking upgrade from 0.1. Here we fix the oversight by simply marking it `option`al. --- lightning/src/ln/channelmanager.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 170d8261d5a..722b60e189d 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -13566,7 +13566,7 @@ where (13, htlc_onion_fields, optional_vec), (14, decode_update_add_htlcs_opt, option), (15, self.inbound_payment_id_secret, required), - (17, in_flight_monitor_updates, required), + (17, in_flight_monitor_updates, option), (19, peer_storage_dir, optional_vec), }); @@ -14097,7 +14097,7 @@ where (13, claimable_htlc_onion_fields, optional_vec), (14, decode_update_add_htlcs, option), (15, inbound_payment_id_secret, option), - (17, in_flight_monitor_updates, required), + (17, in_flight_monitor_updates, option), (19, peer_storage_dir, optional_vec), }); let mut decode_update_add_htlcs = decode_update_add_htlcs.unwrap_or_else(|| new_hash_map()); From 5f247a6fdd53b9e047122f8d85081bce25465f09 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 2 Feb 2025 17:09:47 +0000 Subject: [PATCH 2/5] Clean up `full_stack_target` `InMemorySigner` builder The code was a bit too long to begin with, and rustfmt made a total mess of it, so instead we should be building with more intermediate variables. --- fuzz/src/full_stack.rs | 98 +++++++++--------------------------------- 1 file changed, 21 insertions(+), 77 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 5281a933526..adca93f08df 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -443,85 +443,29 @@ impl SignerProvider for KeyProvider { [ctr; 32] } - fn derive_channel_signer(&self, channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { + fn derive_channel_signer(&self, keys_id: [u8; 32]) -> Self::EcdsaSigner { let secp_ctx = Secp256k1::signing_only(); - let ctr = channel_keys_id[0]; + let ctr = keys_id[0]; let (inbound, state) = self.signer_state.borrow().get(&ctr).unwrap().clone(); - TestChannelSigner::new_with_revoked( - DynSigner::new(if inbound { - InMemorySigner::new( - &secp_ctx, - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, ctr, - ]) - .unwrap(), - [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, ctr, - ], - channel_keys_id, - channel_keys_id, - ) - } else { - InMemorySigner::new( - &secp_ctx, - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 8, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10, ctr, - ]) - .unwrap(), - SecretKey::from_slice(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 11, ctr, - ]) - .unwrap(), - [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, ctr, - ], - channel_keys_id, - channel_keys_id, - ) - }), - state, - false, - ) + + let (a, b, c, d, e, f); + let mut key = [0; 32]; + key[31] = ctr; + key[30] = 1 + if inbound { 0 } else { 6 }; + a = SecretKey::from_slice(&key).unwrap(); + key[30] = 2 + if inbound { 0 } else { 6 }; + b = SecretKey::from_slice(&key).unwrap(); + key[30] = 3 + if inbound { 0 } else { 6 }; + c = SecretKey::from_slice(&key).unwrap(); + key[30] = 4 + if inbound { 0 } else { 6 }; + d = SecretKey::from_slice(&key).unwrap(); + key[30] = 5 + if inbound { 0 } else { 6 }; + e = SecretKey::from_slice(&key).unwrap(); + key[30] = 6 + if inbound { 0 } else { 6 }; + f = key; + let signer = InMemorySigner::new(&secp_ctx, a, b, c, d, e, f, keys_id, keys_id); + + TestChannelSigner::new_with_revoked(DynSigner::new(signer), state, false) } fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result { From 3b08fea069d1e7e6e5e883c6bdf6093d3addfd1d Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 2 Feb 2025 16:28:51 +0000 Subject: [PATCH 3/5] Optionally disable all state-based policy checks in test signer The signer we use in tests tracks the state of the channel and refuses to sign when the channel attempts an invalid state transition. In the next commit, however, we'll add an upgrade test which will fail these checks as the the state won't get copied from previous versions of LDK to this version. Thus, here, we add the ability to disable all state-based checks in the signer. --- fuzz/src/chanmon_consistency.rs | 2 +- fuzz/src/full_stack.rs | 2 +- lightning/src/util/test_channel_signer.rs | 90 +++++++++++++---------- lightning/src/util/test_utils.rs | 7 +- 4 files changed, 59 insertions(+), 42 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 8b41c53a635..7c3700f85f5 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -380,7 +380,7 @@ impl SignerProvider for KeyProvider { ); let revoked_commitment = self.make_enforcement_state_cell(keys.commitment_seed); let keys = DynSigner::new(keys); - TestChannelSigner::new_with_revoked(keys, revoked_commitment, false) + TestChannelSigner::new_with_revoked(keys, revoked_commitment, false, false) } fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result { diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index adca93f08df..4291534a868 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -465,7 +465,7 @@ impl SignerProvider for KeyProvider { f = key; let signer = InMemorySigner::new(&secp_ctx, a, b, c, d, e, f, keys_id, keys_id); - TestChannelSigner::new_with_revoked(DynSigner::new(signer), state, false) + TestChannelSigner::new_with_revoked(DynSigner::new(signer), state, false, false) } fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result { diff --git a/lightning/src/util/test_channel_signer.rs b/lightning/src/util/test_channel_signer.rs index ea6451157cc..e619069af50 100644 --- a/lightning/src/util/test_channel_signer.rs +++ b/lightning/src/util/test_channel_signer.rs @@ -74,6 +74,7 @@ pub struct TestChannelSigner { /// Channel state used for policy enforcement pub state: Arc>, pub disable_revocation_policy_check: bool, + pub disable_all_state_policy_checks: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -123,7 +124,12 @@ impl TestChannelSigner { /// Construct an TestChannelSigner pub fn new(inner: DynSigner) -> Self { let state = Arc::new(Mutex::new(EnforcementState::new())); - Self { inner, state, disable_revocation_policy_check: false } + Self { + inner, + state, + disable_revocation_policy_check: false, + disable_all_state_policy_checks: false, + } } /// Construct an TestChannelSigner with externally managed storage @@ -133,9 +139,9 @@ impl TestChannelSigner { /// here, usually by an implementation of KeysInterface. pub fn new_with_revoked( inner: DynSigner, state: Arc>, - disable_revocation_policy_check: bool, + disable_revocation_policy_check: bool, disable_all_state_policy_checks: bool, ) -> Self { - Self { inner, state, disable_revocation_policy_check } + Self { inner, state, disable_revocation_policy_check, disable_all_state_policy_checks } } #[cfg(any(test, feature = "_test_utils"))] @@ -175,12 +181,12 @@ impl ChannelSigner for TestChannelSigner { if !self.is_signer_available(SignerOp::ReleaseCommitmentSecret) { return Err(()); } - { - let mut state = self.state.lock().unwrap(); + let mut state = self.state.lock().unwrap(); + if !self.disable_all_state_policy_checks { assert!(idx == state.last_holder_revoked_commitment || idx == state.last_holder_revoked_commitment - 1, "can only revoke the current or next unrevoked commitment - trying {}, last revoked {}", idx, state.last_holder_revoked_commitment); assert!(idx > state.last_holder_commitment, "cannot revoke the last holder commitment - attempted to revoke {} last commitment {}", idx, state.last_holder_commitment); - state.last_holder_revoked_commitment = idx; } + state.last_holder_revoked_commitment = idx; self.inner.release_commitment_secret(idx) } @@ -190,12 +196,14 @@ impl ChannelSigner for TestChannelSigner { ) -> Result<(), ()> { let mut state = self.state.lock().unwrap(); let idx = holder_tx.commitment_number(); - assert!( - idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1, - "expecting to validate the current or next holder commitment - trying {}, current {}", - idx, - state.last_holder_commitment - ); + if !self.disable_all_state_policy_checks { + assert!( + idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1, + "expecting to validate the current or next holder commitment - trying {}, current {}", + idx, + state.last_holder_commitment + ); + } state.last_holder_commitment = idx; Ok(()) } @@ -206,7 +214,9 @@ impl ChannelSigner for TestChannelSigner { return Err(()); } let mut state = self.state.lock().unwrap(); - assert!(idx == state.last_counterparty_revoked_commitment || idx == state.last_counterparty_revoked_commitment - 1, "expecting to validate the current or next counterparty revocation - trying {}, current {}", idx, state.last_counterparty_revoked_commitment); + if !self.disable_all_state_policy_checks { + assert!(idx == state.last_counterparty_revoked_commitment || idx == state.last_counterparty_revoked_commitment - 1, "expecting to validate the current or next counterparty revocation - trying {}, current {}", idx, state.last_counterparty_revoked_commitment); + } state.last_counterparty_revoked_commitment = idx; Ok(()) } @@ -230,14 +240,14 @@ impl EcdsaChannelSigner for TestChannelSigner { ) -> Result<(Signature, Vec), ()> { self.verify_counterparty_commitment_tx(channel_parameters, commitment_tx, secp_ctx); - { - #[cfg(test)] - if !self.is_signer_available(SignerOp::SignCounterpartyCommitment) { - return Err(()); - } - let mut state = self.state.lock().unwrap(); - let actual_commitment_number = commitment_tx.commitment_number(); - let last_commitment_number = state.last_counterparty_commitment; + #[cfg(test)] + if !self.is_signer_available(SignerOp::SignCounterpartyCommitment) { + return Err(()); + } + let mut state = self.state.lock().unwrap(); + let actual_commitment_number = commitment_tx.commitment_number(); + let last_commitment_number = state.last_counterparty_commitment; + if !self.disable_all_state_policy_checks { // These commitment numbers are backwards counting. We expect either the same as the previously encountered, // or the next one. assert!( @@ -255,9 +265,9 @@ impl EcdsaChannelSigner for TestChannelSigner { actual_commitment_number, state.last_counterparty_revoked_commitment ); - state.last_counterparty_commitment = - cmp::min(last_commitment_number, actual_commitment_number) } + state.last_counterparty_commitment = + cmp::min(last_commitment_number, actual_commitment_number); Ok(self .inner @@ -281,14 +291,16 @@ impl EcdsaChannelSigner for TestChannelSigner { } let trusted_tx = self.verify_holder_commitment_tx(channel_parameters, commitment_tx, secp_ctx); - let state = self.state.lock().unwrap(); - let commitment_number = trusted_tx.commitment_number(); - if state.last_holder_revoked_commitment - 1 != commitment_number - && state.last_holder_revoked_commitment - 2 != commitment_number - { - if !self.disable_revocation_policy_check { - panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}", - state.last_holder_revoked_commitment, commitment_number, self.inner.channel_keys_id()[0]) + if !self.disable_all_state_policy_checks { + let state = self.state.lock().unwrap(); + let commitment_number = trusted_tx.commitment_number(); + if state.last_holder_revoked_commitment - 1 != commitment_number + && state.last_holder_revoked_commitment - 2 != commitment_number + { + if !self.disable_revocation_policy_check { + panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}", + state.last_holder_revoked_commitment, commitment_number, self.inner.channel_keys_id()[0]) + } } } Ok(self.inner.sign_holder_commitment(channel_parameters, commitment_tx, secp_ctx).unwrap()) @@ -356,13 +368,15 @@ impl EcdsaChannelSigner for TestChannelSigner { if !self.is_signer_available(SignerOp::SignHolderHtlcTransaction) { return Err(()); } - let state = self.state.lock().unwrap(); - if state.last_holder_revoked_commitment - 1 != htlc_descriptor.per_commitment_number - && state.last_holder_revoked_commitment - 2 != htlc_descriptor.per_commitment_number - { - if !self.disable_revocation_policy_check { - panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}", - state.last_holder_revoked_commitment, htlc_descriptor.per_commitment_number, self.inner.channel_keys_id()[0]) + if !self.disable_all_state_policy_checks { + let state = self.state.lock().unwrap(); + if state.last_holder_revoked_commitment - 1 != htlc_descriptor.per_commitment_number + && state.last_holder_revoked_commitment - 2 != htlc_descriptor.per_commitment_number + { + if !self.disable_revocation_policy_check { + panic!("can only sign the next two unrevoked commitment numbers, revoked={} vs requested={} for {}", + state.last_holder_revoked_commitment, htlc_descriptor.per_commitment_number, self.inner.channel_keys_id()[0]) + } } } assert_eq!(htlc_tx.input[input], htlc_descriptor.unsigned_tx_input()); diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index f90bfb97ef7..00b85cc1ef8 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -1531,6 +1531,7 @@ pub struct TestKeysInterface { pub backing: DynKeysInterface, pub override_random_bytes: Mutex>, pub disable_revocation_policy_check: bool, + pub disable_all_state_policy_checks: bool, enforcement_states: Mutex>>>, expectations: Mutex>>, pub unavailable_signers_ops: Mutex>>, @@ -1599,8 +1600,9 @@ impl SignerProvider for TestKeysInterface { fn derive_channel_signer(&self, channel_keys_id: [u8; 32]) -> TestChannelSigner { let keys = self.backing.derive_channel_signer(channel_keys_id); let state = self.make_enforcement_state_cell(keys.channel_keys_id()); - let signer = - TestChannelSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check); + let rev_checks = self.disable_revocation_policy_check; + let state_checks = self.disable_all_state_policy_checks; + let signer = TestChannelSigner::new_with_revoked(keys, state, rev_checks, state_checks); #[cfg(test)] if let Some(ops) = self.unavailable_signers_ops.lock().unwrap().get(&channel_keys_id) { for &op in ops { @@ -1668,6 +1670,7 @@ impl TestKeysInterface { backing: DynKeysInterface::new(backing), override_random_bytes: Mutex::new(None), disable_revocation_policy_check: false, + disable_all_state_policy_checks: false, enforcement_states: Mutex::new(new_hash_map()), expectations: Mutex::new(None), unavailable_signers_ops: Mutex::new(new_hash_map()), From 1e9d0c2b30655c7f31a55cf94f84ac0756197bff Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 2 Feb 2025 16:27:25 +0000 Subject: [PATCH 4/5] Add a simple test of upgrading from LDK 0.1 One major hole in our test coverage historically has been tests covering upgrades or downgrades across LDK versions. Luckily, these aren't particularly hard to write as cargo lets us depend on previous versions of the `lightning` crate directly, which we can use in tests. Here we add a simple initial test of upgrading from LDK 0.1 while there's a pending payment to be claimed. --- Cargo.toml | 1 + ci/ci-tests.sh | 6 ++ lightning-tests/Cargo.toml | 21 ++++++ lightning-tests/src/lib.rs | 5 ++ .../src/upgrade_downgrade_tests.rs | 65 +++++++++++++++++++ lightning/src/ln/functional_test_utils.rs | 2 +- lightning/src/onion_message/messenger.rs | 4 +- 7 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 lightning-tests/Cargo.toml create mode 100644 lightning-tests/src/lib.rs create mode 100644 lightning-tests/src/upgrade_downgrade_tests.rs diff --git a/Cargo.toml b/Cargo.toml index 41a91996f7c..5f19f395a09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ members = [ exclude = [ "lightning-transaction-sync", + "lightning-tests", "ext-functional-test-demo", "no-std-check", "msrv-no-dev-deps-check", diff --git a/ci/ci-tests.sh b/ci/ci-tests.sh index a5c6d828ab0..d8749315ca3 100755 --- a/ci/ci-tests.sh +++ b/ci/ci-tests.sh @@ -57,6 +57,12 @@ for DIR in "${WORKSPACE_MEMBERS[@]}"; do cargo doc -p "$DIR" --document-private-items done +echo -e "\n\nTesting upgrade from prior versions of LDK" +pushd lightning-tests +[ "$RUSTC_MINOR_VERSION" -lt 65 ] && cargo update -p regex --precise "1.9.6" --verbose +cargo test +popd + echo -e "\n\nChecking and testing Block Sync Clients with features" cargo test -p lightning-block-sync --verbose --color always --features rest-client diff --git a/lightning-tests/Cargo.toml b/lightning-tests/Cargo.toml new file mode 100644 index 00000000000..75c68e03f5a --- /dev/null +++ b/lightning-tests/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "lightning-tests" +version = "0.0.1" +authors = ["Matt Corallo"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/lightningdevkit/rust-lightning/" +description = "Tests for LDK crates" +edition = "2021" + +[features] + +[dependencies] +lightning-types = { path = "../lightning-types", features = ["_test_utils"] } +lightning-invoice = { path = "../lightning-invoice", default-features = false } +lightning-macros = { path = "../lightning-macros" } +lightning = { path = "../lightning", features = ["_test_utils"] } +lightning_0_1 = { package = "lightning", version = "0.1.1", features = ["_test_utils"] } + +bitcoin = { version = "0.32.2", default-features = false } + +[dev-dependencies] diff --git a/lightning-tests/src/lib.rs b/lightning-tests/src/lib.rs new file mode 100644 index 00000000000..c028193d692 --- /dev/null +++ b/lightning-tests/src/lib.rs @@ -0,0 +1,5 @@ +#[cfg_attr(test, macro_use)] +extern crate lightning; + +#[cfg(all(test, not(taproot)))] +pub mod upgrade_downgrade_tests; diff --git a/lightning-tests/src/upgrade_downgrade_tests.rs b/lightning-tests/src/upgrade_downgrade_tests.rs new file mode 100644 index 00000000000..0a989553752 --- /dev/null +++ b/lightning-tests/src/upgrade_downgrade_tests.rs @@ -0,0 +1,65 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + +//! Tests which test upgrading from previous versions of LDK or downgrading to previous versions of +//! LDK. + +use lightning_0_1::get_monitor as get_monitor_0_1; +use lightning_0_1::ln::functional_test_utils as lightning_0_1_utils; +use lightning_0_1::util::ser::Writeable; + +use lightning::ln::functional_test_utils::*; + +use lightning_types::payment::PaymentPreimage; + +#[test] +fn simple_upgrade() { + // Tests a simple case of upgrading from LDK 0.1 with a pending payment + let (node_a_ser, node_b_ser, mon_a_ser, mon_b_ser, preimage); + { + let chanmon_cfgs = lightning_0_1_utils::create_chanmon_cfgs(2); + let node_cfgs = lightning_0_1_utils::create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = lightning_0_1_utils::create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = lightning_0_1_utils::create_network(2, &node_cfgs, &node_chanmgrs); + + let chan_id = lightning_0_1_utils::create_announced_chan_between_nodes(&nodes, 0, 1).2; + + let payment_preimage = + lightning_0_1_utils::route_payment(&nodes[0], &[&nodes[1]], 1_000_000); + preimage = PaymentPreimage(payment_preimage.0 .0); + + node_a_ser = nodes[0].node.encode(); + node_b_ser = nodes[1].node.encode(); + mon_a_ser = get_monitor_0_1!(nodes[0], chan_id).encode(); + mon_b_ser = get_monitor_0_1!(nodes[1], chan_id).encode(); + } + + // Create a dummy node to reload over with the 0.1 state + + let mut chanmon_cfgs = create_chanmon_cfgs(2); + + // Our TestChannelSigner will fail as we're jumping ahead, so disable its state-based checks + chanmon_cfgs[0].keys_manager.disable_all_state_policy_checks = true; + chanmon_cfgs[1].keys_manager.disable_all_state_policy_checks = true; + + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let (persister_a, persister_b, chain_mon_a, chain_mon_b); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let (node_a, node_b); + let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); + + let config = test_default_channel_config(); + let a_mons = &[&mon_a_ser[..]]; + reload_node!(nodes[0], config.clone(), &node_a_ser, a_mons, persister_a, chain_mon_a, node_a); + reload_node!(nodes[1], config, &node_b_ser, &[&mon_b_ser], persister_b, chain_mon_b, node_b); + + reconnect_nodes(ReconnectArgs::new(&nodes[0], &nodes[1])); + + claim_payment(&nodes[0], &[&nodes[1]], preimage); +} diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 8a9a5cb1762..2ebe489ce7a 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -1197,7 +1197,7 @@ pub fn _reload_node<'a, 'b, 'c>(node: &'a Node<'a, 'b, 'c>, default_config: User node_deserialized } -#[cfg(any(test, feature = "_externalize_tests"))] +#[macro_export] 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; diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 6009a276976..fd98f78350e 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -1313,8 +1313,8 @@ where } } - #[cfg(any(test, feature = "_externalize_tests"))] - pub(crate) fn set_offers_handler(&mut self, offers_handler: OMH) { + #[cfg(any(test, feature = "_test_utils"))] + pub fn set_offers_handler(&mut self, offers_handler: OMH) { self.offers_handler = offers_handler; } From 86c661a5e6648578e2253eb30eb8f3f13a918154 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 16 May 2025 14:20:24 +0000 Subject: [PATCH 5/5] Test the whole workspace at once in `ci-tests.sh` Running `cargo test -p crate` for each crate in the workspace results in re-building the `lightning` crate for each workspace crate, which can be quite slow. This adds nontrivial time to our total CI runs. Here, instead, we just run `cargo test` and let it build the whole workspace crate list in one go. This does result in combined features which may leave some issues with `cargo test -p crate` undetected, but there's not a ton of harm to that. --- ci/ci-tests.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ci/ci-tests.sh b/ci/ci-tests.sh index d8749315ca3..5d02bd6c362 100755 --- a/ci/ci-tests.sh +++ b/ci/ci-tests.sh @@ -50,12 +50,8 @@ WORKSPACE_MEMBERS=( possiblyrandom ) -echo -e "\n\nChecking, testing, and building docs for all workspace members individually..." -for DIR in "${WORKSPACE_MEMBERS[@]}"; do - cargo test -p "$DIR" --verbose --color always - cargo check -p "$DIR" --verbose --color always - cargo doc -p "$DIR" --document-private-items -done +echo -e "\n\nTesting the workspace, except lightning-transaction-sync." +cargo test --verbose --color always echo -e "\n\nTesting upgrade from prior versions of LDK" pushd lightning-tests @@ -63,6 +59,12 @@ pushd lightning-tests cargo test popd +echo -e "\n\nChecking and building docs for all workspace members individually..." +for DIR in "${WORKSPACE_MEMBERS[@]}"; do + cargo check -p "$DIR" --verbose --color always + cargo doc -p "$DIR" --document-private-items +done + echo -e "\n\nChecking and testing Block Sync Clients with features" cargo test -p lightning-block-sync --verbose --color always --features rest-client