Skip to content

Commit 3bf2169

Browse files
committed
f Replace persistence guard with simple update method
1 parent 1c0b501 commit 3bf2169

File tree

3 files changed

+125
-96
lines changed

3 files changed

+125
-96
lines changed

src/event.rs

+61-24
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ where
337337
);
338338
self.channel_manager.fail_htlc_backwards(&payment_hash);
339339
self.payment_store
340-
.set_status(&payment_hash, PaymentStatus::Failed)
340+
.update(&payment_hash, None, None, None, Some(PaymentStatus::Failed))
341341
.expect("Failed to access payment store");
342342
return;
343343
}
@@ -372,7 +372,7 @@ where
372372
);
373373
self.channel_manager.fail_htlc_backwards(&payment_hash);
374374
self.payment_store
375-
.set_status(&payment_hash, PaymentStatus::Failed)
375+
.update(&payment_hash, None, None, None, Some(PaymentStatus::Failed))
376376
.expect("Failed to access payment store");
377377
}
378378
}
@@ -388,31 +388,68 @@ where
388388
hex_utils::to_string(&payment_hash.0),
389389
amount_msat,
390390
);
391-
let (payment_preimage, payment_secret) = match purpose {
391+
match purpose {
392392
PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
393-
(payment_preimage, Some(payment_secret))
393+
match self.payment_store.update(
394+
&payment_hash,
395+
Some(payment_preimage),
396+
Some(Some(payment_secret)),
397+
Some(Some(amount_msat)),
398+
Some(PaymentStatus::Succeeded),
399+
) {
400+
Ok(true) => (),
401+
Ok(false) => {
402+
log_error!(
403+
self.logger,
404+
"Payment with hash {} couldn't be found in store",
405+
hex_utils::to_string(&payment_hash.0)
406+
);
407+
debug_assert!(false);
408+
}
409+
Err(e) => {
410+
log_error!(
411+
self.logger,
412+
"Failed to update payment with hash {}: {}",
413+
hex_utils::to_string(&payment_hash.0),
414+
e
415+
);
416+
debug_assert!(false);
417+
}
418+
}
419+
}
420+
PaymentPurpose::SpontaneousPayment(preimage) => {
421+
let payment_info = PaymentInfo {
422+
preimage: Some(preimage),
423+
payment_hash,
424+
secret: None,
425+
amount_msat: Some(amount_msat),
426+
direction: PaymentDirection::Inbound,
427+
status: PaymentStatus::Succeeded,
428+
};
429+
430+
match self.payment_store.insert(payment_info) {
431+
Ok(false) => (),
432+
Ok(true) => {
433+
log_error!(
434+
self.logger,
435+
"Spontaneous payment with hash {} was previosly known",
436+
hex_utils::to_string(&payment_hash.0)
437+
);
438+
debug_assert!(false);
439+
}
440+
Err(e) => {
441+
log_error!(
442+
self.logger,
443+
"Failed to insert payment with hash {}: {}",
444+
hex_utils::to_string(&payment_hash.0),
445+
e
446+
);
447+
debug_assert!(false);
448+
}
449+
}
394450
}
395-
PaymentPurpose::SpontaneousPayment(preimage) => (Some(preimage), None),
396451
};
397452

398-
let mut locked_store = self.payment_store.lock().unwrap();
399-
locked_store
400-
.entry(payment_hash)
401-
.and_modify(|payment_info| {
402-
payment_info.status = PaymentStatus::Succeeded;
403-
payment_info.preimage = payment_preimage;
404-
payment_info.secret = payment_secret;
405-
payment_info.amount_msat = Some(amount_msat);
406-
})
407-
.or_insert(PaymentInfo {
408-
preimage: payment_preimage,
409-
payment_hash,
410-
secret: payment_secret,
411-
amount_msat: Some(amount_msat),
412-
direction: PaymentDirection::Inbound,
413-
status: PaymentStatus::Succeeded,
414-
});
415-
416453
self.event_queue
417454
.add_event(Event::PaymentReceived { payment_hash, amount_msat })
418455
.expect("Failed to push to event queue");
@@ -450,7 +487,7 @@ where
450487
);
451488

