Skip to content

Commit c032a10

Browse files
committed
Impl. logging, PaymentInfo storage and querying
1 parent 7658210 commit c032a10

File tree

3 files changed

+139
-28
lines changed

3 files changed

+139
-28
lines changed

src/event.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use crate::{
44
};
55

66
#[allow(unused_imports)]
7-
use crate::logger::{Logger, FilesystemLogger, log_info, log_error, log_warn, log_trace, log_given_level, log_internal};
7+
use crate::logger::{
8+
log_error, log_given_level, log_info, log_internal, log_trace, log_warn, FilesystemLogger,
9+
Logger,
10+
};
811

912
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
1013
use lightning::chain::keysinterface::KeysManager;

src/lib.rs

Lines changed: 135 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,19 @@ pub use event::LdkLiteEvent;
3636
use event::LdkLiteEventHandler;
3737

3838
#[allow(unused_imports)]
39-
use logger::{Logger, FilesystemLogger, log_info, log_error, log_warn, log_trace, log_given_level, log_internal};
39+
use logger::{
40+
log_error, log_given_level, log_info, log_internal, log_trace, log_warn, FilesystemLogger,
41+
Logger,
42+
};
4043

4144
use lightning::chain::keysinterface::{InMemorySigner, KeysInterface, KeysManager, Recipient};
4245
use lightning::chain::{chainmonitor, Access, BestBlock, Confirm, Filter, Watch};
4346
use lightning::ln::channelmanager;
4447
use lightning::ln::channelmanager::{
45-
ChainParameters, ChannelManagerReadArgs, PaymentId, SimpleArcChannelManager,
48+
ChainParameters, ChannelManagerReadArgs, SimpleArcChannelManager,
4649
};
4750
use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler, SimpleArcPeerManager};
48-
use lightning::ln::{PaymentHash, PaymentPreimage};
51+
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
4952
use lightning::routing::gossip;
5053
use lightning::routing::gossip::P2PGossipSync;
5154
use lightning::routing::scoring::ProbabilisticScorer;
@@ -66,6 +69,8 @@ use bdk::blockchain::esplora::EsploraBlockchain;
6669
use bdk::blockchain::{GetBlockHash, GetHeight};
6770
use bdk::database::MemoryDatabase;
6871

72+
use bitcoin::hashes::sha256::Hash as Sha256;
73+
use bitcoin::hashes::Hash;
6974
use bitcoin::secp256k1::PublicKey;
7075
use bitcoin::BlockHash;
7176

@@ -306,8 +311,8 @@ impl LdkLiteBuilder {
306311

307312
// Step 13: Init payment info storage
308313
// TODO: persist payment info to disk
309-
let _inbound_payments = Arc::new(Mutex::new(HashMap::new()));
310-
let _outbound_payments = Arc::new(Mutex::new(HashMap::new()));
314+
let inbound_payments = Arc::new(Mutex::new(HashMap::new()));
315+
let outbound_payments = Arc::new(Mutex::new(HashMap::new()));
311316

312317
// Step 14: Handle LDK Events
313318
let event_queue = mpsc::sync_channel(CHANNEL_BUF_SIZE);
@@ -317,8 +322,8 @@ impl LdkLiteBuilder {
317322
Arc::clone(&channel_manager),
318323
Arc::clone(&network_graph),
319324
Arc::clone(&keys_manager),
320-
Arc::clone(&_inbound_payments),
321-
Arc::clone(&_outbound_payments),
325+
Arc::clone(&inbound_payments),
326+
Arc::clone(&outbound_payments),
322327
event_sender,
323328
Arc::clone(&logger),
324329
Arc::clone(&config),
@@ -356,8 +361,8 @@ impl LdkLiteBuilder {
356361
network_graph,
357362
scorer,
358363
invoice_payer,
359-
_inbound_payments,
360-
_outbound_payments,
364+
inbound_payments,
365+
outbound_payments,
361366
event_queue,
362367
})
363368
}
@@ -389,8 +394,8 @@ pub struct LdkLite {
389394
scorer: Arc<Mutex<Scorer>>,
390395
network_graph: Arc<NetworkGraph>,
391396
invoice_payer: Arc<InvoicePayer<LdkLiteEventHandler>>,
392-
_inbound_payments: Arc<PaymentInfoStorage>,
393-
_outbound_payments: Arc<PaymentInfoStorage>,
397+
inbound_payments: Arc<PaymentInfoStorage>,
398+
outbound_payments: Arc<PaymentInfoStorage>,
394399
event_queue: (EventSender, EventReceiver),
395400
}
396401

