diff --git a/migrate/Cargo.lock b/migrate/Cargo.lock index 94770780..879e5354 100644 --- a/migrate/Cargo.lock +++ b/migrate/Cargo.lock @@ -1710,7 +1710,7 @@ dependencies = [ [[package]] name = "fnn" -version = "0.3.0" +version = "0.3.1" dependencies = [ "anyhow", "arcode", @@ -1772,7 +1772,7 @@ dependencies = [ "fnn 0.2.0", "fnn 0.2.1 (git+https://github.com/nervosnetwork/fiber.git?tag=v0.2.1)", "fnn 0.2.1 (git+https://github.com/nervosnetwork/fiber.git?tag=v0.3.0-rc1)", - "fnn 0.3.0", + "fnn 0.3.1", "hex", "indicatif", "serde", diff --git a/src/fiber/channel.rs b/src/fiber/channel.rs index 641f2cda..d084c07b 100644 --- a/src/fiber/channel.rs +++ b/src/fiber/channel.rs @@ -645,7 +645,9 @@ where TlcErrorCode::PermanentChannelFailure } ChannelState::ChannelReady() => { - if error.contains("channel is not public or disabled") { + eprintln!("debug now InvalidState error: {}", error); + if !state.local_tlc_info.enabled { + // channel is disabled TlcErrorCode::TemporaryChannelFailure } else { // we expect `ChannelReady` will be both OK for tlc forwarding, @@ -1012,7 +1014,7 @@ where return Err(ProcessingChannelError::FinalIncorrectPaymentHash); } } else { - if state.is_public() && state.is_tlc_forwarding_enabled() { + if state.is_public() { if add_tlc.expiry < peeled_onion_packet.current.expiry + state.local_tlc_info.tlc_expiry_delta { @@ -1037,9 +1039,11 @@ where } else { // if we don't have public channel info, we can not forward the TLC // this may happended some malicious sender build a invalid onion router + // here we don't need to check the next channel maybe disabled, because + // handle_add_tlc_command will check the channel state before forwarding + eprintln!("got here ........."); return Err(ProcessingChannelError::InvalidState( - "Received AddTlc message, but the channel is not public or disabled" - .to_string(), + "Received AddTlc message, but the channel is not public".to_string(), )); } } diff --git a/src/fiber/network.rs b/src/fiber/network.rs index 8877d0cc..61aafe62 100644 --- a/src/fiber/network.rs +++ b/src/fiber/network.rs @@ -1530,6 +1530,8 @@ where .write() .await .record_payment_fail(&payment_session, error_detail.clone()); + eprintln!("yukang payment fail: {:?}", error_detail); + eprintln!("yukang need_to_retry: {:?}", need_to_retry); if need_to_retry { // If this is the first hop error, like the WaitingTlcAck error, // we will just retry later, return Ok here for letting endpoint user @@ -1783,6 +1785,7 @@ where let hops_info = self .build_payment_route(&mut payment_session, &payment_data) .await?; + match self .send_payment_onion_packet(state, &mut payment_session, &payment_data, hops_info) .await diff --git a/src/fiber/tests/channel.rs b/src/fiber/tests/channel.rs index f22ca4ef..52d7e0ac 100644 --- a/src/fiber/tests/channel.rs +++ b/src/fiber/tests/channel.rs @@ -3468,42 +3468,42 @@ async fn test_forward_payment_channel_disabled() { true, ) .await; - let [node_a, node_b, node_c] = nodes.try_into().expect("3 nodes"); + let [mut node_a, mut node_b, mut node_c] = nodes.try_into().expect("3 nodes"); let [_channel_a_b, channel_b_c] = channels.try_into().expect("2 channels"); - let node_c_pubkey = node_c.pubkey.clone(); - tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await; - let tlc_amount = 100; + let res = node_a + .send_payment_keysend(&node_c, 10_000_000, false) + .await; + assert!(res.is_ok(), "Send payment failed: {:?}", res); + let res = res.unwrap(); + let payment_hash = res.payment_hash; + node_a.wait_until_success(payment_hash).await; - let message = |rpc_reply| -> NetworkActorMessage { - NetworkActorMessage::Command(NetworkActorCommand::SendPayment( - SendPaymentCommand { - target_pubkey: Some(node_c_pubkey), - amount: Some(tlc_amount), - payment_hash: None, - final_tlc_expiry_delta: None, - tlc_expiry_limit: None, - invoice: None, - timeout: None, - max_fee_amount: None, - max_parts: None, - keysend: Some(true), - udt_type_script: None, - allow_self_payment: false, - hop_hints: None, - dry_run: false, - }, - rpc_reply, - )) - }; - let res = call!(node_a.network_actor, message) - .expect("node_a alive") - .unwrap(); - // this is the payment_hash generated by keysend - assert_eq!(res.status, PaymentSessionStatus::Created); - tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await; + let res = node_b + .send_payment_keysend(&node_c, 10_000_000, false) + .await; + assert!(res.is_ok(), "Send payment failed: {:?}", res); + let res = res.unwrap(); + let payment_hash = res.payment_hash; + node_b.wait_until_success(payment_hash).await; + + let res = node_c + .send_payment_keysend(&node_a, 10_000_000, false) + .await; + assert!(res.is_ok(), "Send payment failed: {:?}", res); + let res = res.unwrap(); + let payment_hash = res.payment_hash; + node_c.wait_until_success(payment_hash).await; + + let res = node_b + .send_payment_keysend(&node_a, 10_000_000, false) + .await; + assert!(res.is_ok(), "Send payment failed: {:?}", res); + let res = res.unwrap(); + let payment_hash = res.payment_hash; + node_b.wait_until_success(payment_hash).await; // update channel to disable it from node_b let update_result = call!(node_b.network_actor, |rpc_reply| { @@ -3526,29 +3526,31 @@ async fn test_forward_payment_channel_disabled() { assert!(update_result.is_ok()); tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await; - let message = |rpc_reply| -> NetworkActorMessage { - NetworkActorMessage::Command(NetworkActorCommand::SendPayment( - SendPaymentCommand { - target_pubkey: Some(node_c_pubkey), - amount: Some(tlc_amount), - payment_hash: None, - final_tlc_expiry_delta: None, - tlc_expiry_limit: None, - invoice: None, - timeout: None, - max_fee_amount: None, - max_parts: None, - keysend: Some(true), - udt_type_script: None, - allow_self_payment: false, - hop_hints: None, - dry_run: false, - }, - rpc_reply, - )) - }; - let res = call!(node_a.network_actor, message).expect("node_a alive"); - assert!(res.is_err()); + let res = node_a + .send_payment_keysend(&node_c, 10_000_000, false) + .await; + assert!(res.is_err(), "Send payment should fail: {:?}", res); + + let res = node_b + .send_payment_keysend(&node_c, 10_000_000, false) + .await; + assert!(res.is_err(), "Send payment should fail: {:?}", res); + + let res = node_c + .send_payment_keysend(&node_b, 10_000_000, false) + .await; + assert!(res.is_ok(), "Send payment failed: {:?}", res); + let res = res.unwrap(); + let payment_hash = res.payment_hash; + node_c.wait_until_success(payment_hash).await; + + let res = node_c + .send_payment_keysend(&node_a, 80_000_000, false) + .await; + assert!(res.is_ok(), "Send payment failed: {:?}", res); + let res = res.unwrap(); + let payment_hash = res.payment_hash; + node_c.wait_until_success(payment_hash).await; } #[tokio::test] @@ -5146,49 +5148,34 @@ async fn test_send_payment_with_disable_channel() { let amounts = vec![(100000000000, 100000000000); nodes_num - 1]; let (nodes, channels) = create_n_nodes_with_established_channel(&amounts, nodes_num, true).await; - let [node_0, _node_1, mut node_2, node_3] = nodes.try_into().expect("4 nodes"); - let source_node = &node_0; - let target_pubkey = node_3.pubkey.clone(); - - // sleep for a while - tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + let [mut node_0, _node_1, mut node_2, mut node_3] = nodes.try_into().expect("4 nodes"); // begin to set channel disable, but do not notify the network node_2.disable_channel_stealthy(channels[1]).await; tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let message = |rpc_reply| -> NetworkActorMessage { - NetworkActorMessage::Command(NetworkActorCommand::SendPayment( - SendPaymentCommand { - target_pubkey: Some(target_pubkey.clone()), - amount: Some(3000), - payment_hash: None, - final_tlc_expiry_delta: None, - tlc_expiry_limit: None, - invoice: None, - timeout: None, - max_fee_amount: None, - max_parts: None, - keysend: Some(true), - udt_type_script: None, - allow_self_payment: false, - hop_hints: None, - dry_run: false, - }, - rpc_reply, - )) - }; - - // expect send payment failed - let res = call!(source_node.network_actor, message).expect("source_node alive"); + // expect send payment failed from node_3 to node_0 + //let res = call!(source_node.network_actor, message).expect("source_node alive"); + let res = node_3.send_payment_keysend(&node_0, 3000, false).await; assert!(res.is_ok()); let payment_hash = res.unwrap().payment_hash; - source_node.wait_until_failed(payment_hash).await; + node_3.wait_until_failed(payment_hash).await; + // because there is only one path for the payment, the payment will fail in the second try // this assertion make sure we didn't do meaningless retry - let payment_session = source_node.get_payment_session(payment_hash).unwrap(); + let payment_session = node_3.get_payment_session(payment_hash).unwrap(); assert_eq!(payment_session.retried_times, 2); + + // expect send payment successfully from node_0 to node_3 + let res = node_0.send_payment_keysend(&node_3, 3000, false).await; + assert!(res.is_ok()); + let payment_hash = res.unwrap().payment_hash; + + node_0.wait_until_success(payment_hash).await; + + let payment_session = node_0.get_payment_session(payment_hash).unwrap(); + assert_eq!(payment_session.retried_times, 1); } #[tokio::test] diff --git a/src/fiber/tests/payment.rs b/src/fiber/tests/payment.rs index 0e0a6929..d6b77066 100644 --- a/src/fiber/tests/payment.rs +++ b/src/fiber/tests/payment.rs @@ -303,12 +303,19 @@ async fn test_send_payment_over_private_channel() { eprintln!("res: {:?}", res); if is_payment_ok { assert!(res.is_ok()); + source_node + .wait_until_success(res.unwrap().payment_hash) + .await; } else { assert!(res.is_err()); + source_node + .wait_until_failed(res.unwrap().payment_hash) + .await; } } test(10000000000, true).await; + tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await; test(30000000000, false).await; }