Skip to content

Commit 052311a

Browse files
committed
Correctly emit PaymentReceivedEvent on rebalances
Previously we did not do this under bad assumptions. We were able to do this only because in tests we could guaranatee the payment ids were the same across trusted and self custodial because we were using ldk-node's payment id. However, with actual trusted backends we can't do this so we have no way to see if the payment is a rebalance until after we've received it. To prevent this from happening again we now mangle the id in DummyTrustedWallet so we don't accidentially have tests assuming that.
1 parent 983ec28 commit 052311a

5 files changed

Lines changed: 46 additions & 32 deletions

File tree

orange-sdk/src/event.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -359,23 +359,14 @@ impl LdkEventHandler {
359359
}
360360
});
361361

362-
let payment_id = PaymentId::Trusted(payment_id.0);
363-
let is_rebalance = {
364-
let map = self.tx_metadata.read();
365-
map.get(&payment_id).is_some_and(|m| m.ty.is_rebalance())
366-
};
367-
368-
// If this is a rebalance payment, we do not emit a PaymentReceived event.
369-
if !is_rebalance {
370-
if let Err(e) = self.event_queue.add_event(Event::PaymentReceived {
371-
payment_id,
372-
payment_hash,
373-
amount_msat,
374-
custom_records,
375-
lsp_fee_msats,
376-
}) {
377-
log_error!(self.logger, "Failed to add PaymentReceived event: {e:?}");
378-
}
362+
if let Err(e) = self.event_queue.add_event(Event::PaymentReceived {
363+
payment_id: PaymentId::SelfCustodial(payment_id.0),
364+
payment_hash,
365+
amount_msat,
366+
custom_records,
367+
lsp_fee_msats,
368+
}) {
369+
log_error!(self.logger, "Failed to add PaymentReceived event: {e:?}");
379370
}
380371
let _ = self.payment_receipt_sender.send(());
381372
},

orange-sdk/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use bitcoin_payment_instructions::PaymentMethod;
2020
use bitcoin_payment_instructions::amount::Amount;
2121

2222
use crate::rebalancer::{OrangeRebalanceEventHandler, OrangeTrigger};
23-
use crate::store::{PaymentId, TxMetadata, TxMetadataStore, TxType};
23+
use crate::store::{TxMetadata, TxMetadataStore, TxType};
2424
#[cfg(feature = "cashu")]
2525
use crate::trusted_wallet::cashu::Cashu;
2626
#[cfg(feature = "_test-utils")]
@@ -74,7 +74,7 @@ pub use ldk_node::bitcoin;
7474
pub use ldk_node::payment::ConfirmationStatus;
7575
#[cfg(feature = "spark")]
7676
pub use spark_wallet::{OperatorPoolConfig, ServiceProviderConfig, SparkWalletConfig};
77-
pub use store::{PaymentType, Transaction, TxStatus};
77+
pub use store::{PaymentId, PaymentType, Transaction, TxStatus};
7878
pub use trusted_wallet::ExtraConfig;
7979

8080
#[cfg(feature = "uniffi")]