452489
self.payment_store
453-
.set_status(&payment_hash, PaymentStatus::Failed)
490+
.update(&payment_hash, None, None, None, Some(PaymentStatus::Failed))
454491
.expect("Failed to access payment store");
455492
self.event_queue
456493
.add_event(Event::PaymentFailed { payment_hash })

src/lib.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,13 @@ impl Node {
10421042
Err(payment::PaymentError::Sending(e)) => {
10431043
log_error!(self.logger, "Failed to send payment: {:?}", e);
10441044

1045-
self.payment_store.set_status(&payment_hash, PaymentStatus::Failed)?;
1045+
self.payment_store.update(
1046+
&payment_hash,
1047+
None,
1048+
None,
1049+
None,
1050+
Some(PaymentStatus::Failed),
1051+
)?;
10461052
Err(Error::PaymentFailed)
10471053
}
10481054
}
@@ -1131,7 +1137,13 @@ impl Node {
11311137
Err(payment::PaymentError::Sending(e)) => {
11321138
log_error!(self.logger, "Failed to send payment: {:?}", e);
11331139

1134-
self.payment_store.set_status(&payment_hash, PaymentStatus::Failed)?;
1140+
self.payment_store.update(
1141+
&payment_hash,
1142+
None,
1143+
None,
1144+
None,
1145+
Some(PaymentStatus::Failed),
1146+
)?;
11351147
Err(Error::PaymentFailed)
11361148
}
11371149
}

src/payment_store.rs

+50-70
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
77
use lightning::util::ser::Writeable;
88
use lightning::{impl_writeable_tlv_based, impl_writeable_tlv_based_enum};
99

10-
use std::collections::hash_map;
11-
use std::collections::{HashMap, HashSet};
10+
use std::collections::HashMap;
1211
use std::iter::FromIterator;
1312
use std::ops::Deref;
14-
use std::sync::{Mutex, MutexGuard};
13+
use std::sync::Mutex;
1514

1615
/// Represents a payment.
1716
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -97,17 +96,13 @@ where
9796
Self { payments, kv_store, logger }
9897
}
9998

