use bitcoin::{secp256k1, Sequence};
use crate::blinded_path::{BlindedPath, NodeIdLookUp};
+use crate::blinded_path::message::ForwardNode;
use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentConstraints, PaymentContext, ReceiveTlvs};
use crate::chain;
use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction};
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
-use crate::sign::ecdsa::WriteableEcdsaChannelSigner;
+use crate::sign::ecdsa::EcdsaChannelSigner;
use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate};
use crate::util::wakers::{Future, Notifier};
use crate::util::scid_utils::fake_scid;
type NodeSigner: NodeSigner + ?Sized;
/// A type that may be dereferenced to [`Self::NodeSigner`].
type NS: Deref<Target = Self::NodeSigner>;
- /// A type implementing [`WriteableEcdsaChannelSigner`].
- type Signer: WriteableEcdsaChannelSigner + Sized;
+ /// A type implementing [`EcdsaChannelSigner`].
+ type Signer: EcdsaChannelSigner + Sized;
/// A type implementing [`SignerProvider`] for [`Self::Signer`].
type SignerProvider: SignerProvider<EcdsaSigner= Self::Signer> + ?Sized;
/// A type that may be dereferenced to [`Self::SignerProvider`].
pub(crate) fn test_send_payment_along_path(&self, path: &Path, payment_hash: &PaymentHash, recipient_onion: RecipientOnionFields, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
let _lck = self.total_consistency_lock.read().unwrap();
self.send_payment_along_path(SendAlongPathArgs {
- path, payment_hash, recipient_onion, total_value, cur_height, payment_id, keysend_preimage,
- session_priv_bytes
+ path, payment_hash, recipient_onion: &recipient_onion, total_value,
+ cur_height, payment_id, keysend_preimage, session_priv_bytes
})
}
///
/// Errors if the parameterized [`Router`] is unable to create a blinded path for the offer.
///
- /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
- ///
/// [`Offer`]: crate::offers::offer::Offer
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
pub fn create_offer_builder(&$self) -> Result<$builder, Bolt12SemanticError> {
/// - `amount_msats` is invalid, or
/// - the parameterized [`Router`] is unable to create a blinded path for the refund.
///
- /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
- ///
/// [`Refund`]: crate::offers::refund::Refund
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
let peers = self.per_peer_state.read().unwrap()
.iter()
- .filter(|(_, peer)| peer.lock().unwrap().latest_features.supports_onion_messages())
- .map(|(node_id, _)| *node_id)
+ .map(|(node_id, peer_state)| (node_id, peer_state.lock().unwrap()))
+ .filter(|(_, peer)| peer.latest_features.supports_onion_messages())
+ .map(|(node_id, peer)| ForwardNode {
+ node_id: *node_id,
+ short_channel_id: peer.channel_by_id
+ .iter()
+ .filter(|(_, channel)| channel.context().is_usable())
+ .min_by_key(|(_, channel)| channel.context().channel_creation_height)
+ .and_then(|(_, channel)| channel.context().get_short_channel_id()),
+ })
.collect::<Vec<_>>();
self.router
}
&mut chan.context
},
- // We retain UnfundedOutboundV1 channel for some time in case
- // peer unexpectedly disconnects, and intends to reconnect again.
- ChannelPhase::UnfundedOutboundV1(_) => {
- return true;
- },
+ // If we get disconnected and haven't yet committed to a funding
+ // transaction, we can replay the `open_channel` on reconnection, so don't
+ // bother dropping the channel here. However, if we already committed to
+ // the funding transaction we don't yet support replaying the funding
+ // handshake (and bailing if the peer rejects it), so we force-close in
+ // that case.
+ ChannelPhase::UnfundedOutboundV1(chan) if chan.is_resumable() => return true,
+ ChannelPhase::UnfundedOutboundV1(chan) => &mut chan.context,
// Unfunded inbound channels will always be removed.
ChannelPhase::UnfundedInboundV1(chan) => {
&mut chan.context
for (funding_txo, monitor) in args.channel_monitors.iter() {
if !funding_txo_set.contains(funding_txo) {
- let logger = WithChannelMonitor::from(&args.logger, monitor);
+ let logger = WithChannelMonitor::from(&args.logger, monitor, None);
let channel_id = monitor.channel_id();
log_info!(logger, "Queueing monitor update to ensure missing channel {} is force closed",
&channel_id);
for (_, monitor) in args.channel_monitors.iter() {
let counterparty_opt = outpoint_to_peer.get(&monitor.get_funding_txo().0);
if counterparty_opt.is_none() {
- let logger = WithChannelMonitor::from(&args.logger, monitor);
for (htlc_source, (htlc, _)) in monitor.get_pending_or_resolved_outbound_htlcs() {
+ let logger = WithChannelMonitor::from(&args.logger, monitor, Some(htlc.payment_hash));
if let HTLCSource::OutboundRoute { payment_id, session_priv, path, .. } = htlc_source {
if path.hops.is_empty() {
log_error!(logger, "Got an empty path for a pending payment");
}
}
for (htlc_source, (htlc, preimage_opt)) in monitor.get_all_current_outbound_htlcs() {
+ let logger = WithChannelMonitor::from(&args.logger, monitor, Some(htlc.payment_hash));
match htlc_source {
HTLCSource::PreviousHopData(prev_hop_data) => {
let pending_forward_matches_htlc = |info: &PendingAddHTLCInfo| {