Skip to content

Commit 73c9554

Browse files
authored
Merge pull request #79 from lightningdevkit/fix-rebalance-times
Show backend settle time for trusted receives
2 parents eea8178 + 57e6804 commit 73c9554

2 files changed

Lines changed: 73 additions & 2 deletions

File tree

orange-sdk/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,17 @@ impl Wallet {
844844
amount: Some(payment.amount),
845845
fee: Some(payment.fee),
846846
payment_type: *ty,
847-
time_since_epoch: tx_metadata.time,
847+
// Inbound receives use the backend's settle time. The rebalancer
848+
// stamps `tx_metadata.time` with `now()` when it first observes a
849+
// payment, so a receive that settled while we were offline would
850+
// otherwise be dated to the next launch and float to the top of
851+
// the time-sorted history. Outbound sends, which we observe as
852+
// they happen, keep the metadata time.
853+
time_since_epoch: if payment.outbound {
854+
tx_metadata.time
855+
} else {
856+
payment.time_since_epoch
857+
},
848858
});
849859
},
850860
TxType::PendingRebalance { .. } => {

orange-sdk/tests/integration_tests.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ldk_node::payment::{ConfirmationStatus, PaymentDirection, PaymentStatus};
1111
use log::info;
1212
use orange_sdk::{Event, PaymentInfo, PaymentType, TxStatus, WalletError};
1313
use std::sync::Arc;
14-
use std::time::Duration;
14+
use std::time::{Duration, SystemTime, UNIX_EPOCH};
1515

1616
mod test_utils;
1717

@@ -85,6 +85,67 @@ async fn test_receive_to_trusted() {
8585
.await;
8686
}
8787

88+
#[tokio::test(flavor = "multi_thread")]
89+
#[test_log::test]
90+
async fn test_trusted_receive_keeps_backend_settle_time() {
91+
test_utils::run_test(|params| async move {
92+
let wallet = Arc::clone(&params.wallet);
93+
let third_party = Arc::clone(&params.third_party);
94+
95+
// Disable rebalancing before the payment exists so the rebalancer does not
96+
// stamp a discovery time when it first observes the receive.
97+
wallet.set_rebalance_enabled(false).await;
98+
99+
let recv_amt = Amount::from_sats(100).unwrap();
100+
assert!(recv_amt < wallet.get_tunables().trusted_balance_limit);
101+
102+
let uri = wallet.get_single_use_receive_uri(Some(recv_amt)).await.unwrap();
103+
assert!(uri.from_trusted);
104+
let payment_id = third_party.bolt11_payment().send(&uri.invoice, None).unwrap();
105+
106+
let p = Arc::clone(&third_party);
107+
test_utils::wait_for_condition("payer payment success", || {
108+
let res = p.payment(&payment_id).is_some_and(|p| p.status == PaymentStatus::Succeeded);
109+
async move { res }
110+
})
111+
.await;
112+
113+
test_utils::wait_for_condition("wallet balance update after receive", || async {
114+
wallet.get_balance().await.unwrap().available_balance() > Amount::ZERO
115+
})
116+
.await;
117+
118+
// The backend has recorded the settle time ~now. Sleep so any later
119+
// discovery stamp lands a clearly later wall-clock time, then mark that
120+
// boundary just before we let the rebalancer run.
121+
tokio::time::sleep(Duration::from_secs(3)).await;
122+
let enabled_at = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
123+
124+
// Re-enable rebalancing and drain the PaymentReceived event. Handling the
125+
// event triggers the rebalancer, which observes the payment for the first
126+
// time and stamps its discovery time (>= enabled_at). Give the spawned
127+
// rebalance check a moment to record it.
128+
wallet.set_rebalance_enabled(true).await;
129+
let event = test_utils::wait_next_event(&wallet).await;
130+
assert!(matches!(event, Event::PaymentReceived { .. }));
131+
tokio::time::sleep(Duration::from_secs(3)).await;
132+
133+
let txs = wallet.list_transactions().await.unwrap();
134+
assert_eq!(txs.len(), 1);
135+
let tx = txs.into_iter().next().unwrap();
136+
137+
// Must be the backend settle time (recorded ~3s before we re-enabled),
138+
// strictly earlier than the discovery stamp written at/after `enabled_at`.
139+
assert!(
140+
tx.time_since_epoch < enabled_at,
141+
"expected backend settle time, got discovery stamp: {:?} >= {:?}",
142+
tx.time_since_epoch,
143+
enabled_at
144+
);
145+
})
146+
.await;
147+
}
148+
88149
#[tokio::test(flavor = "multi_thread")]
89150
#[test_log::test]
90151
async fn test_pay_from_trusted() {

0 commit comments

Comments
 (0)