use crate::{prelude::*, Description, Bolt11InvoiceDescription, Sha256};
use bech32::ToBase32;
-use bitcoin_hashes::Hash;
+use bitcoin::hashes::Hash;
use lightning::chain;
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use lightning::sign::{Recipient, NodeSigner, SignerProvider, EntropySource};
-use lightning::ln::{PaymentHash, PaymentSecret};
-use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, MIN_FINAL_CLTV_EXPIRY_DELTA};
+use lightning::ln::types::{PaymentHash, PaymentSecret};
+use lightning::ln::channel_state::ChannelDetails;
+use lightning::ln::channelmanager::{ChannelManager, MIN_FINAL_CLTV_EXPIRY_DELTA};
use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA};
use lightning::ln::inbound_payment::{create, create_from_hash, ExpandedKey};
use lightning::routing::gossip::RoutingFees;
use lightning::routing::router::{RouteHint, RouteHintHop, Router};
-use lightning::util::logger::Logger;
+use lightning::util::logger::{Logger, Record};
use secp256k1::PublicKey;
+use alloc::collections::{btree_map, BTreeMap};
use core::ops::Deref;
use core::time::Duration;
+#[cfg(not(feature = "std"))]
use core::iter::Iterator;
/// Utility to create an invoice that can be paid to one of multiple nodes, or a "phantom invoice."
min_final_cltv_expiry_delta: Option<u16>,
) -> Result<Bolt11Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<Bolt11Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<Bolt11Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<Bolt11Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<Bolt11Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<Bolt11Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
payment_secret: PaymentSecret, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<Bolt11Invoice, SignOrCreationError<()>>
where
- M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
T::Target: BroadcasterInterface,
ES::Target: EntropySource,
NS::Target: NodeSigner,
where
L::Target: Logger,
{
- let mut filtered_channels: HashMap<PublicKey, ChannelDetails> = HashMap::new();
+ let mut filtered_channels: BTreeMap<PublicKey, ChannelDetails> = BTreeMap::new();
let min_inbound_capacity = min_inbound_capacity_msat.unwrap_or(0);
let mut min_capacity_channel_exists = false;
let mut online_channel_exists = false;
log_trace!(logger, "Considering {} channels for invoice route hints", channels.len());
for channel in channels.into_iter().filter(|chan| chan.is_channel_ready) {
+ let logger = WithChannelDetails::from(logger, &channel);
if channel.get_inbound_payment_scid().is_none() || channel.counterparty.forwarding_info.is_none() {
log_trace!(logger, "Ignoring channel {} for invoice route hints", &channel.channel_id);
continue;
}
match filtered_channels.entry(channel.counterparty.node_id) {
- hash_map::Entry::Occupied(mut entry) => {
+ btree_map::Entry::Occupied(mut entry) => {
let current_max_capacity = entry.get().inbound_capacity_msat;
// If this channel is public and the previous channel is not, ensure we replace the
// previous channel to avoid announcing non-public channels.
channel.inbound_capacity_msat);
}
}
- hash_map::Entry::Vacant(entry) => {
+ btree_map::Entry::Vacant(entry) => {
entry.insert(channel);
}
}
.into_iter()
.map(|(_, channel)| channel)
.filter(|channel| {
+ let logger = WithChannelDetails::from(logger, &channel);
let has_enough_capacity = channel.inbound_capacity_msat >= min_inbound_capacity;
let include_channel = if has_pub_unconf_chan {
// If we have a public channel, but it doesn't have enough confirmations to (yet)
current_channel > candidate_channel
}
+/// Adds relevant context to a [`Record`] before passing it to the wrapped [`Logger`].
+struct WithChannelDetails<'a, 'b, L: Deref> where L::Target: Logger {
+ /// The logger to delegate to after adding context to the record.
+ logger: &'a L,
+ /// The [`ChannelDetails`] for adding relevant context to the logged record.
+ details: &'b ChannelDetails
+}
+
+impl<'a, 'b, L: Deref> Logger for WithChannelDetails<'a, 'b, L> where L::Target: Logger {
+ fn log(&self, mut record: Record) {
+ record.peer_id = Some(self.details.counterparty.node_id);
+ record.channel_id = Some(self.details.channel_id);
+ self.logger.log(record)
+ }
+}
+
+impl<'a, 'b, L: Deref> WithChannelDetails<'a, 'b, L> where L::Target: Logger {
+ fn from(logger: &'a L, details: &'b ChannelDetails) -> Self {
+ Self { logger, details }
+ }
+}
+
#[cfg(test)]
mod test {
- use core::cell::RefCell;
use core::time::Duration;
use crate::{Currency, Description, Bolt11InvoiceDescription, SignOrCreationError, CreationError};
- use bitcoin_hashes::{Hash, sha256};
- use bitcoin_hashes::sha256::Hash as Sha256;
+ use bitcoin::hashes::{Hash, sha256};
+ use bitcoin::hashes::sha256::Hash as Sha256;
use lightning::sign::PhantomKeysManager;
- use lightning::events::{MessageSendEvent, MessageSendEventsProvider, Event, EventsProvider};
- use lightning::ln::{PaymentPreimage, PaymentHash};
+ use lightning::events::{MessageSendEvent, MessageSendEventsProvider};
+ use lightning::ln::types::PaymentHash;
+ #[cfg(feature = "std")]
+ use lightning::ln::types::PaymentPreimage;
use lightning::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId, RecipientOnionFields, Retry};
use lightning::ln::functional_test_utils::*;
use lightning::ln::msgs::ChannelMessageHandler;
let route_params = RouteParameters::from_payment_params_and_value(
payment_params, invoice.amount_milli_satoshis().unwrap());
let payment_event = {
- let mut payment_hash = PaymentHash([0; 32]);
- payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]);
+ let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
nodes[0].node.send_payment(payment_hash,
RecipientOnionFields::secret_only(*invoice.payment_secret()),
PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();
#[cfg(feature = "std")]
fn do_test_multi_node_receive(user_generated_pmt_hash: bool) {
+ use lightning::events::{Event, EventsProvider};
+ use core::cell::RefCell;
+
let mut chanmon_cfgs = create_chanmon_cfgs(3);
let seed_1 = [42u8; 32];
let seed_2 = [43u8; 32];
let user_payment_preimage = PaymentPreimage([1; 32]);
let payment_hash = if user_generated_pmt_hash {
- Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).into_inner()))
+ Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).to_byte_array()))
} else {
None
};
route_hints, nodes[1].keys_manager, nodes[1].keys_manager, nodes[1].logger,
Currency::BitcoinTestnet, None, Duration::from_secs(genesis_timestamp)
).unwrap();
- let (payment_hash, payment_secret) = (PaymentHash(invoice.payment_hash().into_inner()), *invoice.payment_secret());
+ let (payment_hash, payment_secret) = (PaymentHash(invoice.payment_hash().to_byte_array()), *invoice.payment_secret());
let payment_preimage = if user_generated_pmt_hash {
user_payment_preimage
} else {
let params = RouteParameters::from_payment_params_and_value(
payment_params, invoice.amount_milli_satoshis().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]);
+ let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
nodes[0].node.send_payment(payment_hash,
RecipientOnionFields::secret_only(*invoice.payment_secret()),
PaymentId(payment_hash.0), params, Retry::Attempts(0)).unwrap();
let payment_preimage_opt = if user_generated_pmt_hash { None } else { Some(payment_preimage) };
assert_eq!(other_events.borrow().len(), 1);
check_payment_claimable(&other_events.borrow()[0], payment_hash, payment_secret, payment_amt, payment_preimage_opt, invoice.recover_payee_pub_key());
- do_claim_payment_along_route(&nodes[0], &[&vec!(&nodes[fwd_idx])[..]], false, payment_preimage);
+ do_claim_payment_along_route(
+ ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[fwd_idx]]], payment_preimage)
+ );
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
}
nodes[2].node.get_phantom_route_hints(),
];
let user_payment_preimage = PaymentPreimage([1; 32]);
- let payment_hash = Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).into_inner()));
+ let payment_hash = Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).to_byte_array()));
let non_default_invoice_expiry_secs = 4200;
let min_final_cltv_expiry_delta = Some(100);
let duration_since_epoch = Duration::from_secs(1234567);