Skip to content

Commit

Permalink
Swap the dep order between lightning and lightning-invoice
Browse files Browse the repository at this point in the history
`lightning-invoice` previously had a dependency on the entire
`lightning` crate just because it wants to use some of the useful
types from it. This is obviously backwards and leads to some
awkwardness like the BOLT 11 invoice signing API in the `lightning`
crate taking a `[u5]` rather than a `Bolt11Invoice`.

Here we finally rectify this issue, swapping the dependency order
and making `lightning` depend on `lightning-invoice` rather than
the other way around.

This moves various utilities which were in `lightning-invoice` but
relied on `lightning` payment types to make payments to where they
belong (the `lightning` crate), but doesn't bother with integrating
them well in their new home.
  • Loading branch information
TheBlueMatt committed Aug 9, 2024
1 parent 51113a1 commit 7e815be
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 118 deletions.
6 changes: 2 additions & 4 deletions lightning-invoice/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@ rustdoc-args = ["--cfg", "docsrs"]

[features]
default = ["std"]
no-std = ["lightning/no-std"]
std = ["bitcoin/std", "lightning/std", "bech32/std"]
no-std = ["bitcoin/no-std"]
std = ["bitcoin/std", "bech32/std"]

[dependencies]
bech32 = { version = "0.9.1", default-features = false }
lightning-types = { version = "0.1", path = "../lightning-types", default-features = false }
lightning = { version = "0.0.123-beta", path = "../lightning", default-features = false }
secp256k1 = { version = "0.28.0", default-features = false, features = ["recovery", "alloc"] }
serde = { version = "1.0.118", optional = true }
bitcoin = { version = "0.31.2", default-features = false }

[dev-dependencies]
lightning = { version = "0.0.123-beta", path = "../lightning", default-features = false, features = ["_test_utils"] }
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
serde_json = { version = "1"}
hashbrown = { version = "0.13", default-features = false }
Expand Down
41 changes: 23 additions & 18 deletions lightning-invoice/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@
#[cfg(not(any(feature = "std", feature = "no-std")))]
compile_error!("at least one of the `std` or `no-std` features must be enabled");

pub mod payment;
pub mod utils;

extern crate bech32;
#[macro_use] extern crate lightning;
extern crate lightning_types;
extern crate secp256k1;
extern crate alloc;
Expand All @@ -41,12 +37,11 @@ extern crate serde;
#[cfg(feature = "std")]
use std::time::SystemTime;

use bech32::u5;
use bech32::{FromBase32, u5};
use bitcoin::{Address, Network, PubkeyHash, ScriptHash, WitnessProgram, WitnessVersion};
use bitcoin::address::Payload;
use bitcoin::hashes::{Hash, sha256};
use lightning_types::features::Bolt11InvoiceFeatures;
use lightning::util::invoice::construct_invoice_preimage;

use secp256k1::PublicKey;
use secp256k1::{Message, Secp256k1};
Expand Down Expand Up @@ -138,19 +133,16 @@ pub const DEFAULT_EXPIRY_TIME: u64 = 3600;

/// Default minimum final CLTV expiry as defined by [BOLT 11].
///
/// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry, which is
/// provided in [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
/// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry.
///
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
/// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18;

