mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-03-13 14:52:21 +01:00
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.
This commit is contained in:
parent
17cd6e39fc
commit
e41e7564ba
32 changed files with 559 additions and 490 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -13,5 +13,6 @@ lightning-rapid-gossip-sync/res/full_graph.lngossip
|
||||||
lightning-custom-message/target
|
lightning-custom-message/target
|
||||||
lightning-transaction-sync/target
|
lightning-transaction-sync/target
|
||||||
lightning-dns-resolver/target
|
lightning-dns-resolver/target
|
||||||
|
ext-functional-test-demo/target
|
||||||
no-std-check/target
|
no-std-check/target
|
||||||
msrv-no-dev-deps-check/target
|
msrv-no-dev-deps-check/target
|
||||||
|
|
|
@ -21,6 +21,7 @@ members = [
|
||||||
|
|
||||||
exclude = [
|
exclude = [
|
||||||
"lightning-transaction-sync",
|
"lightning-transaction-sync",
|
||||||
|
"ext-functional-test-demo",
|
||||||
"no-std-check",
|
"no-std-check",
|
||||||
"msrv-no-dev-deps-check",
|
"msrv-no-dev-deps-check",
|
||||||
"bench",
|
"bench",
|
||||||
|
|
|
@ -112,6 +112,13 @@ cargo check --verbose --color always
|
||||||
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
|
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
|
||||||
popd
|
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".
|
# Test that we can build downstream code with only the "release pins".
|
||||||
pushd msrv-no-dev-deps-check
|
pushd msrv-no-dev-deps-check
|
||||||
PIN_RELEASE_DEPS
|
PIN_RELEASE_DEPS
|
||||||
|
|
7
ext-functional-test-demo/Cargo.toml
Normal file
7
ext-functional-test-demo/Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "ext-functional-tester"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
lightning = { path = "../lightning", features = ["_externalize_tests"] }
|
31
ext-functional-test-demo/src/main.rs
Normal file
31
ext-functional-test-demo/src/main.rs
Normal file
|
@ -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<dyn DynKeysInterfaceTrait<EcdsaSigner = DynSigner>> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,6 +79,7 @@ use bitcoin::secp256k1::schnorr;
|
||||||
use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey};
|
use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey};
|
||||||
|
|
||||||
use lightning::io::Cursor;
|
use lightning::io::Cursor;
|
||||||
|
use lightning::util::dyn_signer::DynSigner;
|
||||||
use std::cmp::{self, Ordering};
|
use std::cmp::{self, Ordering};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
|
@ -375,6 +376,7 @@ impl SignerProvider for KeyProvider {
|
||||||
channel_keys_id,
|
channel_keys_id,
|
||||||
);
|
);
|
||||||
let revoked_commitment = self.make_enforcement_state_cell(keys.commitment_seed);
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
|
||||||
use bitcoin::secp256k1::schnorr;
|
use bitcoin::secp256k1::schnorr;
|
||||||
use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey};
|
use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey};
|
||||||
|
|
||||||
|
use lightning::util::dyn_signer::DynSigner;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
|
||||||
|
@ -439,7 +440,7 @@ impl SignerProvider for KeyProvider {
|
||||||
let ctr = channel_keys_id[0];
|
let ctr = channel_keys_id[0];
|
||||||
let (inbound, state) = self.signer_state.borrow().get(&ctr).unwrap().clone();
|
let (inbound, state) = self.signer_state.borrow().get(&ctr).unwrap().clone();
|
||||||
TestChannelSigner::new_with_revoked(
|
TestChannelSigner::new_with_revoked(
|
||||||
if inbound {
|
DynSigner::new(if inbound {
|
||||||
InMemorySigner::new(
|
InMemorySigner::new(
|
||||||
&secp_ctx,
|
&secp_ctx,
|
||||||
SecretKey::from_slice(&[
|
SecretKey::from_slice(&[
|
||||||
|
@ -509,7 +510,7 @@ impl SignerProvider for KeyProvider {
|
||||||
channel_keys_id,
|
channel_keys_id,
|
||||||
channel_keys_id,
|
channel_keys_id,
|
||||||
)
|
)
|
||||||
},
|
}),
|
||||||
state,
|
state,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
|
@ -2550,6 +2550,8 @@ mod tests {
|
||||||
failure: PathFailure::OnPath { network_update: None },
|
failure: PathFailure::OnPath { network_update: None },
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
short_channel_id: Some(scored_scid),
|
short_channel_id: Some(scored_scid),
|
||||||
|
error_code: None,
|
||||||
|
error_data: None,
|
||||||
});
|
});
|
||||||
let event = $receive.expect("PaymentPathFailed not handled within deadline");
|
let event = $receive.expect("PaymentPathFailed not handled within deadline");
|
||||||
match event {
|
match event {
|
||||||
|
@ -2567,6 +2569,8 @@ mod tests {
|
||||||
failure: PathFailure::OnPath { network_update: None },
|
failure: PathFailure::OnPath { network_update: None },
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
short_channel_id: None,
|
short_channel_id: None,
|
||||||
|
error_code: None,
|
||||||
|
error_data: None,
|
||||||
});
|
});
|
||||||
let event = $receive.expect("PaymentPathFailed not handled within deadline");
|
let event = $receive.expect("PaymentPathFailed not handled within deadline");
|
||||||
match event {
|
match event {
|
||||||
|
|
|
@ -306,7 +306,7 @@ pub fn drop_legacy_field_definition(expr: TokenStream) -> TokenStream {
|
||||||
///
|
///
|
||||||
/// fn f1() {}
|
/// fn f1() {}
|
||||||
///
|
///
|
||||||
/// #[xtest(feature = "_test_utils")]
|
/// #[xtest(feature = "_externalize_tests")]
|
||||||
/// pub fn test_f1() {
|
/// pub fn test_f1() {
|
||||||
/// f1();
|
/// f1();
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -18,7 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
||||||
[features]
|
[features]
|
||||||
# Internal test utilities exposed to other repo crates
|
# Internal test utilities exposed to other repo crates
|
||||||
_test_utils = ["regex", "bitcoin/bitcoinconsensus", "lightning-types/_test_utils"]
|
_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).
|
# 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.
|
# This is unsafe to use in production because it may result in the counterparty publishing taking our funds.
|
||||||
unsafe_revoked_tx_signing = []
|
unsafe_revoked_tx_signing = []
|
||||||
|
@ -48,10 +48,12 @@ regex = { version = "1.5.6", optional = true }
|
||||||
backtrace = { version = "0.3", optional = true }
|
backtrace = { version = "0.3", optional = true }
|
||||||
|
|
||||||
libm = { version = "0.2", default-features = false }
|
libm = { version = "0.2", default-features = false }
|
||||||
|
inventory = { version = "0.3", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
regex = "1.5.6"
|
regex = "1.5.6"
|
||||||
lightning-types = { version = "0.3.0", path = "../lightning-types", features = ["_test_utils"] }
|
lightning-types = { version = "0.3.0", path = "../lightning-types", features = ["_test_utils"] }
|
||||||
|
lightning-macros = { path = "../lightning-macros" }
|
||||||
|
|
||||||
[dev-dependencies.bitcoin]
|
[dev-dependencies.bitcoin]
|
||||||
version = "0.32.2"
|
version = "0.32.2"
|
||||||
|
|
|
@ -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<ChannelSigner> {
|
pub fn remove_monitor(&self, channel_id: &ChannelId) -> ChannelMonitor<ChannelSigner> {
|
||||||
self.monitors.write().unwrap().remove(channel_id).unwrap().monitor
|
self.monitors.write().unwrap().remove(channel_id).unwrap().monitor
|
||||||
}
|
}
|
||||||
|
|
|
@ -854,10 +854,7 @@ impl Readable for IrrevocablyResolvedHTLC {
|
||||||
/// returned block hash and the the current chain and then reconnecting blocks to get to the
|
/// returned block hash and the the current chain and then reconnecting blocks to get to the
|
||||||
/// best chain) upon deserializing the object!
|
/// best chain) upon deserializing the object!
|
||||||
pub struct ChannelMonitor<Signer: EcdsaChannelSigner> {
|
pub struct ChannelMonitor<Signer: EcdsaChannelSigner> {
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) inner: Mutex<ChannelMonitorImpl<Signer>>,
|
pub(crate) inner: Mutex<ChannelMonitorImpl<Signer>>,
|
||||||
#[cfg(not(test))]
|
|
||||||
pub(super) inner: Mutex<ChannelMonitorImpl<Signer>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Signer: EcdsaChannelSigner> Clone for ChannelMonitor<Signer> where Signer: Clone {
|
impl<Signer: EcdsaChannelSigner> Clone for ChannelMonitor<Signer> where Signer: Clone {
|
||||||
|
@ -965,9 +962,9 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
|
||||||
// Obviously Correct (tm) if we just keep track of them explicitly.
|
// Obviously Correct (tm) if we just keep track of them explicitly.
|
||||||
outputs_to_watch: HashMap<Txid, Vec<(u32, ScriptBuf)>>,
|
outputs_to_watch: HashMap<Txid, Vec<(u32, ScriptBuf)>>,
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub onchain_tx_handler: OnchainTxHandler<Signer>,
|
pub onchain_tx_handler: OnchainTxHandler<Signer>,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
onchain_tx_handler: OnchainTxHandler<Signer>,
|
onchain_tx_handler: OnchainTxHandler<Signer>,
|
||||||
|
|
||||||
// This is set when the Channel[Manager] generated a ChannelMonitorUpdate which indicated the
|
// This is set when the Channel[Manager] generated a ChannelMonitorUpdate which indicated the
|
||||||
|
@ -1818,7 +1815,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
|
||||||
/// Unsafe test-only version of `broadcast_latest_holder_commitment_txn` used by our test framework
|
/// 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
|
/// to bypass HolderCommitmentTransaction state update lockdown after signature and generate
|
||||||
/// revoked commitment transaction.
|
/// 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<L: Deref>(&self, logger: &L) -> Vec<Transaction>
|
pub fn unsafe_get_latest_holder_commitment_txn<L: Deref>(&self, logger: &L) -> Vec<Transaction>
|
||||||
where L::Target: Logger {
|
where L::Target: Logger {
|
||||||
let mut inner = self.inner.lock().unwrap();
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
@ -2132,7 +2129,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
|
||||||
self.inner.lock().unwrap().counterparty_payment_script = script;
|
self.inner.lock().unwrap().counterparty_payment_script = script;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub fn do_mut_signer_call<F: FnMut(&mut Signer) -> ()>(&self, mut f: F) {
|
pub fn do_mut_signer_call<F: FnMut(&mut Signer) -> ()>(&self, mut f: F) {
|
||||||
let mut inner = self.inner.lock().unwrap();
|
let mut inner = self.inner.lock().unwrap();
|
||||||
f(&mut inner.onchain_tx_handler.signer);
|
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
|
// witness length match (ie is 136 bytes long). We generate one here which we also use in some
|
||||||
// in-line tests later.
|
// in-line tests later.
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec<u8> {
|
pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec<u8> {
|
||||||
use bitcoin::opcodes;
|
use bitcoin::opcodes;
|
||||||
let mut ret = [opcodes::all::OP_NOP.to_u8(); 136];
|
let mut ret = [opcodes::all::OP_NOP.to_u8(); 136];
|
||||||
|
@ -2785,7 +2782,7 @@ pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec<u8> {
|
||||||
Vec::from(&ret[..])
|
Vec::from(&ret[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub fn deliberately_bogus_accepted_htlc_witness() -> Vec<Vec<u8>> {
|
pub fn deliberately_bogus_accepted_htlc_witness() -> Vec<Vec<u8>> {
|
||||||
vec![Vec::new(), Vec::new(), Vec::new(), Vec::new(), deliberately_bogus_accepted_htlc_witness_program().into()].into()
|
vec![Vec::new(), Vec::new(), Vec::new(), Vec::new(), deliberately_bogus_accepted_htlc_witness_program().into()].into()
|
||||||
}
|
}
|
||||||
|
@ -3947,7 +3944,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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!
|
/// Note that this includes possibly-locktimed-in-the-future transactions!
|
||||||
fn unsafe_get_latest_holder_commitment_txn<L: Deref>(
|
fn unsafe_get_latest_holder_commitment_txn<L: Deref>(
|
||||||
&mut self, logger: &WithChannelMonitor<L>
|
&mut self, logger: &WithChannelMonitor<L>
|
||||||
|
@ -5289,7 +5286,7 @@ mod tests {
|
||||||
nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header,
|
nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header,
|
||||||
&[(0, broadcast_tx)], conf_height);
|
&[(0, broadcast_tx)], conf_height);
|
||||||
|
|
||||||
let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<InMemorySigner>)>::read(
|
let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<_>)>::read(
|
||||||
&mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()),
|
&mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()),
|
||||||
(&nodes[1].keys_manager.backing, &nodes[1].keys_manager.backing)).unwrap();
|
(&nodes[1].keys_manager.backing, &nodes[1].keys_manager.backing)).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -250,9 +250,9 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
|
||||||
// Key is identifier of the pending claim request, i.e the txid of the initial claiming transaction generated by
|
// 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.
|
// 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)
|
// 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<ClaimId, PackageTemplate>,
|
pub(crate) pending_claim_requests: HashMap<ClaimId, PackageTemplate>,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
pending_claim_requests: HashMap<ClaimId, PackageTemplate>,
|
pending_claim_requests: HashMap<ClaimId, PackageTemplate>,
|
||||||
|
|
||||||
// Used to track external events that need to be forwarded to the `ChainMonitor`. This `Vec`
|
// Used to track external events that need to be forwarded to the `ChainMonitor`. This `Vec`
|
||||||
|
@ -273,9 +273,9 @@ pub struct OnchainTxHandler<ChannelSigner: EcdsaChannelSigner> {
|
||||||
// block height, and are immutable until the outpoint has enough confirmations to meet our
|
// 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
|
// [`ANTI_REORG_DELAY`]. The initial confirmation block height is used to remove the entry if
|
||||||
// the block gets disconnected.
|
// the block gets disconnected.
|
||||||
#[cfg(test)] // Used in functional_test to verify sanitization
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub claimable_outpoints: HashMap<BitcoinOutPoint, (ClaimId, u32)>,
|
pub(crate) claimable_outpoints: HashMap<BitcoinOutPoint, (ClaimId, u32)>,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
claimable_outpoints: HashMap<BitcoinOutPoint, (ClaimId, u32)>,
|
claimable_outpoints: HashMap<BitcoinOutPoint, (ClaimId, u32)>,
|
||||||
|
|
||||||
locktimed_packages: BTreeMap<u32, Vec<PackageTemplate>>,
|
locktimed_packages: BTreeMap<u32, Vec<PackageTemplate>>,
|
||||||
|
@ -1193,7 +1193,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
|
||||||
MaybeSignedTransaction(tx)
|
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 {
|
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");
|
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)
|
self.holder_commitment.add_holder_sig(funding_redeemscript, sig)
|
||||||
|
|
|
@ -105,10 +105,10 @@ pub(crate) fn verify_channel_type_features(channel_type_features: &Option<Channe
|
||||||
// number_of_witness_elements + sig_length + revocation_sig + true_length + op_true + witness_script_length + witness_script
|
// number_of_witness_elements + sig_length + revocation_sig + true_length + op_true + witness_script_length + witness_script
|
||||||
pub(crate) const WEIGHT_REVOKED_OUTPUT: u64 = 1 + 1 + 73 + 1 + 1 + 1 + 77;
|
pub(crate) const WEIGHT_REVOKED_OUTPUT: u64 = 1 + 1 + 73 + 1 + 1 + 1 + 77;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
/// Height delay at which transactions are fee-bumped/rebroadcasted with a low priority.
|
/// Height delay at which transactions are fee-bumped/rebroadcasted with a low priority.
|
||||||
const LOW_FREQUENCY_BUMP_INTERVAL: u32 = 15;
|
const LOW_FREQUENCY_BUMP_INTERVAL: u32 = 15;
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
/// Height delay at which transactions are fee-bumped/rebroadcasted with a low priority.
|
/// Height delay at which transactions are fee-bumped/rebroadcasted with a low priority.
|
||||||
pub(crate) const LOW_FREQUENCY_BUMP_INTERVAL: u32 = 15;
|
pub(crate) const LOW_FREQUENCY_BUMP_INTERVAL: u32 = 15;
|
||||||
|
|
||||||
|
|
|
@ -1054,9 +1054,9 @@ pub enum Event {
|
||||||
/// If this is `Some`, then the corresponding channel should be avoided when the payment is
|
/// If this is `Some`, then the corresponding channel should be avoided when the payment is
|
||||||
/// retried. May be `None` for older [`Event`] serializations.
|
/// retried. May be `None` for older [`Event`] serializations.
|
||||||
short_channel_id: Option<u64>,
|
short_channel_id: Option<u64>,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_code: Option<u16>,
|
error_code: Option<u16>,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_data: Option<Vec<u8>>,
|
error_data: Option<Vec<u8>>,
|
||||||
},
|
},
|
||||||
/// Indicates that a probe payment we sent returned successful, i.e., only failed at the destination.
|
/// 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 {
|
&Event::PaymentPathFailed {
|
||||||
ref payment_id, ref payment_hash, ref payment_failed_permanently, ref failure,
|
ref payment_id, ref payment_hash, ref payment_failed_permanently, ref failure,
|
||||||
ref path, ref short_channel_id,
|
ref path, ref short_channel_id,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
ref error_code,
|
ref error_code,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
ref error_data,
|
ref error_data,
|
||||||
} => {
|
} => {
|
||||||
3u8.write(writer)?;
|
3u8.write(writer)?;
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_code.write(writer)?;
|
error_code.write(writer)?;
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_data.write(writer)?;
|
error_data.write(writer)?;
|
||||||
write_tlv_fields!(writer, {
|
write_tlv_fields!(writer, {
|
||||||
(0, payment_hash, required),
|
(0, payment_hash, required),
|
||||||
|
@ -1920,9 +1920,9 @@ impl MaybeReadable for Event {
|
||||||
},
|
},
|
||||||
3u8 => {
|
3u8 => {
|
||||||
let mut f = || {
|
let mut f = || {
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
let error_code = Readable::read(reader)?;
|
let error_code = Readable::read(reader)?;
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
let error_data = Readable::read(reader)?;
|
let error_data = Readable::read(reader)?;
|
||||||
let mut payment_hash = PaymentHash([0; 32]);
|
let mut payment_hash = PaymentHash([0; 32]);
|
||||||
let mut payment_failed_permanently = false;
|
let mut payment_failed_permanently = false;
|
||||||
|
@ -1952,9 +1952,9 @@ impl MaybeReadable for Event {
|
||||||
failure,
|
failure,
|
||||||
path: Path { hops: path.unwrap(), blinded_tail },
|
path: Path { hops: path.unwrap(), blinded_tail },
|
||||||
short_channel_id,
|
short_channel_id,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_code,
|
error_code,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_data,
|
error_data,
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
@ -2364,7 +2364,7 @@ impl MaybeReadable for Event {
|
||||||
/// broadcast to most peers).
|
/// broadcast to most peers).
|
||||||
/// These events are handled by PeerManager::process_events if you are using a PeerManager.
|
/// These events are handled by PeerManager::process_events if you are using a PeerManager.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))]
|
||||||
pub enum MessageSendEvent {
|
pub enum MessageSendEvent {
|
||||||
/// Used to indicate that we've accepted a channel open and should send the accept_channel
|
/// Used to indicate that we've accepted a channel open and should send the accept_channel
|
||||||
/// message provided to the given peer.
|
/// message provided to the given peer.
|
||||||
|
|
|
@ -142,3 +142,6 @@ mod prelude {
|
||||||
extern crate backtrace;
|
extern crate backtrace;
|
||||||
|
|
||||||
mod sync;
|
mod sync;
|
||||||
|
|
||||||
|
#[cfg(feature = "_externalize_tests")]
|
||||||
|
lightning_macros::xtest_inventory!();
|
||||||
|
|
|
@ -88,6 +88,7 @@ fn params_from_invoice(
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::routing::router::Payee;
|
use crate::routing::router::Payee;
|
||||||
|
use crate::sign::{NodeSigner, Recipient};
|
||||||
use crate::types::payment::PaymentSecret;
|
use crate::types::payment::PaymentSecret;
|
||||||
use bitcoin::hashes::sha256::Hash as Sha256;
|
use bitcoin::hashes::sha256::Hash as Sha256;
|
||||||
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
||||||
|
@ -178,8 +179,6 @@ mod tests {
|
||||||
let (payment_hash, payment_secret) =
|
let (payment_hash, payment_secret) =
|
||||||
nodes[1].node.create_inbound_payment(None, 7200, None).unwrap();
|
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 timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
|
||||||
let invoice = InvoiceBuilder::new(Currency::Bitcoin)
|
let invoice = InvoiceBuilder::new(Currency::Bitcoin)
|
||||||
.description("test".into())
|
.description("test".into())
|
||||||
|
@ -189,8 +188,11 @@ mod tests {
|
||||||
.min_final_cltv_expiry_delta(144)
|
.min_final_cltv_expiry_delta(144)
|
||||||
.amount_milli_satoshis(50_000)
|
.amount_milli_satoshis(50_000)
|
||||||
.payment_metadata(payment_metadata.clone())
|
.payment_metadata(payment_metadata.clone())
|
||||||
.build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &node_secret))
|
.build_raw()
|
||||||
.unwrap();
|
.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();
|
let (hash, onion, params) = payment_parameters_from_invoice(&invoice).unwrap();
|
||||||
nodes[0]
|
nodes[0]
|
||||||
|
|
|
@ -176,9 +176,9 @@ impl HTLCClaim {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
|
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 const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
|
||||||
|
|
||||||
pub(crate) fn commitment_tx_base_weight(channel_type_features: &ChannelTypeFeatures) -> u64 {
|
pub(crate) fn commitment_tx_base_weight(channel_type_features: &ChannelTypeFeatures) -> u64 {
|
||||||
|
|
|
@ -75,7 +75,8 @@ use crate::sign::type_resolver::ChannelSignerType;
|
||||||
|
|
||||||
use super::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint};
|
use super::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
|
#[allow(unused)]
|
||||||
pub struct ChannelValueStat {
|
pub struct ChannelValueStat {
|
||||||
pub value_to_self_msat: u64,
|
pub value_to_self_msat: u64,
|
||||||
pub channel_value_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
|
/// 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
|
/// 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.
|
/// 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;
|
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;
|
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
|
/// If we fail to see a funding transaction confirmed on-chain within this many blocks after the
|
||||||
|
@ -1220,7 +1221,7 @@ impl<SP: Deref> Channel<SP> where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub fn funding_mut(&mut self) -> &mut FundingScope {
|
pub fn funding_mut(&mut self) -> &mut FundingScope {
|
||||||
match &mut self.phase {
|
match &mut self.phase {
|
||||||
ChannelPhase::Undefined => unreachable!(),
|
ChannelPhase::Undefined => unreachable!(),
|
||||||
|
@ -1279,7 +1280,7 @@ impl<SP: Deref> Channel<SP> where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub fn is_unfunded_v1(&self) -> bool {
|
pub fn is_unfunded_v1(&self) -> bool {
|
||||||
matches!(self.phase, ChannelPhase::UnfundedOutboundV1(_) | ChannelPhase::UnfundedInboundV1(_))
|
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.
|
/// minimum channel reserve for self to maintain - set by them.
|
||||||
counterparty_selected_channel_reserve_satoshis: Option<u64>,
|
counterparty_selected_channel_reserve_satoshis: Option<u64>,
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub(super) holder_selected_channel_reserve_satoshis: u64,
|
pub(super) holder_selected_channel_reserve_satoshis: u64,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_externalize_tests")))]
|
||||||
holder_selected_channel_reserve_satoshis: u64,
|
holder_selected_channel_reserve_satoshis: u64,
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
@ -1851,9 +1852,9 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
|
||||||
|
|
||||||
/// The minimum and maximum absolute fee, in satoshis, we are willing to place on the closing
|
/// 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`.
|
/// 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)>,
|
pub(crate) closing_fee_limits: Option<(u64, u64)>,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
closing_fee_limits: Option<(u64, u64)>,
|
closing_fee_limits: Option<(u64, u64)>,
|
||||||
|
|
||||||
/// If we remove an HTLC (or fee update), commit, and receive our counterparty's
|
/// If we remove an HTLC (or fee update), commit, and receive our counterparty's
|
||||||
|
@ -1880,26 +1881,26 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
|
||||||
|
|
||||||
counterparty_dust_limit_satoshis: u64,
|
counterparty_dust_limit_satoshis: u64,
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub(super) holder_dust_limit_satoshis: u64,
|
pub(crate) holder_dust_limit_satoshis: u64,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
holder_dust_limit_satoshis: u64,
|
holder_dust_limit_satoshis: u64,
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub(super) counterparty_max_htlc_value_in_flight_msat: u64,
|
pub(crate) counterparty_max_htlc_value_in_flight_msat: u64,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
counterparty_max_htlc_value_in_flight_msat: u64,
|
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,
|
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,
|
holder_max_htlc_value_in_flight_msat: u64,
|
||||||
|
|
||||||
counterparty_htlc_minimum_msat: u64,
|
counterparty_htlc_minimum_msat: u64,
|
||||||
holder_htlc_minimum_msat: u64,
|
holder_htlc_minimum_msat: u64,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature="_test_utils"))]
|
||||||
pub counterparty_max_accepted_htlcs: u16,
|
pub counterparty_max_accepted_htlcs: u16,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature="_test_utils")))]
|
||||||
counterparty_max_accepted_htlcs: u16,
|
counterparty_max_accepted_htlcs: u16,
|
||||||
holder_max_accepted_htlcs: u16,
|
holder_max_accepted_htlcs: u16,
|
||||||
minimum_depth: Option<u32>,
|
minimum_depth: Option<u32>,
|
||||||
|
@ -1987,9 +1988,9 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
|
||||||
|
|
||||||
/// The unique identifier used to re-derive the private key material for the channel through
|
/// The unique identifier used to re-derive the private key material for the channel through
|
||||||
/// [`SignerProvider::derive_channel_signer`].
|
/// [`SignerProvider::derive_channel_signer`].
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
channel_keys_id: [u8; 32],
|
channel_keys_id: [u8; 32],
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub channel_keys_id: [u8; 32],
|
pub channel_keys_id: [u8; 32],
|
||||||
|
|
||||||
/// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we
|
/// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we
|
||||||
|
@ -3130,7 +3131,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the holder signer for this channel.
|
/// Returns the holder signer for this channel.
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub fn get_mut_signer(&mut self) -> &mut ChannelSignerType<SP> {
|
pub fn get_mut_signer(&mut self) -> &mut ChannelSignerType<SP> {
|
||||||
return &mut self.holder_signer
|
return &mut self.holder_signer
|
||||||
}
|
}
|
||||||
|
@ -7616,12 +7617,12 @@ impl<SP: Deref> FundedChannel<SP> where
|
||||||
self.context.cur_counterparty_commitment_transaction_number + 2
|
self.context.cur_counterparty_commitment_transaction_number + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub fn get_signer(&self) -> &ChannelSignerType<SP> {
|
pub fn get_signer(&self) -> &ChannelSignerType<SP> {
|
||||||
&self.context.holder_signer
|
&self.context.holder_signer
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub fn get_value_stat(&self) -> ChannelValueStat {
|
pub fn get_value_stat(&self) -> ChannelValueStat {
|
||||||
ChannelValueStat {
|
ChannelValueStat {
|
||||||
value_to_self_msat: self.funding.value_to_self_msat,
|
value_to_self_msat: self.funding.value_to_self_msat,
|
||||||
|
|
|
@ -56,7 +56,9 @@ use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelType
|
||||||
use crate::types::features::Bolt11InvoiceFeatures;
|
use crate::types::features::Bolt11InvoiceFeatures;
|
||||||
#[cfg(trampoline)]
|
#[cfg(trampoline)]
|
||||||
use crate::routing::gossip::NodeId;
|
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::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::msgs;
|
||||||
use crate::ln::onion_utils;
|
use crate::ln::onion_utils;
|
||||||
|
@ -128,7 +130,7 @@ use core::ops::Deref;
|
||||||
use bitcoin::hex::impl_fmt_traits;
|
use bitcoin::hex::impl_fmt_traits;
|
||||||
// Re-export this for use in the public API.
|
// Re-export this for use in the public API.
|
||||||
pub use crate::ln::outbound_payment::{Bolt12PaymentError, ProbeSendFailure, Retry, RetryableSendFailure, RecipientOnionFields};
|
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;
|
pub(crate) use crate::ln::outbound_payment::PaymentSendFailure;
|
||||||
use crate::ln::script::ShutdownScript;
|
use crate::ln::script::ShutdownScript;
|
||||||
|
|
||||||
|
@ -2458,9 +2460,10 @@ where
|
||||||
message_router: MR,
|
message_router: MR,
|
||||||
|
|
||||||
/// See `ChannelManager` struct-level documentation for lock order requirements.
|
/// See `ChannelManager` struct-level documentation for lock order requirements.
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub(super) best_block: RwLock<BestBlock>,
|
pub(super) best_block: RwLock<BestBlock>,
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
|
/// See `ChannelManager` struct-level documentation for lock order requirements.
|
||||||
best_block: RwLock<BestBlock>,
|
best_block: RwLock<BestBlock>,
|
||||||
secp_ctx: Secp256k1<secp256k1::All>,
|
secp_ctx: Secp256k1<secp256k1::All>,
|
||||||
|
|
||||||
|
@ -2542,10 +2545,10 @@ where
|
||||||
/// required to access the channel with the `counterparty_node_id`.
|
/// required to access the channel with the `counterparty_node_id`.
|
||||||
///
|
///
|
||||||
/// See `ChannelManager` struct-level documentation for lock order requirements.
|
/// See `ChannelManager` struct-level documentation for lock order requirements.
|
||||||
#[cfg(not(test))]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
outpoint_to_peer: Mutex<HashMap<OutPoint, PublicKey>>,
|
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) outpoint_to_peer: Mutex<HashMap<OutPoint, PublicKey>>,
|
pub(crate) outpoint_to_peer: Mutex<HashMap<OutPoint, PublicKey>>,
|
||||||
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
|
outpoint_to_peer: Mutex<HashMap<OutPoint, PublicKey>>,
|
||||||
|
|
||||||
/// SCIDs (and outbound SCID aliases) -> `counterparty_node_id`s and `channel_id`s.
|
/// 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<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
|
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<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
|
||||||
let _lck = self.total_consistency_lock.read().unwrap();
|
let _lck = self.total_consistency_lock.read().unwrap();
|
||||||
self.send_payment_along_path(SendAlongPathArgs {
|
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
|
/// LDK will not automatically retry this payment, though it may be manually re-sent after an
|
||||||
/// [`Event::PaymentFailed`] is generated.
|
/// [`Event::PaymentFailed`] is generated.
|
||||||
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub fn send_payment_with_route(
|
pub fn send_payment_with_route(
|
||||||
&self, mut route: Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
|
&self, mut route: Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
|
||||||
payment_id: PaymentId
|
payment_id: PaymentId
|
||||||
|
@ -4737,7 +4741,7 @@ where
|
||||||
&self.pending_events, |args| self.send_payment_along_path(args))
|
&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<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>, onion_session_privs: Vec<[u8; 32]>) -> Result<(), PaymentSendFailure> {
|
pub(super) fn test_send_payment_internal(&self, route: &Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>, onion_session_privs: Vec<[u8; 32]>) -> Result<(), PaymentSendFailure> {
|
||||||
let best_block_height = self.best_block.read().unwrap().height;
|
let best_block_height = self.best_block.read().unwrap().height;
|
||||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||||
|
@ -4746,7 +4750,7 @@ where
|
||||||
best_block_height, |args| self.send_payment_along_path(args))
|
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<Vec<[u8; 32]>, PaymentSendFailure> {
|
pub(crate) fn test_add_new_pending_payment(&self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, payment_id: PaymentId, route: &Route) -> Result<Vec<[u8; 32]>, PaymentSendFailure> {
|
||||||
let best_block_height = self.best_block.read().unwrap().height;
|
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)
|
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(())
|
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> {
|
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();
|
let txid = funding_transaction.compute_txid();
|
||||||
self.funding_transaction_generated_intern(temporary_channel_id, counterparty_node_id, funding_transaction, false, |_| {
|
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
|
// Most of our tests were written when we only broadcasted
|
||||||
// `channel_announcement`s once and then never re-broadcasted
|
// `channel_announcement`s once and then never re-broadcasted
|
||||||
// them again, so disable the re-broadcasting entirely in tests
|
// them again, so disable the re-broadcasting entirely in tests
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
{
|
{
|
||||||
should_announce = announcement_sigs.is_some();
|
should_announce = announcement_sigs.is_some();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,9 @@ use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
|
||||||
use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
|
use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
|
||||||
use crate::sign::{EntropySource, RandomBytes};
|
use crate::sign::{EntropySource, RandomBytes};
|
||||||
use crate::util::config::{MaxDustHTLCExposure, UserConfig};
|
use crate::util::config::{MaxDustHTLCExposure, UserConfig};
|
||||||
#[cfg(test)]
|
|
||||||
use crate::util::logger::Logger;
|
use crate::util::logger::Logger;
|
||||||
use crate::util::scid_utils;
|
use crate::util::scid_utils;
|
||||||
use crate::util::test_channel_signer::TestChannelSigner;
|
use crate::util::test_channel_signer::TestChannelSigner;
|
||||||
#[cfg(test)]
|
|
||||||
use crate::util::test_channel_signer::SignerOp;
|
use crate::util::test_channel_signer::SignerOp;
|
||||||
use crate::util::test_utils;
|
use crate::util::test_utils;
|
||||||
use crate::util::test_utils::{TestChainMonitor, TestScorer, TestKeysInterface};
|
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.
|
/// 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
|
/// This is useful for testing behavior for restoring an async signer that previously
|
||||||
/// could not return a signature immediately.
|
/// 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);
|
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
|
/// 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
|
/// 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.
|
/// 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;
|
use crate::sign::ChannelSigner;
|
||||||
log_debug!(self.logger, "Setting channel signer for {} as available={}", chan_id, available);
|
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 {
|
macro_rules! get_channel_ref {
|
||||||
($node: expr, $counterparty_node: expr, $per_peer_state_lock: ident, $peer_state_lock: ident, $channel_id: expr) => {
|
($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 {
|
macro_rules! get_feerate {
|
||||||
($node: expr, $counterparty_node: expr, $channel_id: expr) => {
|
($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 {
|
macro_rules! get_channel_type_features {
|
||||||
($node: expr, $counterparty_node: expr, $channel_id: expr) => {
|
($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
|
node_deserialized
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
macro_rules! reload_node {
|
macro_rules! reload_node {
|
||||||
($node: expr, $new_config: expr, $chanman_encoded: expr, $monitors_encoded: expr, $persister: ident, $new_chain_monitor: ident, $new_channelmanager: ident) => {
|
($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;
|
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 {
|
macro_rules! expect_pending_htlcs_forwardable_from_events {
|
||||||
($node: expr, $events: expr, $ignore: expr) => {{
|
($node: expr, $events: expr, $ignore: expr) => {{
|
||||||
assert_eq!($events.len(), 1);
|
assert_eq!($events.len(), 1);
|
||||||
|
@ -2209,7 +2205,6 @@ macro_rules! get_route {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! get_route_and_payment_hash {
|
macro_rules! get_route_and_payment_hash {
|
||||||
($send_node: expr, $recv_node: expr, $recv_value: expr) => {{
|
($send_node: expr, $recv_node: expr, $recv_value: expr) => {{
|
||||||
|
@ -2345,7 +2340,6 @@ macro_rules! expect_payment_sent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! expect_payment_path_successful {
|
macro_rules! expect_payment_path_successful {
|
||||||
($node: expr) => {
|
($node: expr) => {
|
||||||
|
@ -2433,7 +2427,6 @@ macro_rules! expect_payment_forwarded {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! expect_channel_shutdown_state {
|
macro_rules! expect_channel_shutdown_state {
|
||||||
($node: expr, $chan_id: expr, $state: path) => {
|
($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)>) {
|
pub fn expect_probe_successful_events(node: &Node, mut probe_results: Vec<(PaymentHash, PaymentId)>) {
|
||||||
let mut events = node.node.get_and_clear_pending_events();
|
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 {
|
macro_rules! expect_payment_failed_with_update {
|
||||||
($node: expr, $expected_payment_hash: expr, $payment_failed_permanently: expr, $scid: expr, $chan_closed: expr) => {
|
($node: expr, $expected_payment_hash: expr, $payment_failed_permanently: expr, $scid: expr, $chan_closed: expr) => {
|
||||||
$crate::ln::functional_test_utils::expect_payment_failed_conditions(
|
$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 {
|
macro_rules! expect_payment_failed {
|
||||||
($node: expr, $expected_payment_hash: expr, $payment_failed_permanently: expr $(, $expected_error_code: expr, $expected_error_data: expr)*) => {
|
($node: expr, $expected_payment_hash: expr, $payment_failed_permanently: expr $(, $expected_error_code: expr, $expected_error_data: expr)*) => {
|
||||||
#[allow(unused_mut)]
|
#[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); }
|
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] {
|
let expected_payment_id = match &payment_failed_events[0] {
|
||||||
Event::PaymentPathFailed { payment_hash, payment_failed_permanently, payment_id, failure,
|
Event::PaymentPathFailed { payment_hash, payment_failed_permanently, payment_id, failure,
|
||||||
#[cfg(test)]
|
error_code,
|
||||||
error_code,
|
error_data, .. } => {
|
||||||
#[cfg(test)]
|
|
||||||
error_data, .. } => {
|
|
||||||
assert_eq!(*payment_hash, expected_payment_hash, "unexpected payment_hash");
|
assert_eq!(*payment_hash, expected_payment_hash, "unexpected payment_hash");
|
||||||
assert_eq!(*payment_failed_permanently, expected_payment_failed_permanently, "unexpected payment_failed_permanently value");
|
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_code.is_some(), "expected error_code.is_some() = true");
|
||||||
assert!(error_data.is_some(), "expected error_data.is_some() = true");
|
assert!(error_data.is_some(), "expected error_data.is_some() = true");
|
||||||
if let Some((code, data)) = conditions.expected_htlc_error_data {
|
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<Node<'a, 'b,
|
||||||
handle_announce_close_broadcast_events(nodes, a, b, false, "Channel closed because commitment or closing transaction was confirmed on chain.");
|
handle_announce_close_broadcast_events(nodes, a, b, false, "Channel closed because commitment or closing transaction was confirmed on chain.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
macro_rules! get_channel_value_stat {
|
macro_rules! get_channel_value_stat {
|
||||||
($node: expr, $counterparty_node: expr, $channel_id: expr) => {{
|
($node: expr, $counterparty_node: expr, $channel_id: expr) => {{
|
||||||
let peer_state_lock = $node.node.per_peer_state.read().unwrap();
|
let peer_state_lock = $node.node.per_peer_state.read().unwrap();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -720,6 +720,7 @@ mod test {
|
||||||
use crate::util::test_utils;
|
use crate::util::test_utils;
|
||||||
use crate::util::config::UserConfig;
|
use crate::util::config::UserConfig;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use crate::util::dyn_signer::{DynKeysInterface, DynPhantomKeysInterface};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_prefer_current_channel() {
|
fn test_prefer_current_channel() {
|
||||||
|
@ -1239,6 +1240,13 @@ mod test {
|
||||||
do_test_multi_node_receive(false);
|
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) {
|
fn do_test_multi_node_receive(user_generated_pmt_hash: bool) {
|
||||||
use crate::events::{Event, EventsProvider};
|
use crate::events::{Event, EventsProvider};
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
@ -1246,9 +1254,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
||||||
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1350,9 +1357,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
||||||
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1441,9 +1447,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
||||||
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1469,9 +1474,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[3].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[3].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
||||||
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1499,9 +1503,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[3].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[3].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
||||||
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1556,9 +1559,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
||||||
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1588,9 +1590,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
||||||
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1621,9 +1622,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
let mut chanmon_cfgs = create_chanmon_cfgs(3);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
|
||||||
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1651,9 +1651,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
let mut chanmon_cfgs = create_chanmon_cfgs(4);
|
||||||
let seed_1 = [42u8; 32];
|
let seed_1 = [42u8; 32];
|
||||||
let seed_2 = [43u8; 32];
|
let seed_2 = [43u8; 32];
|
||||||
let cross_node_seed = [44u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
|
||||||
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1726,11 +1725,10 @@ mod test {
|
||||||
let seed_2 = [43 as u8; 32];
|
let seed_2 = [43 as u8; 32];
|
||||||
let seed_3 = [44 as u8; 32];
|
let seed_3 = [44 as u8; 32];
|
||||||
let seed_4 = [45 as u8; 32];
|
let seed_4 = [45 as u8; 32];
|
||||||
let cross_node_seed = [44 as u8; 32];
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[3].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[3].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
chanmon_cfgs[4].keys_manager.backing = make_dyn_keys_interface(&seed_3);
|
||||||
chanmon_cfgs[4].keys_manager.backing = PhantomKeysManager::new(&seed_3, 43, 44, &cross_node_seed);
|
chanmon_cfgs[4].keys_manager.backing = make_dyn_keys_interface(&seed_4);
|
||||||
chanmon_cfgs[5].keys_manager.backing = PhantomKeysManager::new(&seed_4, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(6, &chanmon_cfgs);
|
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 node_chanmgrs = create_node_chanmgrs(6, &node_cfgs, &[None, None, None, None, None, None]);
|
||||||
let nodes = create_network(6, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(6, &node_cfgs, &node_chanmgrs);
|
||||||
|
@ -1783,9 +1781,8 @@ mod test {
|
||||||
let mut chanmon_cfgs = create_chanmon_cfgs(5);
|
let mut chanmon_cfgs = create_chanmon_cfgs(5);
|
||||||
let seed_1 = [42 as u8; 32];
|
let seed_1 = [42 as u8; 32];
|
||||||
let seed_2 = [43 as u8; 32];
|
let seed_2 = [43 as u8; 32];
|
||||||
let cross_node_seed = [44 as u8; 32];
|
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1);
|
||||||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed);
|
chanmon_cfgs[2].keys_manager.backing = make_dyn_keys_interface(&seed_2);
|
||||||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed);
|
|
||||||
let node_cfgs = create_node_cfgs(5, &chanmon_cfgs);
|
let node_cfgs = create_node_cfgs(5, &chanmon_cfgs);
|
||||||
let node_chanmgrs = create_node_chanmgrs(5, &node_cfgs, &[None, None, None, None, None]);
|
let node_chanmgrs = create_node_chanmgrs(5, &node_cfgs, &[None, None, None, None, None]);
|
||||||
let nodes = create_network(5, &node_cfgs, &node_chanmgrs);
|
let nodes = create_network(5, &node_cfgs, &node_chanmgrs);
|
||||||
|
|
|
@ -58,9 +58,9 @@ mod blinded_payment_tests;
|
||||||
#[cfg(all(test, async_payments))]
|
#[cfg(all(test, async_payments))]
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
mod async_payments_tests;
|
mod async_payments_tests;
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
mod functional_tests;
|
pub mod functional_tests;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
mod max_payment_path_len_tests;
|
mod max_payment_path_len_tests;
|
||||||
|
|
|
@ -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);
|
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.
|
// 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[0].keys_manager.backing.inner.set_counter(0x1_0000_0004);
|
||||||
nodes[1].keys_manager.backing.inner.entropy_source.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
|
// 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.
|
// ensures that the HTLC timeout package is held until we reach its expiration height.
|
||||||
|
|
|
@ -925,9 +925,9 @@ pub(crate) struct DecodedOnionFailure {
|
||||||
pub(crate) short_channel_id: Option<u64>,
|
pub(crate) short_channel_id: Option<u64>,
|
||||||
pub(crate) payment_failed_permanently: bool,
|
pub(crate) payment_failed_permanently: bool,
|
||||||
pub(crate) failed_within_blinded_path: bool,
|
pub(crate) failed_within_blinded_path: bool,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub(crate) onion_error_code: Option<u16>,
|
pub(crate) onion_error_code: Option<u16>,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub(crate) onion_error_data: Option<Vec<u8>>,
|
pub(crate) onion_error_data: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1211,9 +1211,9 @@ where
|
||||||
short_channel_id,
|
short_channel_id,
|
||||||
payment_failed_permanently,
|
payment_failed_permanently,
|
||||||
failed_within_blinded_path,
|
failed_within_blinded_path,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
onion_error_code: error_code_ret,
|
onion_error_code: error_code_ret,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
onion_error_data: error_packet_ret,
|
onion_error_data: error_packet_ret,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1224,9 +1224,9 @@ where
|
||||||
short_channel_id: None,
|
short_channel_id: None,
|
||||||
payment_failed_permanently: is_from_final_node,
|
payment_failed_permanently: is_from_final_node,
|
||||||
failed_within_blinded_path: false,
|
failed_within_blinded_path: false,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
onion_error_code: None,
|
onion_error_code: None,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
onion_error_data: None,
|
onion_error_data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1382,9 +1382,9 @@ impl HTLCFailReason {
|
||||||
payment_failed_permanently: false,
|
payment_failed_permanently: false,
|
||||||
short_channel_id: Some(path.hops[0].short_channel_id),
|
short_channel_id: Some(path.hops[0].short_channel_id),
|
||||||
failed_within_blinded_path: false,
|
failed_within_blinded_path: false,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
onion_error_code: Some(*failure_code),
|
onion_error_code: Some(*failure_code),
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
onion_error_data: Some(data.clone()),
|
onion_error_data: Some(data.clone()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1546,9 +1546,9 @@ impl OutboundPayments {
|
||||||
failure: events::PathFailure::InitialSend { err: e },
|
failure: events::PathFailure::InitialSend { err: e },
|
||||||
path,
|
path,
|
||||||
short_channel_id: failed_scid,
|
short_channel_id: failed_scid,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_code: None,
|
error_code: None,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_data: None,
|
error_data: None,
|
||||||
}, None));
|
}, None));
|
||||||
}
|
}
|
||||||
|
@ -1643,7 +1643,7 @@ impl OutboundPayments {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub(super) fn test_add_new_pending_payment<ES: Deref>(
|
pub(super) fn test_add_new_pending_payment<ES: Deref>(
|
||||||
&self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, payment_id: PaymentId,
|
&self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, payment_id: PaymentId,
|
||||||
route: &Route, retry_strategy: Option<Retry>, entropy_source: &ES, best_block_height: u32
|
route: &Route, retry_strategy: Option<Retry>, 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<NS: Deref, F>(
|
pub(super) fn test_send_payment_internal<NS: Deref, F>(
|
||||||
&self, route: &Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
|
&self, route: &Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
|
||||||
keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>,
|
keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>,
|
||||||
|
@ -2099,12 +2099,12 @@ impl OutboundPayments {
|
||||||
probing_cookie_secret: [u8; 32], secp_ctx: &Secp256k1<secp256k1::All>,
|
probing_cookie_secret: [u8; 32], secp_ctx: &Secp256k1<secp256k1::All>,
|
||||||
pending_events: &Mutex<VecDeque<(events::Event, Option<EventCompletionAction>)>>, logger: &L,
|
pending_events: &Mutex<VecDeque<(events::Event, Option<EventCompletionAction>)>>, logger: &L,
|
||||||
) -> bool where L::Target: Logger {
|
) -> bool where L::Target: Logger {
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
let DecodedOnionFailure {
|
let DecodedOnionFailure {
|
||||||
network_update, short_channel_id, payment_failed_permanently, onion_error_code,
|
network_update, short_channel_id, payment_failed_permanently, onion_error_code,
|
||||||
onion_error_data, failed_within_blinded_path
|
onion_error_data, failed_within_blinded_path
|
||||||
} = onion_error.decode_onion_failure(secp_ctx, logger, &source);
|
} = onion_error.decode_onion_failure(secp_ctx, logger, &source);
|
||||||
#[cfg(not(test))]
|
#[cfg(not(any(test, feature = "_test_utils")))]
|
||||||
let DecodedOnionFailure {
|
let DecodedOnionFailure {
|
||||||
network_update, short_channel_id, payment_failed_permanently, failed_within_blinded_path
|
network_update, short_channel_id, payment_failed_permanently, failed_within_blinded_path
|
||||||
} = onion_error.decode_onion_failure(secp_ctx, logger, &source);
|
} = onion_error.decode_onion_failure(secp_ctx, logger, &source);
|
||||||
|
@ -2212,9 +2212,9 @@ impl OutboundPayments {
|
||||||
failure: events::PathFailure::OnPath { network_update },
|
failure: events::PathFailure::OnPath { network_update },
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
short_channel_id,
|
short_channel_id,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_code: onion_error_code,
|
error_code: onion_error_code,
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
error_data: onion_error_data
|
error_data: onion_error_data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl<T> TestEq for T {}
|
||||||
/// variant contains a message from [`msgs`] or otherwise the message type if unknown.
|
/// variant contains a message from [`msgs`] or otherwise the message type if unknown.
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(any(test, feature = "_test_utils"), derive(PartialEq))]
|
||||||
pub(crate) enum Message<T: core::fmt::Debug + Type + TestEq> {
|
pub(crate) enum Message<T: core::fmt::Debug + Type + TestEq> {
|
||||||
Init(msgs::Init),
|
Init(msgs::Init),
|
||||||
Error(msgs::ErrorMessage),
|
Error(msgs::ErrorMessage),
|
||||||
|
|
|
@ -1293,7 +1293,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub(crate) fn set_offers_handler(&mut self, offers_handler: OMH) {
|
pub(crate) fn set_offers_handler(&mut self, offers_handler: OMH) {
|
||||||
self.offers_handler = offers_handler;
|
self.offers_handler = offers_handler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ use crate::offers::invoice::Bolt12Invoice;
|
||||||
use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId};
|
use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId};
|
||||||
use crate::routing::scoring::{ChannelUsage, LockableScore, ScoreLookUp};
|
use crate::routing::scoring::{ChannelUsage, LockableScore, ScoreLookUp};
|
||||||
use crate::sign::EntropySource;
|
use crate::sign::EntropySource;
|
||||||
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
use crate::sync::Mutex;
|
use crate::sync::Mutex;
|
||||||
use crate::util::ser::{Writeable, Readable, ReadableArgs, Writer};
|
use crate::util::ser::{Writeable, Readable, ReadableArgs, Writer};
|
||||||
use crate::util::logger::Logger;
|
use crate::util::logger::Logger;
|
||||||
|
@ -189,17 +190,20 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref, S: Deref, SP: Size
|
||||||
/// A `Router` that returns a fixed route one time, erroring otherwise. Useful for
|
/// 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
|
/// `ChannelManager::send_payment_with_route` to support sending to specific routes without
|
||||||
/// requiring a custom `Router` implementation.
|
/// requiring a custom `Router` implementation.
|
||||||
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
pub(crate) struct FixedRouter {
|
pub(crate) struct FixedRouter {
|
||||||
// Use an `Option` to avoid needing to clone the route when `find_route` is called.
|
// Use an `Option` to avoid needing to clone the route when `find_route` is called.
|
||||||
route: Mutex<Option<Route>>,
|
route: Mutex<Option<Route>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
impl FixedRouter {
|
impl FixedRouter {
|
||||||
pub(crate) fn new(route: Route) -> Self {
|
pub(crate) fn new(route: Route) -> Self {
|
||||||
Self { route: Mutex::new(Some(route)) }
|
Self { route: Mutex::new(Some(route)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
impl Router for FixedRouter {
|
impl Router for FixedRouter {
|
||||||
fn find_route(
|
fn find_route(
|
||||||
&self, _payer: &PublicKey, _route_params: &RouteParameters,
|
&self, _payer: &PublicKey, _route_params: &RouteParameters,
|
||||||
|
|
|
@ -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::channel_keys::HtlcKey;
|
||||||
use crate::ln::msgs;
|
use crate::ln::msgs;
|
||||||
use crate::sign::ecdsa::EcdsaChannelSigner;
|
use crate::sign::ecdsa::EcdsaChannelSigner;
|
||||||
use crate::sign::{ChannelSigner, InMemorySigner};
|
use crate::sign::ChannelSigner;
|
||||||
use crate::types::payment::PaymentPreimage;
|
use crate::types::payment::PaymentPreimage;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -36,6 +36,7 @@ use crate::ln::msgs::PartialSignatureWithNonce;
|
||||||
#[cfg(taproot)]
|
#[cfg(taproot)]
|
||||||
use crate::sign::taproot::TaprootChannelSigner;
|
use crate::sign::taproot::TaprootChannelSigner;
|
||||||
use crate::sign::HTLCDescriptor;
|
use crate::sign::HTLCDescriptor;
|
||||||
|
use crate::util::dyn_signer::DynSigner;
|
||||||
use bitcoin::secp256k1;
|
use bitcoin::secp256k1;
|
||||||
#[cfg(taproot)]
|
#[cfg(taproot)]
|
||||||
use bitcoin::secp256k1::All;
|
use bitcoin::secp256k1::All;
|
||||||
|
@ -68,7 +69,7 @@ pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48;
|
||||||
/// forwards-compatibility prefix/suffixes!
|
/// forwards-compatibility prefix/suffixes!
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TestChannelSigner {
|
pub struct TestChannelSigner {
|
||||||
pub inner: InMemorySigner,
|
pub inner: DynSigner,
|
||||||
/// Channel state used for policy enforcement
|
/// Channel state used for policy enforcement
|
||||||
pub state: Arc<Mutex<EnforcementState>>,
|
pub state: Arc<Mutex<EnforcementState>>,
|
||||||
pub disable_revocation_policy_check: bool,
|
pub disable_revocation_policy_check: bool,
|
||||||
|
@ -119,7 +120,7 @@ impl PartialEq for TestChannelSigner {
|
||||||
|
|
||||||
impl TestChannelSigner {
|
impl TestChannelSigner {
|
||||||
/// Construct an TestChannelSigner
|
/// Construct an TestChannelSigner
|
||||||
pub fn new(inner: InMemorySigner) -> Self {
|
pub fn new(inner: DynSigner) -> Self {
|
||||||
let state = Arc::new(Mutex::new(EnforcementState::new()));
|
let state = Arc::new(Mutex::new(EnforcementState::new()));
|
||||||
Self { inner, state, disable_revocation_policy_check: false }
|
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
|
/// so that all copies are aware of enforcement state. A pointer to this state is provided
|
||||||
/// here, usually by an implementation of KeysInterface.
|
/// here, usually by an implementation of KeysInterface.
|
||||||
pub fn new_with_revoked(
|
pub fn new_with_revoked(
|
||||||
inner: InMemorySigner, state: Arc<Mutex<EnforcementState>>,
|
inner: DynSigner, state: Arc<Mutex<EnforcementState>>,
|
||||||
disable_revocation_policy_check: bool,
|
disable_revocation_policy_check: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { inner, state, disable_revocation_policy_check }
|
Self { inner, state, disable_revocation_policy_check }
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs};
|
||||||
use crate::chain;
|
use crate::chain;
|
||||||
use crate::chain::chaininterface;
|
use crate::chain::chaininterface;
|
||||||
use crate::chain::chaininterface::ConfirmationTarget;
|
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::chaininterface::FEERATE_FLOOR_SATS_PER_KW;
|
||||||
use crate::chain::chainmonitor::{ChainMonitor, Persist};
|
use crate::chain::chainmonitor::{ChainMonitor, Persist};
|
||||||
use crate::chain::channelmonitor::{
|
use crate::chain::channelmonitor::{
|
||||||
|
@ -23,7 +23,7 @@ use crate::chain::transaction::OutPoint;
|
||||||
use crate::chain::WatchedOutput;
|
use crate::chain::WatchedOutput;
|
||||||
use crate::events;
|
use crate::events;
|
||||||
use crate::events::bump_transaction::{Utxo, WalletSource};
|
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::chan_utils::CommitmentTransaction;
|
||||||
use crate::ln::channel_state::ChannelDetails;
|
use crate::ln::channel_state::ChannelDetails;
|
||||||
use crate::ln::channelmanager;
|
use crate::ln::channelmanager;
|
||||||
|
@ -50,13 +50,15 @@ use crate::sign::ChannelSigner;
|
||||||
use crate::sync::RwLock;
|
use crate::sync::RwLock;
|
||||||
use crate::types::features::{ChannelFeatures, InitFeatures, NodeFeatures};
|
use crate::types::features::{ChannelFeatures, InitFeatures, NodeFeatures};
|
||||||
use crate::util::config::UserConfig;
|
use crate::util::config::UserConfig;
|
||||||
|
use crate::util::dyn_signer::{
|
||||||
|
DynKeysInterface, DynKeysInterfaceTrait, DynPhantomKeysInterface, DynSigner,
|
||||||
|
};
|
||||||
use crate::util::logger::{Logger, Record};
|
use crate::util::logger::{Logger, Record};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::util::mut_global::MutGlobal;
|
use crate::util::mut_global::MutGlobal;
|
||||||
use crate::util::persist::{KVStore, MonitorName};
|
use crate::util::persist::{KVStore, MonitorName};
|
||||||
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
|
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
|
||||||
use crate::util::test_channel_signer::{EnforcementState, TestChannelSigner};
|
use crate::util::test_channel_signer::{EnforcementState, TestChannelSigner};
|
||||||
use crate::util::dyn_signer::{DynPhantomKeysInterface, DynSigner, DynKeysInterfaceTrait};
|
|
||||||
|
|
||||||
use bitcoin::amount::Amount;
|
use bitcoin::amount::Amount;
|
||||||
use bitcoin::block::Block;
|
use bitcoin::block::Block;
|
||||||
|
@ -509,14 +511,14 @@ impl<'a> chain::Watch<TestChannelSigner> for TestChainMonitor<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "_test_utils"))]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
struct JusticeTxData {
|
struct JusticeTxData {
|
||||||
justice_tx: Transaction,
|
justice_tx: Transaction,
|
||||||
value: Amount,
|
value: Amount,
|
||||||
commitment_number: u64,
|
commitment_number: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "_test_utils"))]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
pub(crate) struct WatchtowerPersister {
|
pub(crate) struct WatchtowerPersister {
|
||||||
persister: TestPersister,
|
persister: TestPersister,
|
||||||
/// Upon a new commitment_signed, we'll get a
|
/// Upon a new commitment_signed, we'll get a
|
||||||
|
@ -530,7 +532,7 @@ pub(crate) struct WatchtowerPersister {
|
||||||
destination_script: ScriptBuf,
|
destination_script: ScriptBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "_test_utils"))]
|
#[cfg(any(test, feature = "_externalize_tests"))]
|
||||||
impl WatchtowerPersister {
|
impl WatchtowerPersister {
|
||||||
pub(crate) fn new(destination_script: ScriptBuf) -> Self {
|
pub(crate) fn new(destination_script: ScriptBuf) -> Self {
|
||||||
let unsigned_justice_tx_data = Mutex::new(new_hash_map());
|
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<Signer: sign::ecdsa::EcdsaChannelSigner> Persist<Signer> for WatchtowerPersister {
|
impl<Signer: sign::ecdsa::EcdsaChannelSigner> Persist<Signer> for WatchtowerPersister {
|
||||||
fn persist_new_channel(
|
fn persist_new_channel(
|
||||||
&self, monitor_name: MonitorName, data: &ChannelMonitor<Signer>,
|
&self, monitor_name: MonitorName, data: &ChannelMonitor<Signer>,
|
||||||
|
@ -951,7 +953,7 @@ impl TestChannelMessageHandler {
|
||||||
!msgs.as_ref().unwrap().is_empty(),
|
!msgs.as_ref().unwrap().is_empty(),
|
||||||
"Received message when we weren't expecting one"
|
"Received message when we weren't expecting one"
|
||||||
);
|
);
|
||||||
#[cfg(test)]
|
#[cfg(any(test, feature = "_test_utils"))]
|
||||||
assert_eq!(msgs.as_ref().unwrap()[0], _ev);
|
assert_eq!(msgs.as_ref().unwrap()[0], _ev);
|
||||||
msgs.as_mut().unwrap().remove(0);
|
msgs.as_mut().unwrap().remove(0);
|
||||||
}
|
}
|
||||||
|
@ -1487,7 +1489,7 @@ impl NodeSigner for TestNodeSigner {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestKeysInterface {
|
pub struct TestKeysInterface {
|
||||||
pub backing: sign::PhantomKeysManager,
|
pub backing: DynKeysInterface,
|
||||||
pub override_random_bytes: Mutex<Option<[u8; 32]>>,
|
pub override_random_bytes: Mutex<Option<[u8; 32]>>,
|
||||||
pub disable_revocation_policy_check: bool,
|
pub disable_revocation_policy_check: bool,
|
||||||
enforcement_states: Mutex<HashMap<[u8; 32], Arc<Mutex<EnforcementState>>>>,
|
enforcement_states: Mutex<HashMap<[u8; 32], Arc<Mutex<EnforcementState>>>>,
|
||||||
|
@ -1581,30 +1583,42 @@ impl SignerProvider for TestKeysInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub static SIGNER_FACTORY: MutGlobal<Arc<dyn TestSignerFactory>> = MutGlobal::new(|| { Arc::new(DefaultSignerFactory()) });
|
pub static SIGNER_FACTORY: MutGlobal<Arc<dyn TestSignerFactory>> =
|
||||||
|
MutGlobal::new(|| Arc::new(DefaultSignerFactory()));
|
||||||
|
|
||||||
pub trait TestSignerFactory: Send + Sync {
|
pub trait TestSignerFactory: Send + Sync {
|
||||||
/// Make a dynamic signer
|
/// Make a dynamic signer
|
||||||
fn make_signer(&self, seed: &[u8; 32], now: Duration) -> Box<dyn DynKeysInterfaceTrait<EcdsaSigner=DynSigner>>;
|
fn make_signer(
|
||||||
|
&self, seed: &[u8; 32], now: Duration,
|
||||||
|
) -> Box<dyn DynKeysInterfaceTrait<EcdsaSigner = DynSigner>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct DefaultSignerFactory();
|
struct DefaultSignerFactory();
|
||||||
|
|
||||||
impl TestSignerFactory for DefaultSignerFactory {
|
impl TestSignerFactory for DefaultSignerFactory {
|
||||||
fn make_signer(&self, seed: &[u8; 32], now: Duration) -> Box<dyn DynKeysInterfaceTrait<EcdsaSigner=DynSigner>> {
|
fn make_signer(
|
||||||
|
&self, seed: &[u8; 32], now: Duration,
|
||||||
|
) -> Box<dyn DynKeysInterfaceTrait<EcdsaSigner = DynSigner>> {
|
||||||
let phantom = sign::PhantomKeysManager::new(seed, now.as_secs(), now.subsec_nanos(), seed);
|
let phantom = sign::PhantomKeysManager::new(seed, now.as_secs(), now.subsec_nanos(), seed);
|
||||||
let dphantom = DynPhantomKeysInterface::new(phantom);
|
let dphantom = DynPhantomKeysInterface::new(phantom);
|
||||||
let backing = Box::new(dphantom) as Box<dyn DynKeysInterfaceTrait<EcdsaSigner=DynSigner>>;
|
let backing = Box::new(dphantom) as Box<dyn DynKeysInterfaceTrait<EcdsaSigner = DynSigner>>;
|
||||||
backing
|
backing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestKeysInterface {
|
impl TestKeysInterface {
|
||||||
pub fn new(seed: &[u8; 32], network: Network) -> Self {
|
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 now = Duration::from_secs(genesis_block(network).header.time as u64);
|
||||||
|
let backing = factory.make_signer(seed, now);
|
||||||
Self {
|
Self {
|
||||||
backing: sign::PhantomKeysManager::new(seed, now.as_secs(), now.subsec_nanos(), seed),
|
backing: DynKeysInterface::new(backing),
|
||||||
override_random_bytes: Mutex::new(None),
|
override_random_bytes: Mutex::new(None),
|
||||||
disable_revocation_policy_check: false,
|
disable_revocation_policy_check: false,
|
||||||
enforcement_states: Mutex::new(new_hash_map()),
|
enforcement_states: Mutex::new(new_hash_map()),
|
||||||
|
|
Loading…
Add table
Reference in a new issue