use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
use crate::ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
-use crate::routing::router::{PaymentParameters, Route, get_route};
+use crate::routing::router::{self, PaymentParameters, Route};
use crate::ln::features::InitFeatures;
use crate::ln::msgs;
use crate::ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
use crate::util::enforcing_trait_impls::EnforcingSigner;
use crate::util::scid_utils;
use crate::util::test_utils;
-use crate::util::test_utils::{panicking, TestChainMonitor};
+use crate::util::test_utils::{panicking, TestChainMonitor, TestScorer, TestKeysInterface};
use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose};
use crate::util::errors::APIError;
use crate::util::config::UserConfig;
(announcement, as_update, bs_update, channel_id, tx)
}
+/// Gets an RAA and CS which were sent in response to a commitment update
+///
+/// Should only be used directly when the `$node` is not actually a [`Node`].
+macro_rules! do_get_revoke_commit_msgs {
+ ($node: expr, $recipient: expr) => { {
+ let events = $node.node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 2);
+ (match events[0] {
+ MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
+ assert_eq!(node_id, $recipient);
+ (*msg).clone()
+ },
+ _ => panic!("Unexpected event"),
+ }, match events[1] {
+ MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
+ assert_eq!(node_id, $recipient);
+ assert!(updates.update_add_htlcs.is_empty());
+ assert!(updates.update_fulfill_htlcs.is_empty());
+ assert!(updates.update_fail_htlcs.is_empty());
+ assert!(updates.update_fail_malformed_htlcs.is_empty());
+ assert!(updates.update_fee.is_none());
+ updates.commitment_signed.clone()
+ },
+ _ => panic!("Unexpected event"),
+ })
+ } }
+}
+
+/// Gets an RAA and CS which were sent in response to a commitment update
+pub fn get_revoke_commit_msgs(node: &Node, recipient: &PublicKey) -> (msgs::RevokeAndACK, msgs::CommitmentSigned) {
+ do_get_revoke_commit_msgs!(node, recipient)
+}
+
#[macro_export]
/// Gets an RAA and CS which were sent in response to a commitment update
+///
+/// Don't use this, use the identically-named function instead.
macro_rules! get_revoke_commit_msgs {
($node: expr, $node_id: expr) => {
- {
- use $crate::util::events::MessageSendEvent;
- let events = $node.node.get_and_clear_pending_msg_events();
- assert_eq!(events.len(), 2);
- (match events[0] {
- MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
- assert_eq!(*node_id, $node_id);
- (*msg).clone()
- },
- _ => panic!("Unexpected event"),
- }, match events[1] {
- MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
- assert_eq!(*node_id, $node_id);
- assert!(updates.update_add_htlcs.is_empty());
- assert!(updates.update_fulfill_htlcs.is_empty());
- assert!(updates.update_fail_htlcs.is_empty());
- assert!(updates.update_fail_malformed_htlcs.is_empty());
- assert!(updates.update_fee.is_none());
- updates.commitment_signed.clone()
- },
- _ => panic!("Unexpected event"),
- })
- }
+ $crate::ln::functional_test_utils::get_revoke_commit_msgs(&$node, &$node_id)
}
}
}
/// Get an error message from the pending events queue.
-#[macro_export]
-macro_rules! get_err_msg {
- ($node: expr, $node_id: expr) => {
- {
- let events = $node.node.get_and_clear_pending_msg_events();
- assert_eq!(events.len(), 1);
- match events[0] {
- $crate::util::events::MessageSendEvent::HandleError {
- action: $crate::ln::msgs::ErrorAction::SendErrorMessage { ref msg }, ref node_id
- } => {
- assert_eq!(*node_id, $node_id);
- (*msg).clone()
- },
- _ => panic!("Unexpected event"),
- }
- }
+pub fn get_err_msg(node: &Node, recipient: &PublicKey) -> msgs::ErrorMessage {
+ let events = node.node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::HandleError {
+ action: msgs::ErrorAction::SendErrorMessage { ref msg }, ref node_id
+ } => {
+ assert_eq!(node_id, recipient);
+ (*msg).clone()
+ },
+ _ => panic!("Unexpected event"),
}
}
}
}
+/// Gets an UpdateHTLCs MessageSendEvent
+pub fn get_htlc_update_msgs(node: &Node, recipient: &PublicKey) -> msgs::CommitmentUpdate {
+ let events = node.node.get_and_clear_pending_msg_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
+ assert_eq!(node_id, recipient);
+ (*updates).clone()
+ },
+ _ => panic!("Unexpected event"),
+ }
+}
+
#[macro_export]
/// Gets an UpdateHTLCs MessageSendEvent
+///
+/// Don't use this, use the identically-named function instead.
macro_rules! get_htlc_update_msgs {
($node: expr, $node_id: expr) => {
- {
- let events = $node.node.get_and_clear_pending_msg_events();
- assert_eq!(events.len(), 1);
- match events[0] {
- $crate::util::events::MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => {
- assert_eq!(*node_id, $node_id);
- (*updates).clone()
- },
- _ => panic!("Unexpected event"),
- }
- }
+ $crate::ln::functional_test_utils::get_htlc_update_msgs(&$node, &$node_id)
}
}
}
}
+pub fn do_check_spends<F: Fn(&bitcoin::blockdata::transaction::OutPoint) -> Option<TxOut>>(tx: &Transaction, get_output: F) {
+ for outp in tx.output.iter() {
+ assert!(outp.value >= outp.script_pubkey.dust_value().to_sat(), "Spending tx output didn't meet dust limit");
+ }
+ let mut total_value_in = 0;
+ for input in tx.input.iter() {
+ total_value_in += get_output(&input.previous_output).unwrap().value;
+ }
+ let mut total_value_out = 0;
+ for output in tx.output.iter() {
+ total_value_out += output.value;
+ }
+ let min_fee = (tx.weight() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up)
+ // Input amount - output amount = fee, so check that out + min_fee is smaller than input
+ assert!(total_value_out + min_fee <= total_value_in);
+ tx.verify(get_output).unwrap();
+}
+
#[macro_export]
macro_rules! check_spends {
($tx: expr, $($spends_txn: expr),*) => {
assert!(outp.value >= outp.script_pubkey.dust_value().to_sat(), "Input tx output didn't meet dust limit");
}
)*
- for outp in $tx.output.iter() {
- assert!(outp.value >= outp.script_pubkey.dust_value().to_sat(), "Spending tx output didn't meet dust limit");
- }
let get_output = |out_point: &bitcoin::blockdata::transaction::OutPoint| {
$(
if out_point.txid == $spends_txn.txid() {
)*
None
};
- let mut total_value_in = 0;
- for input in $tx.input.iter() {
- total_value_in += get_output(&input.previous_output).unwrap().value;
- }
- let mut total_value_out = 0;
- for output in $tx.output.iter() {
- total_value_out += output.value;
- }
- let min_fee = ($tx.weight() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up)
- // Input amount - output amount = fee, so check that out + min_fee is smaller than input
- assert!(total_value_out + min_fee <= total_value_in);
- $tx.verify(get_output).unwrap();
+ $crate::ln::functional_test_utils::do_check_spends(&$tx, get_output);
}
}
}
/// Check that a channel's closing channel update has been broadcasted, and optionally
/// check whether an error message event has occurred.
-#[macro_export]
-macro_rules! check_closed_broadcast {
- ($node: expr, $with_error_msg: expr) => {{
- use $crate::util::events::MessageSendEvent;
- use $crate::ln::msgs::ErrorAction;
-
- let msg_events = $node.node.get_and_clear_pending_msg_events();
- assert_eq!(msg_events.len(), if $with_error_msg { 2 } else { 1 });
- match msg_events[0] {
- MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
- assert_eq!(msg.contents.flags & 2, 2);
+pub fn check_closed_broadcast(node: &Node, with_error_msg: bool) -> Option<msgs::ErrorMessage> {
+ let msg_events = node.node.get_and_clear_pending_msg_events();
+ assert_eq!(msg_events.len(), if with_error_msg { 2 } else { 1 });
+ match msg_events[0] {
+ MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
+ assert_eq!(msg.contents.flags & 2, 2);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ if with_error_msg {
+ match msg_events[1] {
+ MessageSendEvent::HandleError { action: msgs::ErrorAction::SendErrorMessage { ref msg }, node_id: _ } => {
+ // TODO: Check node_id
+ Some(msg.clone())
},
_ => panic!("Unexpected event"),
}
- if $with_error_msg {
- match msg_events[1] {
- MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id: _ } => {
- // TODO: Check node_id
- Some(msg.clone())
- },
- _ => panic!("Unexpected event"),
- }
- } else { None }
- }}
+ } else { None }
+}
+
+/// Check that a channel's closing channel update has been broadcasted, and optionally
+/// check whether an error message event has occurred.
+///
+/// Don't use this, use the identically-named function instead.
+#[macro_export]
+macro_rules! check_closed_broadcast {
+ ($node: expr, $with_error_msg: expr) => {
+ $crate::ln::functional_test_utils::check_closed_broadcast(&$node, $with_error_msg)
+ }
}
/// Check that a channel's closing channel events has been issued
}
/// Get a payment preimage and hash.
+pub fn get_payment_preimage_hash(recipient: &Node, min_value_msat: Option<u64>, min_final_cltv_expiry_delta: Option<u16>) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
+ let mut payment_count = recipient.network_payment_count.borrow_mut();
+ let payment_preimage = PaymentPreimage([*payment_count; 32]);
+ *payment_count += 1;
+ let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
+ let payment_secret = recipient.node.create_inbound_payment_for_hash(payment_hash, min_value_msat, 7200, min_final_cltv_expiry_delta).unwrap();
+ (payment_preimage, payment_hash, payment_secret)
+}
+
+/// Get a payment preimage and hash.
+///
+/// Don't use this, use the identically-named function instead.
#[macro_export]
macro_rules! get_payment_preimage_hash {
($dest_node: expr) => {
- {
- get_payment_preimage_hash!($dest_node, None)
- }
+ get_payment_preimage_hash!($dest_node, None)
};
($dest_node: expr, $min_value_msat: expr) => {
- {
- crate::get_payment_preimage_hash!($dest_node, $min_value_msat, None)
- }
+ crate::get_payment_preimage_hash!($dest_node, $min_value_msat, None)
};
($dest_node: expr, $min_value_msat: expr, $min_final_cltv_expiry_delta: expr) => {
- {
- use bitcoin::hashes::Hash as _;
- let mut payment_count = $dest_node.network_payment_count.borrow_mut();
- let payment_preimage = $crate::ln::PaymentPreimage([*payment_count; 32]);
- *payment_count += 1;
- let payment_hash = $crate::ln::PaymentHash(
- bitcoin::hashes::sha256::Hash::hash(&payment_preimage.0[..]).into_inner());
- let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, $min_value_msat, 7200, $min_final_cltv_expiry_delta).unwrap();
- (payment_preimage, payment_hash, payment_secret)
- }
+ $crate::ln::functional_test_utils::get_payment_preimage_hash(&$dest_node, $min_value_msat, $min_final_cltv_expiry_delta)
};
}
+/// Gets a route from the given sender to the node described in `payment_params`.
+pub fn get_route(send_node: &Node, payment_params: &PaymentParameters, recv_value: u64, final_cltv_expiry_delta: u32) -> Result<Route, msgs::LightningError> {
+ let scorer = TestScorer::new();
+ let keys_manager = TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet);
+ let random_seed_bytes = keys_manager.get_secure_random_bytes();
+ router::get_route(
+ &send_node.node.get_our_node_id(), payment_params, &send_node.network_graph.read_only(),
+ Some(&send_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
+ recv_value, final_cltv_expiry_delta, send_node.logger, &scorer, &random_seed_bytes
+ )
+}
+
+/// Gets a route from the given sender to the node described in `payment_params`.
+///
+/// Don't use this, use the identically-named function instead.
#[macro_export]
macro_rules! get_route {
- ($send_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{
- use $crate::chain::keysinterface::EntropySource;
- let scorer = $crate::util::test_utils::TestScorer::new();
- let keys_manager = $crate::util::test_utils::TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet);
- let random_seed_bytes = keys_manager.get_secure_random_bytes();
- $crate::routing::router::get_route(
- &$send_node.node.get_our_node_id(), &$payment_params, &$send_node.network_graph.read_only(),
- Some(&$send_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
- $recv_value, $cltv, $send_node.logger, &scorer, &random_seed_bytes
- )
- }}
+ ($send_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {
+ $crate::ln::functional_test_utils::get_route(&$send_node, &$payment_params, $recv_value, $cltv)
+ }
}
#[cfg(test)]
$crate::get_route_and_payment_hash!($send_node, $recv_node, payment_params, $recv_value, TEST_FINAL_CLTV)
}};
($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr, $cltv: expr) => {{
- let (payment_preimage, payment_hash, payment_secret) = $crate::get_payment_preimage_hash!($recv_node, Some($recv_value));
- let route = $crate::get_route!($send_node, $payment_params, $recv_value, $cltv);
+ let (payment_preimage, payment_hash, payment_secret) =
+ $crate::ln::functional_test_utils::get_payment_preimage_hash(&$recv_node, Some($recv_value), None);
+ let route = $crate::ln::functional_test_utils::get_route(&$send_node, &$payment_params, $recv_value, $cltv);
(route.unwrap(), payment_hash, payment_preimage, payment_secret)
}}
}
pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV)
.with_features(expected_route.last().unwrap().node.invoice_features());
- let route = get_route!(origin_node, payment_params, recv_value, TEST_FINAL_CLTV).unwrap();
+ let route = get_route(origin_node, &payment_params, recv_value, TEST_FINAL_CLTV).unwrap();
assert_eq!(route.paths.len(), 1);
assert_eq!(route.paths[0].len(), expected_route.len());
for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {
let seed = [0u8; 32];
let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
let random_seed_bytes = keys_manager.get_secure_random_bytes();
- let route = get_route(
+ let route = router::get_route(
&origin_node.node.get_our_node_id(), &payment_params, &network_graph,
None, recv_value, TEST_FINAL_CLTV, origin_node.logger, &scorer, &random_seed_bytes).unwrap();
assert_eq!(route.paths.len(), 1);