Skip to content

Commit

Permalink
tests: test that lndk forwards onion messages
Browse files Browse the repository at this point in the history
  • Loading branch information
orbitalturtle committed Oct 3, 2023
1 parent 05012eb commit eaff827
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bytes = "1.4.0"
bitcoincore-rpc = { package="core-rpc", version = "0.17.0" }
bitcoind = { version = "0.30.0", features = [ "22_0" ] }
chrono = { version = "0.4.26" }
ldk-sample = { git = "https://github.com/lndk-org/ldk-sample" }
ldk-sample = { git = "https://github.com/lndk-org/ldk-sample", branch = "onion-handler" }
mockall = "0.11.3"
tempfile = "3.5.0"

Expand Down
23 changes: 15 additions & 8 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ const LNDK_TESTS_FOLDER: &str = "lndk-tests";

pub async fn setup_test_infrastructure(
test_name: &str,
) -> (BitcoindNode, LndNode, LdkNode, LdkNode) {
) -> (BitcoindNode, LndNode, LdkNode, LdkNode, PathBuf) {
let bitcoind = setup_bitcoind().await;
let (ldk_test_dir, lnd_test_dir) = setup_test_dirs();
let (ldk_test_dir, lnd_test_dir, lndk_test_dir) = setup_test_dirs();
let mut lnd = LndNode::new(
bitcoind.node.params.clone(),
bitcoind.zmq_block_port,
Expand Down Expand Up @@ -62,7 +62,7 @@ pub async fn setup_test_infrastructure(
let ldk1 = ldk_sample::start_ldk(ldk1_config, test_name).await;
let ldk2 = ldk_sample::start_ldk(ldk2_config, test_name).await;

(bitcoind, lnd, ldk1, ldk2)
(bitcoind, lnd, ldk1, ldk2, lndk_test_dir)
}

// Sets up /tmp/lndk-tests folder where we'll store the bins, data directories, and logs needed
Expand All @@ -77,19 +77,23 @@ pub async fn setup_test_infrastructure(
// +-- /lnd-data (lnd data and logs are stored here)
// |
// +-- /ldk-data (ldk data and logs are stored here)
// |
// +-- /lndk-data (lndk logs are stored here)
//
fn setup_test_dirs() -> (PathBuf, PathBuf) {
fn setup_test_dirs() -> (PathBuf, PathBuf, PathBuf) {
let lndk_tests_dir = env::temp_dir().join(LNDK_TESTS_FOLDER);
let bin_dir = lndk_tests_dir.join("bin");
let ldk_data_dir = lndk_tests_dir.join("ldk-data");
let lnd_data_dir = lndk_tests_dir.join("lnd-data");
let lndk_data_dir = lndk_tests_dir.join("lndk-data");

fs::create_dir_all(lndk_tests_dir.clone()).unwrap();
fs::create_dir_all(bin_dir.clone()).unwrap();
fs::create_dir_all(ldk_data_dir.clone()).unwrap();
fs::create_dir_all(lnd_data_dir.clone()).unwrap();
fs::create_dir_all(lndk_data_dir.clone()).unwrap();

(ldk_data_dir, lnd_data_dir)
(ldk_data_dir, lnd_data_dir, lndk_data_dir)
}

// BitcoindNode holds the tools we need to interact with a Bitcoind node.
Expand Down Expand Up @@ -131,10 +135,10 @@ pub async fn setup_bitcoind() -> BitcoindNode {

// LndNode holds the tools we need to interact with a Lightning node.
pub struct LndNode {
address: String,
pub address: String,
_lnd_dir_tmp: TempDir,
cert_path: String,
macaroon_path: String,
pub cert_path: String,
pub macaroon_path: String,
_handle: Child,
client: Option<Client>,
}
Expand Down Expand Up @@ -198,6 +202,9 @@ impl LndNode {
"--bitcoind.rpchost={:?}",
bitcoind_connect_params.rpc_socket
),
format!("--protocol.custom-message=513"),
format!("--protocol.custom-nodeann=39"),
format!("--protocol.custom-init=39"),
];

// TODO: For Windows we might need to add ".exe" at the end.
Expand Down
88 changes: 78 additions & 10 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,89 @@
mod common;
use lndk;

#[tokio::test(flavor = "multi_thread")]
async fn test_ldk_send_onion_message() {
let test_name = "send_onion_message";
let (_bitcoind, _lnd, ldk1, ldk2) = common::setup_test_infrastructure(test_name).await;
let (node_id_2, node_addr_2) = ldk2.get_node_info();
ldk1.connect_to_peer(node_id_2, node_addr_2).await.unwrap();
use bitcoin::secp256k1::PublicKey;
use chrono::Utc;
use ldk_sample::node_api::Node as LdkNode;
use std::path::PathBuf;
use std::str::FromStr;
use tokio::select;
use tokio::time::{sleep, timeout, Duration};

async fn wait_to_receive_onion_message(
ldk1: LdkNode,
ldk2: LdkNode,
lnd_id: PublicKey,
) -> (LdkNode, LdkNode) {
let data: Vec<u8> = vec![72, 101, 108, 108, 111];
let res = ldk1.send_onion_message(vec![node_id_2], 65, data).await;

let res = ldk1
.send_onion_message(vec![lnd_id, ldk2.get_node_info().0], 65, data)
.await;
assert!(res.is_ok());

// We need to give lndk time to process the message and forward it to ldk2.
let ldk2 = match timeout(Duration::from_secs(100), check_for_message(ldk2)).await {
Err(_) => panic!("ldk2 did not receive onion message before timeout"),
Ok(ldk2) => ldk2,
};

return (ldk1, ldk2);
}

async fn check_for_message(ldk: LdkNode) -> LdkNode {
loop {
if ldk.onion_message_handler.messages.lock().unwrap().len() == 1 {
println!("MESSAGE: {:?}", ldk.onion_message_handler.messages);
return ldk;
}
sleep(Duration::from_secs(2)).await;
}
}

#[tokio::test(flavor = "multi_thread")]
async fn test_ldk_lnd_connect() {
let test_name = "ldk_lnd_connect";
let (_bitcoind, mut lnd, ldk1, _ldk2) = common::setup_test_infrastructure(test_name).await;
async fn test_lndk_forwards_onion_message() {
let test_name = "lndk_forwards_onion_message";
let (_bitcoind, mut lnd, ldk1, ldk2, lndk_dir) =
common::setup_test_infrastructure(test_name).await;

// Here we'll produce a little path of two channels. Both ldk nodes are connected to lnd like so:
//
// ldk1 <-> lnd <-> ldk2
//
// Notice that ldk1 and ldk2 are not connected directly to each other.
let (pubkey, addr) = ldk1.get_node_info();
let (pubkey_2, addr_2) = ldk2.get_node_info();
lnd.connect_to_peer(pubkey, addr).await;
lnd.connect_to_peer(pubkey_2, addr_2).await;
let lnd_info = lnd.get_info().await;

// Now we'll spin up lndk. Even though ldk1 and ldk2 are not directly connected, we'll show that lndk
// successfully helps lnd forward the onion message from ldk1 to ldk2.
let lnd_cfg = lndk::lnd::LndCfg::new(
lnd.address,
PathBuf::from_str(&lnd.cert_path).unwrap(),
PathBuf::from_str(&lnd.macaroon_path).unwrap(),
);
let now_timestamp = Utc::now();
let timestamp = now_timestamp.format("%d-%m-%Y-%H%M");
let lndk_cfg = lndk::Cfg {
lnd: lnd_cfg,
log_dir: Some(
lndk_dir
.join(format!("lndk-logs-{test_name}-{timestamp}"))
.to_str()
.unwrap()
.to_string(),
),
};
select! {
val = lndk::run(lndk_cfg) => {
panic!("lndk should not have completed first {:?}", val);
},
// We wait for ldk2 to receive the onion message.
(ldk1, ldk2) = wait_to_receive_onion_message(ldk1, ldk2, PublicKey::from_str(&lnd_info.identity_pubkey).unwrap()) => {
ldk1.stop().await;
ldk2.stop().await;
}
}
}

0 comments on commit eaff827

Please sign in to comment.