//! A bunch of useful utilities for building networks of nodes and exchanging messages between
//! nodes for functional tests.
-use chain::{Listen, Watch};
+use chain::{Confirm, Listen, Watch};
use chain::channelmonitor::ChannelMonitor;
use chain::transaction::OutPoint;
use ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
use routing::router::{Route, get_route};
use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
-use ln::features::InitFeatures;
+use ln::features::{InitFeatures, InvoiceFeatures};
use ln::msgs;
use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
use util::enforcing_trait_impls::EnforcingSigner;
/// The possible ways we may notify a ChannelManager of a new block
#[derive(Clone, Copy, PartialEq)]
pub enum ConnectStyle {
- /// Calls update_best_block first, detecting transactions in the block only after receiving the
+ /// Calls best_block_updated first, detecting transactions in the block only after receiving the
/// header and height information.
BestBlockFirst,
/// The same as BestBlockFirst, however when we have multiple blocks to connect, we only
- /// make a single update_best_block call.
+ /// make a single best_block_updated call.
BestBlockFirstSkippingBlocks,
/// Calls transactions_confirmed first, detecting transactions in the block before updating the
/// header and height information.
TransactionsFirst,
/// The same as TransactionsFirst, however when we have multiple blocks to connect, we only
- /// make a single update_best_block call.
+ /// make a single best_block_updated call.
TransactionsFirstSkippingBlocks,
/// Provides the full block via the chain::Listen interface. In the current code this is
/// equivalent to TransactionsFirst with some additional assertions.
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
match *node.connect_style.borrow() {
ConnectStyle::BestBlockFirst|ConnectStyle::BestBlockFirstSkippingBlocks => {
- node.chain_monitor.chain_monitor.update_best_block(&block.header, height);
+ node.chain_monitor.chain_monitor.best_block_updated(&block.header, height);
node.chain_monitor.chain_monitor.transactions_confirmed(&block.header, &txdata, height);
- node.node.update_best_block(&block.header, height);
- node.node.transactions_confirmed(&block.header, height, &txdata);
+ node.node.best_block_updated(&block.header, height);
+ node.node.transactions_confirmed(&block.header, &txdata, height);
},
ConnectStyle::TransactionsFirst|ConnectStyle::TransactionsFirstSkippingBlocks => {
node.chain_monitor.chain_monitor.transactions_confirmed(&block.header, &txdata, height);
- node.chain_monitor.chain_monitor.update_best_block(&block.header, height);
- node.node.transactions_confirmed(&block.header, height, &txdata);
- node.node.update_best_block(&block.header, height);
+ node.chain_monitor.chain_monitor.best_block_updated(&block.header, height);
+ node.node.transactions_confirmed(&block.header, &txdata, height);
+ node.node.best_block_updated(&block.header, height);
},
ConnectStyle::FullBlockViaListen => {
- node.chain_monitor.chain_monitor.block_connected(&block.header, &txdata, height);
- Listen::block_connected(node.node, &block, height);
+ node.chain_monitor.chain_monitor.block_connected(&block, height);
+ node.node.block_connected(&block, height);
}
}
}
},
ConnectStyle::BestBlockFirstSkippingBlocks|ConnectStyle::TransactionsFirstSkippingBlocks => {
if i == count - 1 {
- node.chain_monitor.chain_monitor.update_best_block(&prev_header.0, prev_header.1);
- node.node.update_best_block(&prev_header.0, prev_header.1);
+ node.chain_monitor.chain_monitor.best_block_updated(&prev_header.0, prev_header.1);
+ node.node.best_block_updated(&prev_header.0, prev_header.1);
}
},
_ => {
- node.chain_monitor.chain_monitor.update_best_block(&prev_header.0, prev_header.1);
- node.node.update_best_block(&prev_header.0, prev_header.1);
+ node.chain_monitor.chain_monitor.best_block_updated(&prev_header.0, prev_header.1);
+ node.node.best_block_updated(&prev_header.0, prev_header.1);
},
}
}
/// Get a payment preimage and hash.
#[macro_export]
macro_rules! get_payment_preimage_hash {
- ($node: expr) => {
+ ($dest_node: expr) => {
{
- let payment_preimage = PaymentPreimage([*$node.network_payment_count.borrow(); 32]);
- *$node.network_payment_count.borrow_mut() += 1;
+ let payment_preimage = PaymentPreimage([*$dest_node.network_payment_count.borrow(); 32]);
+ *$dest_node.network_payment_count.borrow_mut() += 1;
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
- (payment_preimage, payment_hash)
+ let payment_secret = $dest_node.node.create_inbound_payment_for_hash(payment_hash, None, 7200).unwrap();
+ (payment_preimage, payment_hash, payment_secret)
}
}
}
+#[cfg(test)]
+macro_rules! get_route_and_payment_hash {
+ ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{
+ let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!($recv_node);
+ let net_graph_msg_handler = &$send_node.net_graph_msg_handler;
+ let route = get_route(&$send_node.node.get_our_node_id(),
+ &net_graph_msg_handler.network_graph.read().unwrap(),
+ &$recv_node.node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, $send_node.logger).unwrap();
+ (route, payment_hash, payment_preimage, payment_secret)
+ }}
+}
+
macro_rules! expect_pending_htlcs_forwardable_ignore {
($node: expr) => {{
let events = $node.node.get_and_clear_pending_events();
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, None);
}
-pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
- let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(origin_node);
+pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
+ let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(expected_route.last().unwrap());
send_along_route_with_hash(origin_node, route, expected_route, recv_value, our_payment_hash);
- (our_payment_preimage, our_payment_hash)
+ (our_payment_preimage, our_payment_hash, our_payment_secret)
}
pub fn claim_payment_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage, our_payment_secret: Option<PaymentSecret>, expected_amount: u64) {
pub const TEST_FINAL_CLTV: u32 = 50;
-pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash) {
+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 net_graph_msg_handler = &origin_node.net_graph_msg_handler;
let logger = test_utils::TestLogger::new();
- let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, &logger).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()) {
assert_eq!(hop.pubkey, node.node.get_our_node_id());
}
- let (_, our_payment_hash) = get_payment_preimage_hash!(origin_node);
+ let (_, our_payment_hash, _) = get_payment_preimage_hash!(expected_route.last().unwrap());
unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &None), 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")));
}