|
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,82 @@ 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 | + std::thread::sleep(std::time::Duration::from_secs(1)); |
| 401 | + |
| 402 | + let invoice = nodes[4].receive_payment(2_500_000, &"asdf", 9217).unwrap(); |
| 403 | + nodes[0].send_payment(&invoice).unwrap(); |
| 404 | + |
| 405 | + expect_event!(nodes[4], PaymentReceived); |
| 406 | + expect_event!(nodes[0], PaymentSuccessful); |
| 407 | +} |
| 408 | + |
344 | 409 | #[test] |
345 | 410 | fn connect_to_public_testnet_esplora() { |
346 | 411 | let mut config = random_config(); |
|
0 commit comments