Skip to content

Commit 7e0b3e1

Browse files
add test external node
1 parent fd29ab5 commit 7e0b3e1

File tree

5 files changed

+307
-267
lines changed

5 files changed

+307
-267
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ swift.swiftdoc
2727
/bindings/kotlin/ldk-node-android/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.kt
2828
/bindings/kotlin/ldk-node-jvm/lib/src/main/kotlin/org/lightningdevkit/ldknode/ldk_node.kt
2929
/bindings/kotlin/ldk-node-jvm/lib/src/main/resources/
30+
31+
/lnd-data

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ lightning = { version = "0.1.0", features = ["std", "_test_utils"] }
102102
#lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] }
103103
proptest = "1.0.0"
104104
regex = "1.5.6"
105+
# remover this dependencies
106+
lnd_grpc_rust = { version = "2.10.0", default-features = false }
107+
clightningrpc = { version = "0.3.0-beta.8", default-features = false }
105108

106109
[target.'cfg(not(no_download))'.dev-dependencies]
107110
electrsd = { version = "0.35.0", default-features = false, features = ["legacy", "esplora_a33e97e1", "corepc-node_27_2"] }
@@ -115,7 +118,6 @@ clightningrpc = { version = "0.3.0-beta.8", default-features = false }
115118

116119
[target.'cfg(lnd_test)'.dev-dependencies]
117120
lnd_grpc_rust = { version = "2.10.0", default-features = false }
118-
tokio = { version = "1.37", features = ["fs"] }
119121

120122
[build-dependencies]
121123
uniffi = { version = "0.28.3", features = ["build"], optional = true }

tests/common/mod.rs

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,24 @@
1010

1111
pub(crate) mod logging;
1212

13+
use electrsd::corepc_client::client_sync::Auth;
1314
use logging::TestLogWriter;
1415

16+
use ldk_node::bitcoin::secp256k1::PublicKey;
1517
use ldk_node::config::{Config, ElectrumSyncConfig, EsploraSyncConfig};
1618
use ldk_node::io::sqlite_store::SqliteStore;
1719
use ldk_node::payment::{PaymentDirection, PaymentKind, PaymentStatus};
1820
use ldk_node::{
1921
Builder, CustomTlvRecord, Event, LightningBalance, Node, NodeError, PendingSweepBalance,
22+
UserChannelId,
2023
};
2124

2225
use lightning::ln::msgs::SocketAddress;
2326
use lightning::routing::gossip::NodeAlias;
2427
use lightning::util::persist::KVStore;
2528
use lightning::util::test_utils::TestStore;
2629

27-
use lightning_invoice::{Bolt11InvoiceDescription, Description};
30+
use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, Description};
2831
use lightning_types::payment::{PaymentHash, PaymentPreimage};
2932

