Skip to content

Commit

Permalink
retry a different channel when the there is a temporary channel error…
Browse files Browse the repository at this point in the history
… in first hop
  • Loading branch information
chenyukang committed Jan 9, 2025
1 parent 181ea20 commit f34882a
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 7 deletions.
3 changes: 3 additions & 0 deletions src/fiber/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ impl InternalResult {
| TlcErrorCode::ExpiryTooFar => {
need_to_retry = false;
}
TlcErrorCode::TemporaryChannelFailure => {
self.fail_pair_balanced(nodes, index + 1);
}
_ => {
// we can not penalize our own node, the whole payment session need to retry
}
Expand Down
15 changes: 8 additions & 7 deletions src/fiber/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1713,15 +1713,16 @@ where
return;
}

let need_to_retry = self
.network_graph
.write()
.await
.record_payment_fail(&payment_session, tlc_err.clone());
if matches!(channel_error, ProcessingChannelError::WaitingTlcAck) {
let need_to_retry = if matches!(channel_error, ProcessingChannelError::WaitingTlcAck) {
payment_session.last_error = Some("WaitingTlcAck".to_string());
self.store.insert_payment_session(payment_session.clone());
}
true
} else {
self.network_graph
.write()
.await
.record_payment_fail(&payment_session, tlc_err.clone())
};
if need_to_retry {
let _ = self.try_payment_session(myself, state, payment_hash).await;
} else {
Expand Down
85 changes: 85 additions & 0 deletions src/fiber/tests/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1449,3 +1449,88 @@ async fn test_send_payment_middle_hop_stopped_retry_longer_path() {

node_0.wait_until_failed(res.payment_hash).await;
}

#[tokio::test]
async fn test_send_payment_max_value_in_flight_in_first_hop() {
// https://github.com/nervosnetwork/fiber/issues/450

init_tracing();
let _span = tracing::info_span!("node", node = "test").entered();
let nodes = NetworkNode::new_interconnected_nodes(2).await;
let [mut node_0, mut node_1] = nodes.try_into().expect("2 nodes");
let (_channel_id, _funding_tx) = {
establish_channel_between_nodes(
&mut node_0,
&mut node_1,
true,
HUGE_CKB_AMOUNT,
HUGE_CKB_AMOUNT,
None,
Some(100000000),
None,
None,
None,
None,
None,
None,
None,
None,
)
.await
};

tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;

let res = node_0
.send_payment_keysend(&node_1, 100000000 + 1, false)
.await
.unwrap();
eprintln!("res: {:?}", res);
assert_eq!(res.fee, 0);

let payment_hash = res.payment_hash;
node_0.wait_until_failed(payment_hash).await;

// now we can not send payment with amount 100000000 + 1 with dry_run
// since there is already payment history data
let res = node_0
.send_payment_keysend(&node_1, 100000000 + 1, true)
.await;
eprintln!("res: {:?}", res);
assert!(res.unwrap_err().to_string().contains("no path found"));

// if we build a nother channel with higher max_value_in_flight
// we can send payment with amount 100000000 + 1 with this new channel
let (_channel_id, _funding_tx) = {
establish_channel_between_nodes(
&mut node_0,
&mut node_1,
true,
HUGE_CKB_AMOUNT,
HUGE_CKB_AMOUNT,
None,
Some(100000000 + 2),
None,
None,
None,
None,
None,
None,
None,
None,
)
.await
};

tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;

let res = node_0
.send_payment_keysend(&node_1, 100000000 + 1, false)
.await
.unwrap();
eprintln!("res: {:?}", res);
assert_eq!(res.fee, 0);

let payment_hash = res.payment_hash;
node_0.wait_until_success(payment_hash).await;
}

0 comments on commit f34882a

Please sign in to comment.