@@ -575,12 +580,13 @@ impl LdkLite {
575580

576581
/// Retrieve a new on-chain/funding address.
577582
pub fn new_funding_address(&mut self) -> Result<bitcoin::Address, Error> {
578-
// TODO: log
579583
if self.running.read().unwrap().is_none() {
580584
return Err(Error::NotRunning);
581585
}
582586

583-
self.chain_access.get_new_address()
587+
let funding_address = self.chain_access.get_new_address()?;
588+
log_info!(self.logger, "generated new funding address: {}", funding_address);
589+
Ok(funding_address)
584590
}
585591

586592
// Connect to a node and open a new channel. Disconnects and re-connects should be handled automatically
@@ -590,40 +596,120 @@ impl LdkLite {
590596
// pub close_channel(&mut self, channel_id: u64) -> Result<()>;
591597
//
592598
/// Send a payement given an invoice.
593-
pub fn send_payment(&self, invoice: Invoice) -> Result<PaymentId, Error> {
599+
pub fn send_payment(&self, invoice: Invoice) -> Result<PaymentHash, Error> {
594600
if self.running.read().unwrap().is_none() {
595601
return Err(Error::NotRunning);
596602
}
603+
597604
// TODO: ensure we never tried paying the given payment hash before
598-
// TODO: log
599-
Ok(self.invoice_payer.pay_invoice(&invoice)?)
605+
let status = match self.invoice_payer.pay_invoice(&invoice) {
606+
Ok(_payment_id) => {
607+
let payee_pubkey = invoice.recover_payee_pub_key();
608+
// TODO: is this unwrap safe? Would a payment to an invoice with None amount ever
609+
// succeed?
610+
let amt_msat = invoice.amount_milli_satoshis().unwrap();
611+
log_info!(self.logger, "initiated sending {} msats to {}", amt_msat, payee_pubkey);
612+
PaymentStatus::Pending
613+
}
614+
Err(payment::PaymentError::Invoice(e)) => {
615+
log_error!(self.logger, "invalid invoice: {}", e);
616+
return Err(Error::Payment(payment::PaymentError::Invoice(e)));
617+
}
618+
Err(payment::PaymentError::Routing(e)) => {
619+
log_error!(self.logger, "failed to find route: {}", e.err);
620+
return Err(Error::Payment(payment::PaymentError::Routing(e)));
621+
}
622+
Err(payment::PaymentError::Sending(e)) => {
623+
log_error!(self.logger, "failed to send payment: {:?}", e);
624+
PaymentStatus::Failed
625+
}
626+
};
627+
628+
let payment_hash = PaymentHash(invoice.payment_hash().clone().into_inner());
629+
let payment_secret = Some(invoice.payment_secret().clone());
630+
631+
let mut outbound_payments_lock = self.outbound_payments.lock().unwrap();
632+
outbound_payments_lock.insert(
633+
payment_hash,
634+
PaymentInfo {
635+
preimage: None,
636+
secret: payment_secret,
637+
status,
638+
amount_msat: invoice.amount_milli_satoshis(),
639+
},
640+
);
641+
642+
Ok(payment_hash)
600643
}
601644

602645
/// Send a spontaneous, aka. "keysend", payment
603646
pub fn send_spontaneous_payment(
604647
&self, amount_msat: u64, node_id: PublicKey,
605-
) -> Result<PaymentId, Error> {
648+
) -> Result<PaymentHash, Error> {
606649
if self.running.read().unwrap().is_none() {
607650
return Err(Error::NotRunning);
608651
}
609-
// TODO: log
652+
610653
let payment_preimage = PaymentPreimage(self.keys_manager.get_secure_random_bytes());
611-
Ok(self.invoice_payer.pay_pubkey(
654+
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
655+
656+
let status = match self.invoice_payer.pay_pubkey(
612657
node_id,
613658
payment_preimage,
614659
amount_msat,
615660
self.config.default_cltv_expiry_delta,
616-
)?)
661+
) {
662+
Ok(_payment_id) => {
663+
log_info!(self.logger, "initiated sending {} msats to {}", amount_msat, node_id);
664+
PaymentStatus::Pending
665+
}
666+
Err(payment::PaymentError::Invoice(e)) => {
667+
log_error!(self.logger, "invalid invoice: {}", e);
668+
return Err(Error::Payment(payment::PaymentError::Invoice(e)));
669+
}
670+
Err(payment::PaymentError::Routing(e)) => {
671+
log_error!(self.logger, "failed to find route: {}", e.err);
672+
return Err(Error::Payment(payment::PaymentError::Routing(e)));
673+
}
674+
Err(payment::PaymentError::Sending(e)) => {
675+
log_error!(self.logger, "failed to send payment: {:?}", e);
676+
PaymentStatus::Failed
677+
}
678+
};
679+
680+
let mut outbound_payments_lock = self.outbound_payments.lock().unwrap();
681+
outbound_payments_lock.insert(
682+
payment_hash,
683+
PaymentInfo { preimage: None, secret: None, status, amount_msat: Some(amount_msat) },
684+
);
685+
686+
Ok(payment_hash)
617687
}
618688
//
619689
// // Create an invoice to receive a payment
620690
// pub receive_payment(&mut self, amount: Option<u64>) -> Invoice;
621691
//
622-
// // Get a new on-chain/funding address.
623-
// pub new_funding_address(&mut self) -> Address;
624-
//
625-
// // Query for information about payment status.
626-
// pub payment_info(&mut self) -> PaymentInfo;
692+
/// Query for information about the status of a specific payment.
693+
pub fn payment_info(&mut self, payment_hash: &[u8; 32]) -> Option<PaymentInfo> {
694+
let payment_hash = PaymentHash(*payment_hash);
695+
696+
{
697+
let outbound_payments_lock = self.outbound_payments.lock().unwrap();
698+
if let Some(payment_info) = outbound_payments_lock.get(&payment_hash) {
699+
return Some((*payment_info).clone());
700+
}
701+
}
702+
703+
{
704+
let inbound_payments_lock = self.inbound_payments.lock().unwrap();
705+
if let Some(payment_info) = inbound_payments_lock.get(&payment_hash) {
706+
return Some((*payment_info).clone());
707+
}
708+
}
709+
710+
None
711+
}
712+
627713
//
628714
// // Query for information about our channels
629715
// pub channel_info(&mut self) -> ChannelInfo;
@@ -680,7 +766,30 @@ async fn do_connect_peer(
680766
// Structs wrapping the particular information which should easily be
681767
// understandable, parseable, and transformable, i.e., we'll try to avoid
682768
// exposing too many technical detail here.
683-
struct PaymentInfo;
769+
/// Represents a payment.
770+
#[derive(Clone, Debug, PartialEq, Eq)]
771+
pub struct PaymentInfo {
772+
/// The pre-image used by the payment.
773+
pub preimage: Option<PaymentPreimage>,
774+
/// The secret used by the payment.
775+
pub secret: Option<PaymentSecret>,
776+
/// The status of the payment.
777+
pub status: PaymentStatus,
778+
/// The amount transferred.
779+
pub amount_msat: Option<u64>,
780+
}
781+
782+
/// Represents the current status of a payment.
783+
#[derive(Clone, Debug, PartialEq, Eq)]
784+
pub enum PaymentStatus {
785+
/// The payment is still pending.
786+
Pending,
787+
/// The payment suceeded.
788+
Succeeded,
789+
/// The payment failed.
790+
Failed,
791+
}
792+
684793
//struct ChannelInfo;
685794
//struct FundingInfo;
686795

src/logger.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ impl Logger for FilesystemLogger {
3939
}
4040
}
4141

42-
4342
// TODO: We copied the logging macros for now from `lightning::util::macro_logger`. We should
4443
// switch back to using them from upstream after the next release, which includes their export.
4544
macro_rules! log_internal {

0 commit comments

Comments
 (0)