/// Builder for [`Bolt11Invoice`]s. It's the most convenient and advised way to use this library. It
/// ensures that only a semantically and syntactically correct invoice can be built using it.
///
/// ```
/// extern crate secp256k1;
/// extern crate lightning;
/// extern crate lightning_invoice;
/// extern crate bitcoin;
///
Expand Down Expand Up @@ -969,7 +961,23 @@ macro_rules! find_all_extract {
impl RawBolt11Invoice {
/// Hash the HRP as bytes and signatureless data part.
fn hash_from_parts(hrp_bytes: &[u8], data_without_signature: &[u5]) -> [u8; 32] {
let preimage = construct_invoice_preimage(hrp_bytes, data_without_signature);
let mut preimage = Vec::<u8>::from(hrp_bytes);

let mut data_part = Vec::from(data_without_signature);
let overhang = (data_part.len() * 5) % 8;
if overhang > 0 {
// add padding if data does not end at a byte boundary
data_part.push(u5::try_from_u8(0).unwrap());

// if overhang is in (1..3) we need to add u5(0) padding two times
if overhang < 3 {
data_part.push(u5::try_from_u8(0).unwrap());
}
}

preimage.extend_from_slice(&Vec::<u8>::from_base32(&data_part)
.expect("No padding error may occur due to appended zero above."));

let mut hash: [u8; 32] = Default::default();
hash.copy_from_slice(&sha256::Hash::hash(&preimage)[..]);
hash
Expand Down Expand Up @@ -1635,15 +1643,12 @@ pub enum CreationError {
/// The supplied millisatoshi amount was greater than the total bitcoin supply.
InvalidAmount,

/// Route hints were required for this invoice and were missing. Applies to
/// [phantom invoices].
///
/// [phantom invoices]: crate::utils::create_phantom_invoice
// TODO: These two errors are really errors with things in the `lightning` crate and thus
// shouldn't live here.
/// Route hints were required for this invoice and were missing.
MissingRouteHints,

/// The provided `min_final_cltv_expiry_delta` was less than [`MIN_FINAL_CLTV_EXPIRY_DELTA`].
///
/// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA
/// The provided `min_final_cltv_expiry_delta` was less than rust-lightning's minimum.
MinFinalCltvExpiryDeltaTooShort,
}

Expand Down
1 change: 0 additions & 1 deletion lightning-invoice/tests/ser_de.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
extern crate bech32;
extern crate lightning;
extern crate lightning_invoice;
extern crate secp256k1;
extern crate hex;
Expand Down
5 changes: 3 additions & 2 deletions lightning/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ unsafe_revoked_tx_signing = []
# Override signing to not include randomness when generating signatures for test vectors.
_test_vectors = []

no-std = ["hashbrown", "possiblyrandom", "bitcoin/no-std", "core2/alloc", "libm"]
std = ["bitcoin/std", "bech32/std"]
no-std = ["hashbrown", "possiblyrandom", "bitcoin/no-std", "lightning-invoice/no-std", "core2/alloc", "libm"]
std = ["bitcoin/std", "bech32/std", "lightning-invoice/std"]

# Generates low-r bitcoin signatures, which saves 1 byte in 50% of the cases
grind_signatures = []
Expand All @@ -41,6 +41,7 @@ default = ["std", "grind_signatures"]

[dependencies]
lightning-types = { version = "0.1", path = "../lightning-types", default-features = false }
lightning-invoice = { version = "0.31.0-beta", path = "../lightning-invoice", default-features = false }

bech32 = { version = "0.9.1", default-features = false }
bitcoin = { version = "0.31.2", default-features = false, features = ["secp-recovery"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@

//! Convenient utilities for paying Lightning invoices.
use crate::Bolt11Invoice;
use lightning_invoice::Bolt11Invoice;
use bitcoin::hashes::Hash;

use lightning::ln::types::PaymentHash;
use lightning::ln::channelmanager::RecipientOnionFields;
use lightning::routing::router::{PaymentParameters, RouteParameters};
use crate::ln::types::PaymentHash;
use crate::ln::channelmanager::RecipientOnionFields;
use crate::routing::router::{PaymentParameters, RouteParameters};

/// Builds the necessary parameters to pay or pre-flight probe the given zero-amount
/// [`Bolt11Invoice`] using [`ChannelManager::send_payment`] or
Expand All @@ -26,8 +26,8 @@ use lightning::routing::router::{PaymentParameters, RouteParameters};
/// Will always succeed unless the invoice has an amount specified, in which case
/// [`payment_parameters_from_invoice`] should be used.
///
/// [`ChannelManager::send_payment`]: lightning::ln::channelmanager::ChannelManager::send_payment
/// [`ChannelManager::send_preflight_probes`]: lightning::ln::channelmanager::ChannelManager::send_preflight_probes
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
/// [`ChannelManager::send_preflight_probes`]: crate::ln::channelmanager::ChannelManager::send_preflight_probes
pub fn payment_parameters_from_zero_amount_invoice(invoice: &Bolt11Invoice, amount_msat: u64)
-> Result<(PaymentHash, RecipientOnionFields, RouteParameters), ()> {
if invoice.amount_milli_satoshis().is_some() {
Expand All @@ -46,8 +46,8 @@ pub fn payment_parameters_from_zero_amount_invoice(invoice: &Bolt11Invoice, amou
/// Will always succeed unless the invoice has no amount specified, in which case
/// [`payment_parameters_from_zero_amount_invoice`] should be used.
///
/// [`ChannelManager::send_payment`]: lightning::ln::channelmanager::ChannelManager::send_payment
/// [`ChannelManager::send_preflight_probes`]: lightning::ln::channelmanager::ChannelManager::send_preflight_probes
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
/// [`ChannelManager::send_preflight_probes`]: crate::ln::channelmanager::ChannelManager::send_preflight_probes
pub fn payment_parameters_from_invoice(invoice: &Bolt11Invoice)
-> Result<(PaymentHash, RecipientOnionFields, RouteParameters), ()> {
if let Some(amount_msat) = invoice.amount_milli_satoshis() {
Expand Down Expand Up @@ -83,11 +83,11 @@ fn params_from_invoice(invoice: &Bolt11Invoice, amount_msat: u64)
#[cfg(test)]
mod tests {
use super::*;
use crate::{InvoiceBuilder, Currency};
use lightning_invoice::{InvoiceBuilder, Currency};
use bitcoin::hashes::sha256::Hash as Sha256;
use lightning::ln::types::PaymentSecret;
use lightning::routing::router::Payee;
use secp256k1::{SecretKey, PublicKey, Secp256k1};
use crate::ln::types::PaymentSecret;
use crate::routing::router::Payee;
use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1};
use core::time::Duration;
#[cfg(feature = "std")]
use std::time::SystemTime;
Expand Down Expand Up @@ -169,10 +169,10 @@ mod tests {
#[test]
#[cfg(feature = "std")]
fn payment_metadata_end_to_end() {
use lightning::events::Event;
use lightning::ln::channelmanager::{Retry, PaymentId};
use lightning::ln::msgs::ChannelMessageHandler;
use lightning::ln::functional_test_utils::*;
use crate::events::Event;
use crate::ln::channelmanager::{Retry, PaymentId};
use crate::ln::msgs::ChannelMessageHandler;
use crate::ln::functional_test_utils::*;
// Test that a payment metadata read from an invoice passed to `pay_invoice` makes it all
// the way out through the `PaymentClaimable` event.
let chanmon_cfgs = create_chanmon_cfgs(2);
Expand Down
Loading

0 comments on commit 7e815be

Please sign in to comment.