//! Convenient utilities to create an invoice.
-use {CreationError, Currency, Invoice, InvoiceBuilder, SignOrCreationError};
-use payment::{InFlightHtlcs, Payer, Router};
+use crate::{CreationError, Currency, Invoice, InvoiceBuilder, SignOrCreationError};
+use crate::payment::{Payer, ScoringRouter};
use crate::{prelude::*, Description, InvoiceDescription, Sha256};
use bech32::ToBase32;
use bitcoin_hashes::{Hash, sha256};
use lightning::chain;
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
-use lightning::chain::keysinterface::{Recipient, KeysInterface, Sign};
+use lightning::chain::keysinterface::{Recipient, KeysInterface};
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, PaymentSendFailure, MIN_FINAL_CLTV_EXPIRY};
#[cfg(feature = "std")]
use lightning::ln::inbound_payment::{create, create_from_hash, ExpandedKey};
use lightning::ln::msgs::LightningError;
use lightning::routing::gossip::{NetworkGraph, NodeId, RoutingFees};
-use lightning::routing::router::{Route, RouteHint, RouteHintHop, RouteParameters, find_route, RouteHop};
+use lightning::routing::router::{InFlightHtlcs, Route, RouteHint, RouteHintHop, RouteParameters, find_route, RouteHop, Router};
use lightning::routing::scoring::{ChannelUsage, LockableScore, Score};
use lightning::util::logger::Logger;
use secp256k1::PublicKey;
use core::ops::Deref;
use core::time::Duration;
-use sync::Mutex;
+use crate::sync::Mutex;
#[cfg(feature = "std")]
/// Utility to create an invoice that can be paid to one of multiple nodes, or a "phantom invoice."
/// [`ChannelManager::create_inbound_payment`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment
/// [`ChannelManager::create_inbound_payment_for_hash`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
/// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
-pub fn create_phantom_invoice<Signer: Sign, K: Deref, L: Deref>(
+pub fn create_phantom_invoice<K: Deref, L: Deref>(
amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, description: String,
invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
logger: L, network: Currency,
{
let description = Description::new(description).map_err(SignOrCreationError::CreationError)?;
let description = InvoiceDescription::Direct(&description,);
- _create_phantom_invoice::<Signer, K, L>(
+ _create_phantom_invoice::<K, L>(
amt_msat, payment_hash, description, invoice_expiry_delta_secs, phantom_route_hints,
keys_manager, logger, network,
)
/// [`ChannelManager::create_inbound_payment`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment
/// [`ChannelManager::create_inbound_payment_for_hash`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
/// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
-pub fn create_phantom_invoice_with_description_hash<Signer: Sign, K: Deref, L: Deref>(
+pub fn create_phantom_invoice_with_description_hash<K: Deref, L: Deref>(
amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, invoice_expiry_delta_secs: u32,
description_hash: Sha256, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
logger: L, network: Currency
K::Target: KeysInterface,
L::Target: Logger,
{
- _create_phantom_invoice::<Signer, K, L>(
+ _create_phantom_invoice::<K, L>(
amt_msat, payment_hash, InvoiceDescription::Hash(&description_hash),
invoice_expiry_delta_secs, phantom_route_hints, keys_manager, logger, network,
)
}
#[cfg(feature = "std")]
-fn _create_phantom_invoice<Signer: Sign, K: Deref, L: Deref>(
+fn _create_phantom_invoice<K: Deref, L: Deref>(
amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, description: InvoiceDescription,
invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
logger: L, network: Currency,
///
/// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
/// in excess of the current time.
-pub fn create_invoice_from_channelmanager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
- channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+ channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
network: Currency, amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<Signer>,
+ M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
T::Target: BroadcasterInterface,
- K::Target: KeysInterface<Signer = Signer>,
+ K::Target: KeysInterface,
F::Target: FeeEstimator,
L::Target: Logger,
{
///
/// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
/// in excess of the current time.
-pub fn create_invoice_from_channelmanager_with_description_hash<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
- channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_with_description_hash<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+ channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<Signer>,
+ M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
T::Target: BroadcasterInterface,
- K::Target: KeysInterface<Signer = Signer>,
+ K::Target: KeysInterface,
F::Target: FeeEstimator,
L::Target: Logger,
{
/// See [`create_invoice_from_channelmanager_with_description_hash`]
/// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
/// available and the current time is supplied by the caller.
-pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
- channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+ channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<Signer>,
+ M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
T::Target: BroadcasterInterface,
- K::Target: KeysInterface<Signer = Signer>,
+ K::Target: KeysInterface,
F::Target: FeeEstimator,
L::Target: Logger,
{
/// See [`create_invoice_from_channelmanager`]
/// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
/// available and the current time is supplied by the caller.
-pub fn create_invoice_from_channelmanager_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
- channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+ channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
network: Currency, amt_msat: Option<u64>, description: String, duration_since_epoch: Duration,
invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<Signer>,
+ M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
T::Target: BroadcasterInterface,
- K::Target: KeysInterface<Signer = Signer>,
+ K::Target: KeysInterface,
F::Target: FeeEstimator,
L::Target: Logger,
{
)
}
-fn _create_invoice_from_channelmanager_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
- channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+fn _create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+ channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
network: Currency, amt_msat: Option<u64>, description: InvoiceDescription,
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
) -> Result<Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<Signer>,
+ M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
T::Target: BroadcasterInterface,
- K::Target: KeysInterface<Signer = Signer>,
+ K::Target: KeysInterface,
F::Target: FeeEstimator,
L::Target: Logger,
{
S::Target: for <'a> LockableScore<'a>,
{
fn find_route(
- &self, payer: &PublicKey, params: &RouteParameters, _payment_hash: &PaymentHash,
- first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs
+ &self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&ChannelDetails]>,
+ inflight_htlcs: InFlightHtlcs
) -> Result<Route, LightningError> {
let random_seed_bytes = {
let mut locked_random_seed_bytes = self.random_seed_bytes.lock().unwrap();
&random_seed_bytes
)
}
+}
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref> ScoringRouter for DefaultRouter<G, L, S> where
+ L::Target: Logger,
+ S::Target: for <'a> LockableScore<'a>,
+{
fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
self.scorer.lock().payment_path_failed(path, short_channel_id);
}
}
}
-impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Payer for ChannelManager<Signer, M, T, K, F, L>
+impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Payer for ChannelManager<M, T, K, F, L>
where
- M::Target: chain::Watch<Signer>,
+ M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
T::Target: BroadcasterInterface,
- K::Target: KeysInterface<Signer = Signer>,
+ K::Target: KeysInterface,
F::Target: FeeEstimator,
L::Target: Logger,
{
}
fn send_payment(
- &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>
- ) -> Result<PaymentId, PaymentSendFailure> {
- self.send_payment(route, payment_hash, payment_secret)
+ &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
+ payment_id: PaymentId
+ ) -> Result<(), PaymentSendFailure> {
+ self.send_payment(route, payment_hash, payment_secret, payment_id)
}
fn send_spontaneous_payment(
- &self, route: &Route, payment_preimage: PaymentPreimage,
- ) -> Result<PaymentId, PaymentSendFailure> {
- self.send_spontaneous_payment(route, Some(payment_preimage))
- .map(|(_, payment_id)| payment_id)
+ &self, route: &Route, payment_preimage: PaymentPreimage, payment_id: PaymentId,
+ ) -> Result<(), PaymentSendFailure> {
+ self.send_spontaneous_payment(route, Some(payment_preimage), payment_id).map(|_| ())
}
fn retry_payment(
#[cfg(test)]
mod test {
use core::time::Duration;
- use {Currency, Description, InvoiceDescription};
+ use crate::{Currency, Description, InvoiceDescription};
use bitcoin_hashes::Hash;
use bitcoin_hashes::sha256::Hash as Sha256;
use lightning::chain::keysinterface::PhantomKeysManager;
use lightning::ln::{PaymentPreimage, PaymentHash};
- use lightning::ln::channelmanager::{self, PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY};
+ use lightning::ln::channelmanager::{self, PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY, PaymentId};
use lightning::ln::functional_test_utils::*;
use lightning::ln::msgs::ChannelMessageHandler;
use lightning::routing::router::{PaymentParameters, RouteParameters, find_route};
- use lightning::util::enforcing_trait_impls::EnforcingSigner;
use lightning::util::events::{MessageSendEvent, MessageSendEventsProvider, Event};
use lightning::util::test_utils;
use lightning::util::config::UserConfig;
use lightning::chain::keysinterface::KeysInterface;
- use utils::create_invoice_from_channelmanager_and_duration_since_epoch;
+ use crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch;
use std::collections::HashSet;
#[test]
let payment_event = {
let mut payment_hash = PaymentHash([0; 32]);
payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]);
- nodes[0].node.send_payment(&route, payment_hash, &Some(invoice.payment_secret().clone())).unwrap();
+ nodes[0].node.send_payment(&route, payment_hash, &Some(invoice.payment_secret().clone()), PaymentId(payment_hash.0)).unwrap();
let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap();
assert_eq!(added_monitors.len(), 1);
added_monitors.clear();
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let description_hash = crate::Sha256(Hash::hash("Testing description_hash".as_bytes()));
- let invoice = ::utils::create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
+ let invoice = crate::utils::create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
&nodes[1].node, nodes[1].keys_manager, nodes[1].logger, Currency::BitcoinTestnet,
Some(10_000), description_hash, Duration::from_secs(1234567), 3600
).unwrap();
get_event_msg!(nodes[2], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
nodes[0].node.handle_channel_ready(&nodes[2].node.get_our_node_id(), &as_channel_ready);
get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[2].node.get_our_node_id());
+ expect_channel_ready_event(&nodes[0], &nodes[2].node.get_our_node_id());
+ expect_channel_ready_event(&nodes[2], &nodes[0].node.get_our_node_id());
// As `msgs::ChannelUpdate` was never handled for the participating node(s) of the second
// channel, the channel will never be assigned any `counterparty.forwarding_info`.
let non_default_invoice_expiry_secs = 4200;
let invoice =
- ::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger>(
+ crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(
Some(payment_amt), payment_hash, "test".to_string(), non_default_invoice_expiry_secs,
route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet
).unwrap();
let (payment_event, fwd_idx) = {
let mut payment_hash = PaymentHash([0; 32]);
payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]);
- nodes[0].node.send_payment(&route, payment_hash, &Some(invoice.payment_secret().clone())).unwrap();
+ nodes[0].node.send_payment(&route, payment_hash, &Some(invoice.payment_secret().clone()), PaymentId(payment_hash.0)).unwrap();
let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap();
assert_eq!(added_monitors.len(), 1);
added_monitors.clear();
nodes[2].node.get_phantom_route_hints(),
];
- let invoice = ::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger>(Some(payment_amt), Some(payment_hash), "test".to_string(), 3600, route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet).unwrap();
+ let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(Some(payment_amt), Some(payment_hash), "test".to_string(), 3600, route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet).unwrap();
let chan_0_1 = &nodes[1].node.list_usable_channels()[0];
assert_eq!(invoice.route_hints()[0].0[0].htlc_minimum_msat, chan_0_1.inbound_htlc_minimum_msat);
let description_hash = crate::Sha256(Hash::hash("Description hash phantom invoice".as_bytes()));
let non_default_invoice_expiry_secs = 4200;
- let invoice = ::utils::create_phantom_invoice_with_description_hash::<
- EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger,
+ let invoice = crate::utils::create_phantom_invoice_with_description_hash::<
+ &test_utils::TestKeysInterface, &test_utils::TestLogger,
>(
Some(payment_amt), None, non_default_invoice_expiry_secs, description_hash,
route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet
get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[3].node.get_our_node_id());
nodes[3].node.handle_channel_ready(&nodes[1].node.get_our_node_id(), &as_channel_ready);
get_event_msg!(nodes[3], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
+ expect_channel_ready_event(&nodes[1], &nodes[3].node.get_our_node_id());
+ expect_channel_ready_event(&nodes[3], &nodes[1].node.get_our_node_id());
// As `msgs::ChannelUpdate` was never handled for the participating node(s) of the third
// channel, the channel will never be assigned any `counterparty.forwarding_info`.
.map(|route_hint| route_hint.phantom_scid)
.collect::<HashSet<u64>>();
- let invoice = ::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger>(invoice_amt, None, "test".to_string(), 3600, phantom_route_hints, &invoice_node.keys_manager, &invoice_node.logger, Currency::BitcoinTestnet).unwrap();
+ let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(invoice_amt, None, "test".to_string(), 3600, phantom_route_hints, &invoice_node.keys_manager, &invoice_node.logger, Currency::BitcoinTestnet).unwrap();
let invoice_hints = invoice.private_routes();