100-
pub(crate) fn insert(&self, payment_info: PaymentInfo) -> Result<(), Error> {
99+
pub(crate) fn insert(&self, payment_info: PaymentInfo) -> Result<bool, Error> {
101100
let mut locked_payments = self.payments.lock().unwrap();
102101

103102
let payment_hash = payment_info.payment_hash.clone();
104-
locked_payments.insert(payment_hash.clone(), payment_info.clone());
105-
self.write_info_and_commit(&payment_hash, &payment_info)
106-
}
107-
108-
pub(crate) fn lock(&self) -> Result<PaymentInfoGuard<K>, ()> {
109-
let locked_store = self.payments.lock().map_err(|_| ())?;
110-
Ok(PaymentInfoGuard::new(locked_store, self.kv_store.clone()))
103+
let updated = locked_payments.insert(payment_hash.clone(), payment_info.clone()).is_some();
104+
self.write_info_and_commit(&payment_hash, &payment_info)?;
105+
Ok(updated)
111106
}
112107

113108
pub(crate) fn remove(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
@@ -133,16 +128,36 @@ where
133128
self.payments.lock().unwrap().contains_key(payment_hash)
134129
}
135130

136-
pub(crate) fn set_status(
137-
&self, payment_hash: &PaymentHash, payment_status: PaymentStatus,
138-
) -> Result<(), Error> {
131+
pub(crate) fn update(
132+
&self, payment_hash: &PaymentHash, update_preimage: Option<Option<PaymentPreimage>>,
133+
update_secret: Option<Option<PaymentSecret>>, update_amount_msat: Option<Option<u64>>,
134+
update_status: Option<PaymentStatus>,
135+
) -> Result<bool, Error> {
136+
let mut updated = false;
139137
let mut locked_payments = self.payments.lock().unwrap();
140138

141139
if let Some(payment_info) = locked_payments.get_mut(payment_hash) {
142-
payment_info.status = payment_status;
140+
if let Some(preimage_opt) = update_preimage {
141+
payment_info.preimage = preimage_opt;
142+
}
143+
144+
if let Some(secret_opt) = update_secret {
145+
payment_info.secret = secret_opt;
146+
}
147+
148+
if let Some(amount_opt) = update_amount_msat {
149+
payment_info.amount_msat = amount_opt;
150+
}
151+
152+
if let Some(status) = update_status {
153+
payment_info.status = status;
154+
}
155+
143156
self.write_info_and_commit(payment_hash, payment_info)?;
157+
updated = true;
144158
}
145-
Ok(())
159+
160+
Ok(updated)
146161
}
147162

148163
fn write_info_and_commit(
@@ -184,59 +199,6 @@ where
184199
}
185200
}
186201

187-
pub(crate) struct PaymentInfoGuard<'a, K: Deref>
188-
where
189-
K::Target: KVStore,
190-
{
191-
inner: MutexGuard<'a, HashMap<PaymentHash, PaymentInfo>>,
192-
touched_keys: HashSet<PaymentHash>,
193-
kv_store: K,
194-
}
195-
196-
impl<'a, K: Deref> PaymentInfoGuard<'a, K>
197-
where
198-
K::Target: KVStore,
199-
{
200-
pub fn new(inner: MutexGuard<'a, HashMap<PaymentHash, PaymentInfo>>, kv_store: K) -> Self {
201-
let touched_keys = HashSet::new();
202-
Self { inner, touched_keys, kv_store }
203-
}
204-
205-
pub fn entry(
206-
&mut self, payment_hash: PaymentHash,
207-
) -> hash_map::Entry<PaymentHash, PaymentInfo> {
208-
self.touched_keys.insert(payment_hash);
209-
self.inner.entry(payment_hash)
210-
}
211-
}
212-
213-
impl<'a, K: Deref> Drop for PaymentInfoGuard<'a, K>
214-
where
215-
K::Target: KVStore,
216-
{
217-
fn drop(&mut self) {
218-
for key in self.touched_keys.iter() {
219-
let store_key = hex_utils::to_string(&key.0);
220-
221-
match self.inner.entry(*key) {
222-
hash_map::Entry::Vacant(_) => {
223-
self.kv_store
224-
.remove(PAYMENT_INFO_PERSISTENCE_NAMESPACE, &store_key)
225-
.expect("Persistence failed");
226-
}
227-
hash_map::Entry::Occupied(e) => {
228-
let mut writer = self
229-
.kv_store
230-
.write(PAYMENT_INFO_PERSISTENCE_NAMESPACE, &store_key)
231-
.expect("Persistence failed");
232-
e.get().write(&mut writer).expect("Persistence failed");
233-
writer.commit().expect("Persistence failed");
234-
}
235-
};
236-
}
237-
}
238-
}
239-
240202
#[cfg(test)]
241203
mod tests {
242204
use super::*;
@@ -262,7 +224,25 @@ mod tests {
262224
};
263225

264226
assert!(!store.get_and_clear_did_persist());
265-
payment_info_store.lock().unwrap().entry(payment_hash).or_insert(payment_info);
227+
228+
assert_eq!(Ok(false), payment_info_store.insert(payment_info.clone()));
266229
assert!(store.get_and_clear_did_persist());
230+
231+
assert_eq!(Ok(true), payment_info_store.insert(payment_info));
232+
assert!(store.get_and_clear_did_persist());
233+
234+
assert_eq!(
235+
Ok(true),
236+
payment_info_store.update(
237+
&payment_hash,
238+
None,
239+
None,
240+
None,
241+
Some(PaymentStatus::Succeeded)
242+
)
243+
);
244+
assert!(store.get_and_clear_did_persist());
245+
246+
assert_eq!(PaymentStatus::Succeeded, payment_info_store.get(&payment_hash).unwrap().status);
267247
}
268248
}

0 commit comments

Comments
 (0)