use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, keysinterface::EntropySource};
use crate::chain::channelmonitor::ChannelMonitor;
use crate::chain::transaction::OutPoint;
+use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose};
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-use crate::ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
+use crate::ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA};
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
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::events::ClosureReason;
use crate::util::enforcing_trait_impls::EnforcingSigner;
use crate::util::scid_utils;
use crate::util::test_utils;
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;
use crate::util::ser::{ReadableArgs, Writeable};
scid
}
/// Mine a single block containing the given transaction
-pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
+///
+/// Returns the SCID a channel confirmed in the given transaction will have, assuming the funding
+/// output is the 1st output in the transaction.
+pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) -> u64 {
let height = node.best_block_info().1 + 1;
- confirm_transaction_at(node, tx, height);
+ confirm_transaction_at(node, tx, height)
}
/// Mine a single block containing the given transactions
pub fn mine_transactions<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, txn: &[&Transaction]) {
let mut per_peer_state_lock;
let mut peer_state_lock;
let chan = get_channel_ref!($node, $counterparty_node, per_peer_state_lock, peer_state_lock, $channel_id);
- chan.get_feerate()
+ chan.get_feerate_sat_per_1000_weight()
}
}
}
assert_eq!(added_monitors[0].0, funding_output);
added_monitors.clear();
}
+ expect_channel_pending_event(&node_b, &node_a.node.get_our_node_id());
node_a.node.handle_funding_signed(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendFundingSigned, node_a.node.get_our_node_id()));
{
assert_eq!(added_monitors[0].0, funding_output);
added_monitors.clear();
}
+ expect_channel_pending_event(&node_a, &node_b.node.get_our_node_id());
let events_4 = node_a.node.get_and_clear_pending_events();
assert_eq!(events_4.len(), 0);
MessageSendEvent::SendFundingSigned { node_id, msg } => {
assert_eq!(*node_id, initiator.node.get_our_node_id());
initiator.node.handle_funding_signed(&receiver.node.get_our_node_id(), &msg);
+ expect_channel_pending_event(&initiator, &receiver.node.get_our_node_id());
+ expect_channel_pending_event(&receiver, &initiator.node.get_our_node_id());
check_added_monitors!(initiator, 1);
assert_eq!(initiator.tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
MessageSendEvent::SendChannelReady { node_id, msg } => {
assert_eq!(*node_id, initiator.node.get_our_node_id());
initiator.node.handle_channel_ready(&receiver.node.get_our_node_id(), &msg);
+ expect_channel_ready_event(&initiator, &receiver.node.get_our_node_id());
}
_ => panic!("Unexpected event"),
}
receiver.node.handle_channel_ready(&initiator.node.get_our_node_id(), &as_channel_ready);
+ expect_channel_ready_event(&receiver, &initiator.node.get_our_node_id());
let as_channel_update = get_event_msg!(initiator, MessageSendEvent::SendChannelUpdate, receiver.node.get_our_node_id());
let bs_channel_update = get_event_msg!(receiver, MessageSendEvent::SendChannelUpdate, initiator.node.get_our_node_id());
assert_eq!(initiator.node.list_usable_channels().len(), initiator_channels + 1);
assert_eq!(receiver.node.list_usable_channels().len(), receiver_channels + 1);
- expect_channel_ready_event(&initiator, &receiver.node.get_our_node_id());
- expect_channel_ready_event(&receiver, &initiator.node.get_our_node_id());
-
(tx, as_channel_ready.channel_id)
}
check_added_monitors!(nodes[b], 1);
let cs_funding_signed = get_event_msg!(nodes[b], MessageSendEvent::SendFundingSigned, nodes[a].node.get_our_node_id());
+ expect_channel_pending_event(&nodes[b], &nodes[a].node.get_our_node_id());
+
nodes[a].node.handle_funding_signed(&nodes[b].node.get_our_node_id(), &cs_funding_signed);
+ expect_channel_pending_event(&nodes[a], &nodes[b].node.get_our_node_id());
check_added_monitors!(nodes[a], 1);
+ assert_eq!(nodes[a].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
+ assert_eq!(nodes[a].tx_broadcaster.txn_broadcasted.lock().unwrap()[0], tx);
+ nodes[a].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
+
let conf_height = core::cmp::max(nodes[a].best_block_info().1 + 1, nodes[b].best_block_info().1 + 1);
confirm_transaction_at(&nodes[a], &tx, conf_height);
connect_blocks(&nodes[a], CHAN_CONFIRM_DEPTH - 1);
/// Check that a channel's closing channel update has been broadcasted, and optionally
/// check whether an error message event has occurred.
-pub fn check_closed_broadcast(node: &Node, with_error_msg: bool) -> Option<msgs::ErrorMessage> {
+pub fn check_closed_broadcast(node: &Node, num_channels: usize, with_error_msg: bool) -> Vec<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] {
+ assert_eq!(msg_events.len(), if with_error_msg { num_channels * 2 } else { num_channels });
+ msg_events.into_iter().filter_map(|msg_event| {
+ match msg_event {
+ MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
+ assert_eq!(msg.contents.flags & 2, 2);
+ None
+ },
MessageSendEvent::HandleError { action: msgs::ErrorAction::SendErrorMessage { ref msg }, node_id: _ } => {
+ assert!(with_error_msg);
// TODO: Check node_id
Some(msg.clone())
},
_ => panic!("Unexpected event"),
}
- } else { None }
+ }).collect()
}
/// Check that a channel's closing channel update has been broadcasted, and optionally
#[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)
+ $crate::ln::functional_test_utils::check_closed_broadcast(&$node, 1, $with_error_msg).pop()
}
}
($events: expr, $expected_failures: expr) => {{
for event in $events {
match event {
- $crate::util::events::Event::PendingHTLCsForwardable { .. } => { },
- $crate::util::events::Event::HTLCHandlingFailed { ref failed_next_destination, .. } => {
+ $crate::events::Event::PendingHTLCsForwardable { .. } => { },
+ $crate::events::Event::HTLCHandlingFailed { ref failed_next_destination, .. } => {
assert!($expected_failures.contains(&failed_next_destination))
},
_ => panic!("Unexpected destination"),
if fail_backwards {
expect_pending_htlcs_forwardable_and_htlc_handling_failed!(node_a,
- vec![crate::util::events::HTLCDestination::NextHopChannel{ node_id: Some(node_b.node.get_our_node_id()), channel_id: commitment_signed.channel_id }]);
+ vec![crate::events::HTLCDestination::NextHopChannel{ node_id: Some(node_b.node.get_our_node_id()), channel_id: commitment_signed.channel_id }]);
check_added_monitors!(node_a, 1);
let node_a_per_peer_state = node_a.node.per_peer_state.read().unwrap();
let events = $node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
- $crate::util::events::Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, via_channel_id: _, via_user_channel_id: _ } => {
+ $crate::events::Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, .. } => {
assert_eq!($expected_payment_hash, *payment_hash);
assert_eq!($expected_recv_value, amount_msat);
assert_eq!($expected_receiver_node_id, receiver_node_id.unwrap());
match purpose {
- $crate::util::events::PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
+ $crate::events::PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
assert_eq!(&$expected_payment_preimage, payment_preimage);
assert_eq!($expected_payment_secret, *payment_secret);
},
let events = $node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
- $crate::util::events::Event::PaymentClaimed { ref payment_hash, amount_msat, .. } => {
+ $crate::events::Event::PaymentClaimed { ref payment_hash, amount_msat, .. } => {
assert_eq!($expected_payment_hash, *payment_hash);
assert_eq!($expected_recv_value, amount_msat);
},
assert_eq!(events.len(), 1);
}
let expected_payment_id = match events[0] {
- $crate::util::events::Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => {
+ $crate::events::Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => {
assert_eq!($expected_payment_preimage, *payment_preimage);
assert_eq!(expected_payment_hash, *payment_hash);
assert!(fee_paid_msat.is_some());
if $expect_paths {
for i in 1..events.len() {
match events[i] {
- $crate::util::events::Event::PaymentPathSuccessful { payment_id, payment_hash, .. } => {
+ $crate::events::Event::PaymentPathSuccessful { payment_id, payment_hash, .. } => {
assert_eq!(payment_id, expected_payment_id);
assert_eq!(payment_hash, Some(expected_payment_hash));
},
let events = $node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
- $crate::util::events::Event::PaymentPathSuccessful { .. } => {},
+ $crate::events::Event::PaymentPathSuccessful { .. } => {},
_ => panic!("Unexpected event"),
}
}
let events = $node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
- Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => {
+ Event::PaymentForwarded {
+ fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id,
+ outbound_amount_forwarded_msat: _
+ } => {
assert_eq!(fee_earned_msat, $expected_fee);
if fee_earned_msat.is_some() {
// Is the event prev_channel_id in one of the channels between the two nodes?
}
#[cfg(any(test, feature = "_bench_unstable", feature = "_test_utils"))]
-pub fn expect_channel_ready_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) {
+pub fn expect_channel_pending_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) {
let events = node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
- crate::util::events::Event::ChannelReady{ ref counterparty_node_id, .. } => {
+ crate::events::Event::ChannelPending { ref counterparty_node_id, .. } => {
assert_eq!(*expected_counterparty_node_id, *counterparty_node_id);
},
_ => panic!("Unexpected event"),
}
}
+#[cfg(any(test, feature = "_bench_unstable", feature = "_test_utils"))]
+pub fn expect_channel_ready_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) {
+ let events = node.node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ crate::events::Event::ChannelReady{ ref counterparty_node_id, .. } => {
+ assert_eq!(*expected_counterparty_node_id, *counterparty_node_id);
+ },
+ _ => panic!("Unexpected event"),
+ }
+}
pub struct PaymentFailedConditions<'a> {
pub(crate) expected_htlc_error_data: Option<(u16, &'a [u8])>,
pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) -> PaymentId {
let payment_id = PaymentId(origin_node.keys_manager.backing.get_secure_random_bytes());
- origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), payment_id).unwrap();
+ origin_node.node.send_payment_with_route(&route, our_payment_hash,
+ RecipientOnionFields::secret_only(our_payment_secret), payment_id).unwrap();
check_added_monitors!(origin_node, expected_paths.len());
pass_along_route(origin_node, expected_paths, recv_value, our_payment_hash, our_payment_secret);
payment_id
}
-pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_claimable_expected: bool, clear_recipient_events: bool, expected_preimage: Option<PaymentPreimage>) {
+pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_claimable_expected: bool, clear_recipient_events: bool, expected_preimage: Option<PaymentPreimage>) -> Option<Event> {
let mut payment_event = SendEvent::from_event(ev);
let mut prev_node = origin_node;
+ let mut event = None;
for (idx, &node) in expected_path.iter().enumerate() {
assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
let events_2 = node.node.get_and_clear_pending_events();
if payment_claimable_expected {
assert_eq!(events_2.len(), 1);
- match events_2[0] {
- Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, ref via_channel_id, ref via_user_channel_id } => {
+ match &events_2[0] {
+ Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat,
+ receiver_node_id, ref via_channel_id, ref via_user_channel_id,
+ claim_deadline, onion_fields,
+ } => {
assert_eq!(our_payment_hash, *payment_hash);
assert_eq!(node.node.get_our_node_id(), receiver_node_id.unwrap());
+ assert!(onion_fields.is_some());
match &purpose {
PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
assert_eq!(expected_preimage, *payment_preimage);
assert_eq!(our_payment_secret.unwrap(), *payment_secret);
+ assert_eq!(Some(*payment_secret), onion_fields.as_ref().unwrap().payment_secret);
},
PaymentPurpose::SpontaneousPayment(payment_preimage) => {
assert_eq!(expected_preimage.unwrap(), *payment_preimage);
assert!(our_payment_secret.is_none());
},
}
- assert_eq!(amount_msat, recv_value);
+ assert_eq!(*amount_msat, recv_value);
assert!(node.node.list_channels().iter().any(|details| details.channel_id == via_channel_id.unwrap()));
assert!(node.node.list_channels().iter().any(|details| details.user_channel_id == via_user_channel_id.unwrap()));
+ assert!(claim_deadline.unwrap() > node.best_block_info().1);
},
_ => panic!("Unexpected event"),
}
+ event = Some(events_2[0].clone());
} else {
assert!(events_2.is_empty());
}
prev_node = node;
}
+ event
}
-pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_claimable_expected: bool, expected_preimage: Option<PaymentPreimage>) {
- do_pass_along_path(origin_node, expected_path, recv_value, our_payment_hash, our_payment_secret, ev, payment_claimable_expected, true, expected_preimage);
+pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_claimable_expected: bool, expected_preimage: Option<PaymentPreimage>) -> Option<Event> {
+ do_pass_along_path(origin_node, expected_path, recv_value, our_payment_hash, our_payment_secret, ev, payment_claimable_expected, true, expected_preimage)
}
pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) {
assert_eq!(hop.pubkey, node.node.get_our_node_id());
}
- let (_, our_payment_hash, our_payment_preimage) = get_payment_preimage_hash!(expected_route.last().unwrap());
- unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_preimage), PaymentId(our_payment_hash.0)), true, APIError::ChannelUnavailable { ref err },
+ let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(expected_route.last().unwrap());
+ unwrap_send_err!(origin_node.node.send_payment_with_route(&route, our_payment_hash,
+ RecipientOnionFields::secret_only(our_payment_secret), PaymentId(our_payment_hash.0)),
+ true, APIError::ChannelUnavailable { ref err },
assert!(err.contains("Cannot send value that would put us over the max HTLC value in flight our peer will accept")));
}