|
1 | 1 | use crate::builder::NodeBuilder;
|
2 | 2 | use crate::io::test_utils::TestSyncStore;
|
3 | 3 | use crate::test::utils::*;
|
4 |
| -use crate::test::utils::{expect_event, random_config, setup_two_nodes}; |
| 4 | +use crate::test::utils::{expect_channel_pending_event, expect_event, open_channel, random_config}; |
5 | 5 | use crate::{Error, Event, Node, PaymentDirection, PaymentStatus};
|
6 | 6 |
|
7 | 7 | use bitcoin::Amount;
|
@@ -86,24 +86,13 @@ fn do_channel_full_cycle<K: KVStore + Sync + Send>(
|
86 | 86 | .unwrap();
|
87 | 87 |
|
88 | 88 | assert_eq!(node_a.list_peers().first().unwrap().node_id, node_b.node_id());
|
89 |
| - expect_event!(node_a, ChannelPending); |
| 89 | + let funding_txo_a = expect_channel_pending_event!(node_a, node_b.node_id()); |
| 90 | + let funding_txo_b = expect_channel_pending_event!(node_b, node_a.node_id()); |
| 91 | + assert_eq!(funding_txo_a, funding_txo_b); |
90 | 92 |
|
91 |
| - let funding_txo = match node_b.wait_next_event() { |
92 |
| - ref e @ Event::ChannelPending { funding_txo, .. } => { |
93 |
| - println!("{} got event {:?}", std::stringify!(node_b), e); |
94 |
| - assert_eq!(node_b.next_event().as_ref(), Some(e)); |
95 |
| - node_b.event_handled(); |
96 |
| - funding_txo |
97 |
| - } |
98 |
| - ref e => { |
99 |
| - panic!("{} got unexpected event!: {:?}", std::stringify!(node_b), e); |
100 |
| - } |
101 |
| - }; |
102 |
| - |
103 |
| - wait_for_tx(&electrsd, funding_txo.txid); |
| 93 | + wait_for_tx(&electrsd, funding_txo_a.txid); |
104 | 94 |
|
105 | 95 | if !allow_0conf {
|
106 |
| - println!("\n .. generating blocks .."); |
107 | 96 | generate_blocks_and_wait(&bitcoind, &electrsd, 6);
|
108 | 97 | }
|
109 | 98 |
|
@@ -276,7 +265,7 @@ fn do_channel_full_cycle<K: KVStore + Sync + Send>(
|
276 | 265 | expect_event!(node_a, ChannelClosed);
|
277 | 266 | expect_event!(node_b, ChannelClosed);
|
278 | 267 |
|
279 |
| - wait_for_outpoint_spend(&electrsd, funding_txo); |
| 268 | + wait_for_outpoint_spend(&electrsd, funding_txo_b); |
280 | 269 |
|
281 | 270 | generate_blocks_and_wait(&bitcoind, &electrsd, 1);
|
282 | 271 | node_a.sync_wallets().unwrap();
|
@@ -341,6 +330,83 @@ fn channel_open_fails_when_funds_insufficient() {
|
341 | 330 | );
|
342 | 331 | }
|
343 | 332 |
|
| 333 | +#[test] |
| 334 | +fn multi_hop_sending() { |
| 335 | + let (bitcoind, electrsd) = setup_bitcoind_and_electrsd(); |
| 336 | + let esplora_url = format!("http://{}", electrsd.esplora_url.as_ref().unwrap()); |
| 337 | + |
| 338 | + // Setup and fund 5 nodes |
| 339 | + let mut nodes = Vec::new(); |
| 340 | + for _ in 0..5 { |
| 341 | + let config = random_config(); |
| 342 | + let mut builder = NodeBuilder::from_config(config); |
| 343 | + builder.set_esplora_server(esplora_url.clone()); |
| 344 | + let node = builder.build().unwrap(); |
| 345 | + node.start().unwrap(); |
| 346 | + nodes.push(node); |
| 347 | + } |
| 348 | + |
| 349 | + let addresses = nodes.iter().map(|n| n.new_onchain_address().unwrap()).collect(); |
| 350 | + let premine_amount_sat = 5_000_000; |
| 351 | + premine_and_distribute_funds( |
| 352 | + &bitcoind, |
| 353 | + &electrsd, |
| 354 | + addresses, |
| 355 | + Amount::from_sat(premine_amount_sat), |
| 356 | + ); |
| 357 | + |
| 358 | + for n in &nodes { |
| 359 | + n.sync_wallets().unwrap(); |
| 360 | + assert_eq!(n.spendable_onchain_balance_sats().unwrap(), premine_amount_sat); |
| 361 | + assert_eq!(n.next_event(), None); |
| 362 | + } |
| 363 | + |
| 364 | + // Setup channel topology: |
| 365 | + // (1M:0)- N2 -(1M:0) |
| 366 | + // / \ |
| 367 | + // N0 -(100k:0)-> N1 N4 |
| 368 | + // \ / |
| 369 | + // (1M:0)- N3 -(1M:0) |
| 370 | + |
| 371 | + open_channel(&nodes[0], &nodes[1], 100_000, true, &electrsd); |
| 372 | + open_channel(&nodes[1], &nodes[2], 1_000_000, true, &electrsd); |
| 373 | + // We need to sync wallets in-between back-to-back channel opens from the same node so BDK |
| 374 | + // wallet picks up on the broadcast funding tx and doesn't double-spend itself. |
| 375 | + // |
| 376 | + // TODO: Remove once fixed in BDK. |
| 377 | + nodes[1].sync_wallets().unwrap(); |
| 378 | + open_channel(&nodes[1], &nodes[3], 1_000_000, true, &electrsd); |
| 379 | + open_channel(&nodes[2], &nodes[4], 1_000_000, true, &electrsd); |
| 380 | + open_channel(&nodes[3], &nodes[4], 1_000_000, true, &electrsd); |
| 381 | + |
| 382 | + generate_blocks_and_wait(&bitcoind, &electrsd, 6); |
| 383 | + |
| 384 | + for n in &nodes { |
| 385 | + n.sync_wallets().unwrap(); |
| 386 | + } |
| 387 | + |
| 388 | + expect_event!(nodes[0], ChannelReady); |
| 389 | + expect_event!(nodes[1], ChannelReady); |
| 390 | + expect_event!(nodes[1], ChannelReady); |
| 391 | + expect_event!(nodes[1], ChannelReady); |
| 392 | + expect_event!(nodes[2], ChannelReady); |
| 393 | + expect_event!(nodes[2], ChannelReady); |
| 394 | + expect_event!(nodes[3], ChannelReady); |
| 395 | + expect_event!(nodes[3], ChannelReady); |
| 396 | + expect_event!(nodes[4], ChannelReady); |
| 397 | + expect_event!(nodes[4], ChannelReady); |
| 398 | + |
| 399 | + // Sleep a bit for gossip to propagate. |
| 400 | + // FIXME: This doesn't work anyways currently and should be removed when we have a solution. |
| 401 | + std::thread::sleep(std::time::Duration::from_secs(60)); |
| 402 | + |
| 403 | + let invoice = nodes[4].receive_payment(10000, &"asdf", 9217).unwrap(); |
| 404 | + nodes[0].send_payment(&invoice).unwrap(); |
| 405 | + |
| 406 | + expect_event!(nodes[4], PaymentReceived); |
| 407 | + expect_event!(nodes[0], PaymentSuccessful); |
| 408 | +} |
| 409 | + |
344 | 410 | #[test]
|
345 | 411 | fn connect_to_public_testnet_esplora() {
|
346 | 412 | let mut config = random_config();
|
|
0 commit comments