orange-sdk/src/store.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ impl From<Transaction> for StoreTransaction {
130130
/// the payment to the user.
131131
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
132132
pub enum PaymentId {
133+
/// A self-custodial payment identifier.
133134
SelfCustodial([u8; 32]),
135+
/// A trusted payment identifier.
134136
Trusted([u8; 32]),
135137
}
136138

orange-sdk/src/trusted_wallet/dummy.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl DummyTrustedWallet {
9292
payment_preimage,
9393
} => {
9494
// convert id
95-
let id = payment_id.unwrap().0;
95+
let id = mangle_payment_id(payment_id.unwrap().0);
9696

9797
let mut payments = pays.write().unwrap();
9898
let item = payments.iter_mut().find(|p| p.id == id);
@@ -123,7 +123,7 @@ impl DummyTrustedWallet {
123123
},
124124
Event::PaymentFailed { payment_id, payment_hash, reason } => {
125125
// convert id
126-
let id = payment_id.unwrap().0;
126+
let id = mangle_payment_id(payment_id.unwrap().0);
127127

128128
let mut payments = pays.write().unwrap();
129129
let item = payments.iter().cloned().enumerate().find(|(_, p)| p.id == id);
@@ -152,7 +152,7 @@ impl DummyTrustedWallet {
152152
},
153153
Event::PaymentReceived { payment_id, amount_msat, payment_hash, .. } => {
154154
// convert id
155-
let id = payment_id.unwrap().0;
155+
let id = mangle_payment_id(payment_id.unwrap().0);
156156

157157
let mut payments = pays.write().unwrap();
158158
// We create invoices on the fly without adding the payment to our list
@@ -301,18 +301,24 @@ impl TrustedWalletInterface for DummyTrustedWallet {
301301
Box::pin(async move {
302302
let id = match method {
303303
PaymentMethod::LightningBolt11(inv) => {
304-
self.ldk_node
304+
let id = self
305+
.ldk_node
305306
.bolt11_payment()
306307
.send_using_amount(&inv, amount.milli_sats(), None)
307308
.unwrap()
308-
.0
309+
.0;
310+
311+
mangle_payment_id(id)
309312
},
310313
PaymentMethod::LightningBolt12(offer) => {
311-
self.ldk_node
314+
let id = self
315+
.ldk_node
312316
.bolt12_payment()
313317
.send_using_amount(&offer, amount.milli_sats(), None, None)
314318
.unwrap()
315-
.0
319+
.0;
320+
321+
mangle_payment_id(id)
316322
},
317323
PaymentMethod::OnChain(address) => {
318324
let txid = self
@@ -353,3 +359,13 @@ impl TrustedWalletInterface for DummyTrustedWallet {
353359
})
354360
}
355361
}
362+
363+
// we don't want our payment ids to be the same as LDK's, this ended up not testing
364+
// bad assumptions properly. So we mangle the payment id a bit here to avoid collisions.
365+
fn mangle_payment_id(id: [u8; 32]) -> [u8; 32] {
366+
let mut mangled = id;
367+
for i in 0..32 {
368+
mangled[i] = mangled[i].wrapping_add(0x42);
369+
}
370+
mangled
371+
}

orange-sdk/tests/integration_tests.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,18 +218,23 @@ fn test_sweep_to_ln() {
218218
_ => panic!("Expected ChannelOpened event"),
219219
}
220220

221-
// because of an issue in CDK, we skip the rest of this test
222-
// otherwise it will fail for now
223-
// TODO REMOVE ME
224-
if cfg!(feature = "_cashu-tests") {
225-
return;
221+
let expect_amt = intermediate_amt.saturating_add(recv_amt);
222+
223+
let event = wait_next_event(&wallet).await;
224+
match event {
225+
Event::PaymentReceived { payment_id, amount_msat, lsp_fee_msats, .. } => {
226+
assert!(matches!(payment_id, orange_sdk::PaymentId::SelfCustodial(_)));
227+
assert!(lsp_fee_msats.is_some());
228+
assert_eq!(amount_msat, expect_amt.milli_sats() - lsp_fee_msats.unwrap());
229+
},
230+
e => panic!("Expected RebalanceSuccessful event, got {e:?}"),
226231
}
227232

228233
let event = wait_next_event(&wallet).await;
229234
match event {
230235
Event::RebalanceSuccessful { amount_msat, fee_msat, .. } => {
231236
assert!(fee_msat > 0);
232-
assert_eq!(amount_msat, intermediate_amt.saturating_add(recv_amt).milli_sats());
237+
assert_eq!(amount_msat, expect_amt.milli_sats());
233238
},
234239
e => panic!("Expected RebalanceSuccessful event, got {e:?}"),
235240
}

0 commit comments

Comments
 (0)