Skip to content

Commit fea709d

Browse files
committed
Split inbound+outbound payments, use PaymentId as outbound key
1 parent aa1635c commit fea709d

File tree

3 files changed

+75
-50
lines changed

3 files changed

+75
-50
lines changed

src/cli.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::disk::{self, INBOUND_PAYMENTS_FNAME, OUTBOUND_PAYMENTS_FNAME};
22
use crate::hex_utils;
33
use crate::{
4-
ChannelManager, HTLCStatus, MillisatAmount, NetworkGraph, OnionMessenger, PaymentInfo,
5-
PaymentInfoStorage, PeerManager,
4+
ChannelManager, HTLCStatus, InboundPaymentInfoStorage, MillisatAmount, NetworkGraph,
5+
OnionMessenger, OutboundPaymentInfoStorage, PaymentInfo, PeerManager,
66
};
77
use bitcoin::hashes::sha256::Hash as Sha256;
88
use bitcoin::hashes::Hash;
@@ -63,9 +63,9 @@ impl Writeable for UserOnionMessageContents {
6363
pub(crate) fn poll_for_user_input(
6464
peer_manager: Arc<PeerManager>, channel_manager: Arc<ChannelManager>,
6565
keys_manager: Arc<KeysManager>, network_graph: Arc<NetworkGraph>,
66-
onion_messenger: Arc<OnionMessenger>, inbound_payments: Arc<Mutex<PaymentInfoStorage>>,
67-
outbound_payments: Arc<Mutex<PaymentInfoStorage>>, ldk_data_dir: String, network: Network,
68-
logger: Arc<disk::FilesystemLogger>, fs_store: Arc<FilesystemStore>,
66+
onion_messenger: Arc<OnionMessenger>, inbound_payments: Arc<Mutex<InboundPaymentInfoStorage>>,
67+
outbound_payments: Arc<Mutex<OutboundPaymentInfoStorage>>, ldk_data_dir: String,
68+
network: Network, logger: Arc<disk::FilesystemLogger>, fs_store: Arc<FilesystemStore>,
6969
) {
7070
println!(
7171
"LDK startup successful. Enter \"help\" to view available commands. Press Ctrl-D to quit."
@@ -553,7 +553,9 @@ fn list_channels(channel_manager: &Arc<ChannelManager>, network_graph: &Arc<Netw
553553
println!("]");
554554
}
555555

556-
fn list_payments(inbound_payments: &PaymentInfoStorage, outbound_payments: &PaymentInfoStorage) {
556+
fn list_payments(
557+
inbound_payments: &InboundPaymentInfoStorage, outbound_payments: &OutboundPaymentInfoStorage,
558+
) {
557559
print!("[");
558560
for (payment_hash, payment_info) in &inbound_payments.payments {
559561
println!("");
@@ -684,12 +686,12 @@ fn open_channel(
684686

685687
fn send_payment(
686688
channel_manager: &ChannelManager, invoice: &Bolt11Invoice,
687-
outbound_payments: &mut PaymentInfoStorage, fs_store: Arc<FilesystemStore>,
689+
outbound_payments: &mut OutboundPaymentInfoStorage, fs_store: Arc<FilesystemStore>,
688690
) {
689-
let payment_hash = PaymentHash((*invoice.payment_hash()).into_inner());
691+
let payment_id = PaymentId((*invoice.payment_hash()).into_inner());
690692
let payment_secret = Some(*invoice.payment_secret());
691693
outbound_payments.payments.insert(
692-
payment_hash,
694+
payment_id,
693695
PaymentInfo {
694696
preimage: None,
695697
secret: payment_secret,
@@ -708,25 +710,25 @@ fn send_payment(
708710
Err(e) => {
709711
println!("ERROR: failed to send payment: {:?}", e);
710712
print!("> ");
711-
outbound_payments.payments.get_mut(&payment_hash).unwrap().status = HTLCStatus::Failed;
713+
outbound_payments.payments.get_mut(&payment_id).unwrap().status = HTLCStatus::Failed;
712714
fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound_payments.encode()).unwrap();
713715
}
714716
};
715717
}
716718

717719
fn keysend<E: EntropySource>(
718720
channel_manager: &ChannelManager, payee_pubkey: PublicKey, amt_msat: u64, entropy_source: &E,
719-
outbound_payments: &mut PaymentInfoStorage, fs_store: Arc<FilesystemStore>,
721+
outbound_payments: &mut OutboundPaymentInfoStorage, fs_store: Arc<FilesystemStore>,
720722
) {
721723
let payment_preimage = PaymentPreimage(entropy_source.get_secure_random_bytes());
722-
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
724+
let payment_id = PaymentId(Sha256::hash(&payment_preimage.0[..]).into_inner());
723725

724726
let route_params = RouteParameters::from_payment_params_and_value(
725727
PaymentParameters::for_keysend(payee_pubkey, 40, false),
726728
amt_msat,
727729
);
728730
outbound_payments.payments.insert(
729-
payment_hash,
731+
payment_id,
730732
PaymentInfo {
731733
preimage: None,
732734
secret: None,
@@ -738,7 +740,7 @@ fn keysend<E: EntropySource>(
738740
match channel_manager.send_spontaneous_payment_with_retry(
739741
Some(payment_preimage),
740742
RecipientOnionFields::spontaneous_empty(),
741-
PaymentId(payment_hash.0),
743+
payment_id,
742744
route_params,
743745
Retry::Timeout(Duration::from_secs(10)),
744746
) {
@@ -749,16 +751,16 @@ fn keysend<E: EntropySource>(
749751
Err(e) => {
750752
println!("ERROR: failed to send payment: {:?}", e);
751753
print!("> ");
752-
outbound_payments.payments.get_mut(&payment_hash).unwrap().status = HTLCStatus::Failed;
754+
outbound_payments.payments.get_mut(&payment_id).unwrap().status = HTLCStatus::Failed;
753755
fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound_payments.encode()).unwrap();
754756
}
755757
};
756758
}
757759

758760
fn get_invoice(
759-
amt_msat: u64, inbound_payments: &mut PaymentInfoStorage, channel_manager: &ChannelManager,
760-
keys_manager: Arc<KeysManager>, network: Network, expiry_secs: u32,
761-
logger: Arc<disk::FilesystemLogger>,
761+
amt_msat: u64, inbound_payments: &mut InboundPaymentInfoStorage,
762+
channel_manager: &ChannelManager, keys_manager: Arc<KeysManager>, network: Network,
763+
expiry_secs: u32, logger: Arc<disk::FilesystemLogger>,
762764
) {
763765
let currency = match network {
764766
Network::Bitcoin => Currency::Bitcoin,

src/disk.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{cli, NetworkGraph, PaymentInfoStorage};
1+
use crate::{cli, InboundPaymentInfoStorage, NetworkGraph, OutboundPaymentInfoStorage};
22
use bitcoin::secp256k1::PublicKey;
33
use bitcoin::Network;
44
use chrono::Utc;
@@ -86,13 +86,22 @@ pub(crate) fn read_network(
8686
NetworkGraph::new(network, logger)
8787
}
8888

89-
pub(crate) fn read_payment_info(path: &Path) -> PaymentInfoStorage {
89+
pub(crate) fn read_inbound_payment_info(path: &Path) -> InboundPaymentInfoStorage {
9090
if let Ok(file) = File::open(path) {
91-
if let Ok(info) = PaymentInfoStorage::read(&mut BufReader::new(file)) {
91+
if let Ok(info) = InboundPaymentInfoStorage::read(&mut BufReader::new(file)) {
9292
return info;
9393
}
9494
}
95-
PaymentInfoStorage { payments: HashMap::new() }
95+
InboundPaymentInfoStorage { payments: HashMap::new() }
96+
}
97+
98+
pub(crate) fn read_outbound_payment_info(path: &Path) -> OutboundPaymentInfoStorage {
99+
if let Ok(file) = File::open(path) {
100+
if let Ok(info) = OutboundPaymentInfoStorage::read(&mut BufReader::new(file)) {
101+
return info;
102+
}
103+
}
104+
OutboundPaymentInfoStorage { payments: HashMap::new() }
96105
}
97106

98107
pub(crate) fn read_scorer(

src/main.rs

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use lightning::events::bump_transaction::{BumpTransactionEventHandler, Wallet};
2020
use lightning::events::{Event, PaymentFailureReason, PaymentPurpose};
2121
use lightning::ln::channelmanager::{self, RecentPaymentDetails};
2222
use lightning::ln::channelmanager::{
23-
ChainParameters, ChannelManagerReadArgs, SimpleArcChannelManager,
23+
ChainParameters, ChannelManagerReadArgs, PaymentId, SimpleArcChannelManager,
2424
};
2525
use lightning::ln::msgs::DecodeError;
2626
use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler, SimpleArcPeerManager};
@@ -109,11 +109,19 @@ impl_writeable_tlv_based!(PaymentInfo, {
109109
(6, amt_msat, required),
110110
});
111111

112-
pub(crate) struct PaymentInfoStorage {
112+
pub(crate) struct InboundPaymentInfoStorage {
113113
payments: HashMap<PaymentHash, PaymentInfo>,
114114
}
115115

116-
impl_writeable_tlv_based!(PaymentInfoStorage, {
116+
impl_writeable_tlv_based!(InboundPaymentInfoStorage, {
117+
(0, payments, required),
118+
});
119+
120+
pub(crate) struct OutboundPaymentInfoStorage {
121+
payments: HashMap<PaymentId, PaymentInfo>,
122+
}
123+
124+
impl_writeable_tlv_based!(OutboundPaymentInfoStorage, {
117125
(0, payments, required),
118126
});
119127

@@ -171,8 +179,9 @@ pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler<
171179
async fn handle_ldk_events(
172180
channel_manager: &Arc<ChannelManager>, bitcoind_client: &BitcoindClient,
173181
network_graph: &NetworkGraph, keys_manager: &KeysManager,
174-
bump_tx_event_handler: &BumpTxEventHandler, inbound_payments: Arc<Mutex<PaymentInfoStorage>>,
175-
outbound_payments: Arc<Mutex<PaymentInfoStorage>>, fs_store: &Arc<FilesystemStore>,
182+
bump_tx_event_handler: &BumpTxEventHandler,
183+
inbound_payments: Arc<Mutex<InboundPaymentInfoStorage>>,
184+
outbound_payments: Arc<Mutex<OutboundPaymentInfoStorage>>, fs_store: &Arc<FilesystemStore>,
176185
network: Network, event: Event,
177186
) {
178187
match event {
@@ -286,10 +295,12 @@ async fn handle_ldk_events(
286295
}
287296
fs_store.write("", "", INBOUND_PAYMENTS_FNAME, &inbound.encode()).unwrap();
288297
}
289-
Event::PaymentSent { payment_preimage, payment_hash, fee_paid_msat, .. } => {
298+
Event::PaymentSent {
299+
payment_preimage, payment_hash, fee_paid_msat, payment_id, ..
300+
} => {
290301
let mut outbound = outbound_payments.lock().unwrap();
291-
for (hash, payment) in outbound.payments.iter_mut() {
292-
if *hash == payment_hash {
302+
for (id, payment) in outbound.payments.iter_mut() {
303+
if *id == payment_id.unwrap() {
293304
payment.preimage = Some(payment_preimage);
294305
payment.status = HTLCStatus::Succeeded;
295306
println!(
@@ -343,7 +354,7 @@ async fn handle_ldk_events(
343354
Event::PaymentPathFailed { .. } => {}
344355
Event::ProbeSuccessful { .. } => {}
345356
Event::ProbeFailed { .. } => {}
346-
Event::PaymentFailed { payment_hash, reason, .. } => {
357+
Event::PaymentFailed { payment_hash, reason, payment_id, .. } => {
347358
print!(
348359
"\nEVENT: Failed to send payment to payment hash {}: {:?}",
349360
payment_hash,
@@ -353,8 +364,8 @@ async fn handle_ldk_events(
353364
io::stdout().flush().unwrap();
354365

355366
let mut outbound = outbound_payments.lock().unwrap();
356-
if outbound.payments.contains_key(&payment_hash) {
357-
let payment = outbound.payments.get_mut(&payment_hash).unwrap();
367+
if outbound.payments.contains_key(&payment_id) {
368+
let payment = outbound.payments.get_mut(&payment_id).unwrap();
358369
payment.status = HTLCStatus::Failed;
359370
}
360371
fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
@@ -364,7 +375,12 @@ async fn handle_ldk_events(
364375
print!("> ");
365376
io::stdout().flush().unwrap();
366377

367-
// TODO: mark the payment as failed
378+
let mut outbound = outbound_payments.lock().unwrap();
379+
if outbound.payments.contains_key(&payment_id) {
380+
let payment = outbound.payments.get_mut(&payment_id).unwrap();
381+
payment.status = HTLCStatus::Failed;
382+
}
383+
fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
368384
}
369385
Event::PaymentForwarded {
370386
prev_channel_id,
@@ -833,32 +849,30 @@ async fn start_ldk() {
833849
}
834850
});
835851

836-
let inbound_payments = Arc::new(Mutex::new(disk::read_payment_info(Path::new(&format!(
837-
"{}/{}",
838-
ldk_data_dir, INBOUND_PAYMENTS_FNAME
839-
)))));
840-
let outbound_payments = Arc::new(Mutex::new(disk::read_payment_info(Path::new(&format!(
841-
"{}/{}",
842-
ldk_data_dir, OUTBOUND_PAYMENTS_FNAME
843-
)))));
844-
let recent_payments_payment_hashes = channel_manager
852+
let inbound_payments = Arc::new(Mutex::new(disk::read_inbound_payment_info(Path::new(
853+
&format!("{}/{}", ldk_data_dir, INBOUND_PAYMENTS_FNAME),
854+
))));
855+
let outbound_payments = Arc::new(Mutex::new(disk::read_outbound_payment_info(Path::new(
856+
&format!("{}/{}", ldk_data_dir, OUTBOUND_PAYMENTS_FNAME),
857+
))));
858+
let recent_payments_payment_ids = channel_manager
845859
.list_recent_payments()
846860
.into_iter()
847861
.filter_map(|p| match p {
848-
RecentPaymentDetails::Pending { payment_hash, .. } => Some(payment_hash),
849-
RecentPaymentDetails::Fulfilled { payment_hash, .. } => payment_hash,
850-
RecentPaymentDetails::Abandoned { payment_hash, .. } => Some(payment_hash),
851-
RecentPaymentDetails::AwaitingInvoice { payment_id: _ } => todo!(),
862+
RecentPaymentDetails::Pending { payment_id, .. } => Some(payment_id),
863+
RecentPaymentDetails::Fulfilled { payment_id, .. } => Some(payment_id),
864+
RecentPaymentDetails::Abandoned { payment_id, .. } => Some(payment_id),
865+
RecentPaymentDetails::AwaitingInvoice { payment_id } => Some(payment_id),
852866
})
853-
.collect::<Vec<PaymentHash>>();
854-
for (payment_hash, payment_info) in outbound_payments
867+
.collect::<Vec<PaymentId>>();
868+
for (payment_id, payment_info) in outbound_payments
855869
.lock()
856870
.unwrap()
857871
.payments
858872
.iter_mut()
859873
.filter(|(_, i)| matches!(i.status, HTLCStatus::Pending))
860874
{
861-
if !recent_payments_payment_hashes.contains(payment_hash) {
875+
if !recent_payments_payment_ids.contains(payment_id) {
862876
payment_info.status = HTLCStatus::Failed;
863877
}
864878
}

0 commit comments

Comments
 (0)