Skip to content

Commit

Permalink
Merge pull request fedimint#3839 from elsirion/2023-12-no-std-lightni…
Browse files Browse the repository at this point in the history
…ng-invoice

fix: don't depend on std features from lightning-invoice
  • Loading branch information
elsirion authored Dec 5, 2023
2 parents 60daa84 + 0eb470e commit af69ced
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 17 deletions.
7 changes: 3 additions & 4 deletions gateway/ln-gateway/src/state_machine/pay.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::fmt::Display;
use std::sync::Arc;
use std::time::Duration;

use bitcoin_hashes::sha256;
use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition};
Expand Down Expand Up @@ -136,8 +135,8 @@ pub enum OutgoingContractError {
TimeoutTooClose,
#[error("Gateway could not retrieve metadata about the contract.")]
MissingContractData,
#[error("The invoice is expired. Expiry duration: {0:?}")]
InvoiceExpired(Duration),
#[error("The invoice is expired. Expiry happened at timestamp: {0}")]
InvoiceExpired(u64),
}

#[derive(Error, Debug, Serialize, Deserialize, Encodable, Decodable, Clone, Eq, PartialEq)]
Expand Down Expand Up @@ -569,7 +568,7 @@ impl GatewayPayInvoice {

if payment_data.is_expired() {
return Err(OutgoingContractError::InvoiceExpired(
payment_data.expiry_duration(),
payment_data.expiry_timestamp(),
));
}

Expand Down
29 changes: 20 additions & 9 deletions modules/fedimint-ln-client/src/pay.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::sync::Arc;
use std::time::Duration;
use std::time::{Duration, UNIX_EPOCH};

use bitcoin_hashes::sha256;
use fedimint_client::sm::{ClientSMDatabaseTransaction, State, StateTransition};
Expand Down Expand Up @@ -646,18 +646,29 @@ impl PaymentData {
match self {
PaymentData::Invoice(invoice) => invoice.is_expired(),
PaymentData::PrunedInvoice(PrunedInvoice {
timestamp, expiry, ..
}) => timestamp
.checked_add(*expiry)
.map(|expiry_time| expiry_time < now())
.unwrap_or(false),
expiry_timestamp, ..
}) => {
let Some(now) = now().duration_since(UNIX_EPOCH).map(|t| t.as_secs()).ok() else {
// Something is very wrong (time out of bounds), we'll not attempt too pay the
// invoice
return true;
};

*expiry_timestamp < now
}
}
}

pub fn expiry_duration(&self) -> Duration {
/// Returns the expiry timestamp in seconds since the UNIX epoch
pub fn expiry_timestamp(&self) -> u64 {
match self {
PaymentData::Invoice(invoice) => invoice.expiry_time(),
PaymentData::PrunedInvoice(PrunedInvoice { expiry, .. }) => *expiry,
PaymentData::Invoice(invoice) => invoice
.expires_at()
.map(|t| t.as_secs())
.unwrap_or(u64::MAX),
PaymentData::PrunedInvoice(PrunedInvoice {
expiry_timestamp, ..
}) => *expiry_timestamp,
}
}
}
14 changes: 10 additions & 4 deletions modules/fedimint-ln-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,14 +651,21 @@ pub struct PrunedInvoice {
pub payment_secret: [u8; 32],
pub route_hints: Vec<RouteHint>,
pub min_final_cltv_delta: u64,
pub timestamp: SystemTime,
pub expiry: Duration,
/// Time at which the invoice expires in seconds since unix epoch
pub expiry_timestamp: u64,
}

impl TryFrom<Bolt11Invoice> for PrunedInvoice {
type Error = anyhow::Error;

fn try_from(invoice: Bolt11Invoice) -> Result<Self, Self::Error> {
// We use expires_at since it doesn't rely on the std feature in
// lightning-invoice. See #3838.
let expiry_timestamp = invoice
.expires_at()
.map(|t| t.as_secs())
.unwrap_or(u64::MAX);

Ok(PrunedInvoice {
amount: Amount::from_msats(
invoice
Expand All @@ -673,8 +680,7 @@ impl TryFrom<Bolt11Invoice> for PrunedInvoice {
payment_secret: invoice.payment_secret().0,
route_hints: invoice.route_hints().into_iter().map(Into::into).collect(),
min_final_cltv_delta: invoice.min_final_cltv_expiry_delta(),
timestamp: invoice.timestamp(),
expiry: invoice.expiry_time(),
expiry_timestamp,
})
}
}

0 comments on commit af69ced

Please sign in to comment.