3033
use lightning_persister::fs_store::FilesystemStore;
@@ -38,6 +41,7 @@ use bitcoin::{
3841
use electrsd::corepc_node::Client as BitcoindClient;
3942
use electrsd::corepc_node::Node as BitcoinD;
4043
use electrsd::{corepc_node, ElectrsD};
44+
use electrum_client::Client as ElectrumClient;
4145
use electrum_client::ElectrumApi;
4246

4347
use rand::distributions::Alphanumeric;
@@ -47,6 +51,7 @@ use serde_json::{json, Value};
4751
use std::collections::{HashMap, HashSet};
4852
use std::env;
4953
use std::path::PathBuf;
54+
use std::str::FromStr;
5055
use std::sync::{Arc, RwLock};
5156
use std::time::Duration;
5257

@@ -1324,3 +1329,144 @@ impl KVStore for TestSyncStore {
13241329
self.do_list(primary_namespace, secondary_namespace)
13251330
}
13261331
}
1332+
1333+
pub trait ExternalLightningNode {
1334+
fn get_node_info(&mut self) -> (PublicKey, SocketAddress);
1335+
fn create_invoice(&mut self, amount_msat: u64, description: String) -> String;
1336+
fn pay_invoice(&mut self, invoice: &str);
1337+
fn check_receive_payment(&mut self, quantity_invoices: usize);
1338+
fn description_invoice(&mut self) -> String {
1339+
"externalNodeTest".to_string()
1340+
}
1341+
/// only needed for implementations that require a short delay to update routes/balances after receiving funds (e.g. LND).
1342+
fn can_send_payment(&mut self, _: String, _: u64) -> bool {
1343+
// Default implementation, can be overridden
1344+
true
1345+
}
1346+
}
1347+
1348+
fn init_setup_test_external_node() -> (Node, BitcoindClient, ElectrumClient) {
1349+
// Setup bitcoind / electrs clients
1350+
let bitcoind_client = BitcoindClient::new_with_auth(
1351+
"http://127.0.0.1:18443",
1352+
Auth::UserPass("user".to_string(), "pass".to_string()),
1353+
)
1354+
.unwrap();
1355+
let electrs_client = ElectrumClient::new("tcp://127.0.0.1:50001").unwrap();
1356+
1357+
// Give electrs a kick.
1358+
generate_blocks_and_wait(&bitcoind_client, &electrs_client, 1);
1359+
1360+
// Setup LDK Node
1361+
let config = random_config(true);
1362+
let mut builder = Builder::from_config(config.node_config);
1363+
builder.set_chain_source_esplora("http://127.0.0.1:3002".to_string(), None);
1364+
1365+
let node = builder.build().unwrap();
1366+
node.start().unwrap();
1367+
1368+
// Premine some funds and distribute
1369+
let address = node.onchain_payment().new_address().unwrap();
1370+
let premine_amount = Amount::from_sat(5_000_000);
1371+
premine_and_distribute_funds(&bitcoind_client, &electrs_client, vec![address], premine_amount);
1372+
1373+
(node, bitcoind_client, electrs_client)
1374+
}
1375+
1376+
fn open_channel_by_node_id<E: ElectrumApi>(
1377+
bitcoind: &BitcoindClient, electrs: &E, node: &Node, external_node_id: PublicKey,
1378+
external_node_address: SocketAddress, funding_amount_sat: u64, push_msat: Option<u64>,
1379+
) -> UserChannelId {
1380+
node.sync_wallets().unwrap();
1381+
1382+
// Open the channel
1383+
node.open_announced_channel(
1384+
external_node_id,
1385+
external_node_address,
1386+
funding_amount_sat,
1387+
push_msat,
1388+
None,
1389+
)
1390+
.unwrap();
1391+
1392+
let funding_txo = expect_channel_pending_event!(node, external_node_id);
1393+
wait_for_tx(electrs, funding_txo.txid);
1394+
generate_blocks_and_wait(bitcoind, electrs, 6);
1395+
node.sync_wallets().unwrap();
1396+
let user_channel_id = expect_channel_ready_event!(node, external_node_id);
1397+
user_channel_id
1398+
}
1399+
1400+
fn ldk_send_payment_to_external_node<E: ExternalLightningNode>(
1401+
node: &Node, external_node: &mut E, amount_msat: u64,
1402+
) {
1403+
let description = external_node.description_invoice();
1404+
let invoice_string = external_node.create_invoice(amount_msat, description);
1405+
let invoice = Bolt11Invoice::from_str(&invoice_string).unwrap();
1406+
node.bolt11_payment().send(&invoice, None).unwrap();
1407+
}
1408+
1409+
fn ldk_check_send_payment_succeeds<E: ExternalLightningNode>(
1410+
node: &Node, external_node: &mut E, quantity_invoices: usize,
1411+
) {
1412+
expect_event!(node, PaymentSuccessful);
1413+
external_node.check_receive_payment(quantity_invoices)
1414+
}
1415+
1416+
fn ldk_receive_payment_from_external_node<E: ExternalLightningNode>(
1417+
node: &Node, external_node: &mut E, amount_msat: u64,
1418+
) {
1419+
let description = external_node.description_invoice();
1420+
let invoice_description =
1421+
Bolt11InvoiceDescription::Direct(Description::new(description).unwrap());
1422+
let ldk_invoice =
1423+
node.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();
1424+
external_node.pay_invoice(&ldk_invoice.to_string());
1425+
1426+
expect_event!(node, PaymentReceived);
1427+
}
1428+
1429+
pub(crate) fn do_ldk_opens_channel_with_external_node<E: ExternalLightningNode>(
1430+
external_node: &mut E,
1431+
) {
1432+
// Initialize LDK node and clients
1433+
let (node, bitcoind_client, electrs_client) = init_setup_test_external_node();
1434+
1435+
// setup external node info
1436+
let (external_node_id, external_node_address) = external_node.get_node_info();
1437+
1438+
println!(
1439+
"Opening channel with external node: {} at {}",
1440+
external_node_id, external_node_address
1441+
);
1442+
// Open the channel
1443+
let funding_amount_sat = 2_000_000;
1444+
let push_msat = Some(500_000_000);
1445+
let user_channel_id = open_channel_by_node_id(
1446+
&bitcoind_client,
1447+
&electrs_client,
1448+
&node,
1449+
external_node_id,
1450+
external_node_address,
1451+
funding_amount_sat,
1452+
push_msat,
1453+
);
1454+
1455+
println!("Sending payment to external node");
1456+
// Send a payment to the external node
1457+
let invoice_amount_sat = 100_000_000;
1458+
ldk_send_payment_to_external_node(&node, external_node, invoice_amount_sat);
1459+
ldk_check_send_payment_succeeds(&node, external_node, 1);
1460+
1461+
println!("Sending payment to ldk");
1462+
// Send a payment to LDK
1463+
let amount_msat = 9_000_000;
1464+
assert!(external_node.can_send_payment(node.node_id().to_string(), amount_msat));
1465+
ldk_receive_payment_from_external_node(&node, external_node, amount_msat);
1466+
1467+
println!("Closing channel with external node");
1468+
// Close the channel
1469+
node.close_channel(&user_channel_id, external_node_id).unwrap();
1470+
expect_event!(node, ChannelClosed);
1471+
node.stop().unwrap();
1472+
}

0 commit comments

Comments
 (0)