Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,7 +91,10 @@ use crate::ser::Base32Iterable;
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Bolt11ParseError {
Bech32Error(CheckedHrpstringError),
Bech32Error(
/// This is not exported to bindings users as the details don't matter much
Comment thread
joostjager marked this conversation as resolved.
CheckedHrpstringError,
),
ParseAmountError(ParseIntError),
MalformedSignature(bitcoin::secp256k1::Error),
BadPrefix,
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/chain/chainmonitor.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,8 @@ impl<ChannelSigner: EcdsaChannelSigner> Deref for LockedChannelMonitor<'_, Chann

/// An unconstructable [`Persist`]er which is used under the hood when you call
/// [`ChainMonitor::new_async_beta`].
///
/// This is not exported to bindings users as async is not supported outside of Rust.
Comment thread
joostjager marked this conversation as resolved.
pub struct AsyncPersister<
K: Deref + MaybeSend + MaybeSync + 'static,
S: FutureSpawner,
Expand DownExpand Up@@ -431,6 +433,8 @@ impl<
/// [`MonitorUpdatingPersisterAsync`] and thus allows persistence to be completed async.
///
/// Note that async monitor updating is considered beta, and bugs may be triggered by its use.
///
/// This is not exported to bindings users as async is not supported outside of Rust.
pub fn new_async_beta(
chain_source: Option<C>, broadcaster: T, logger: L, feeest: F,
persister: MonitorUpdatingPersisterAsync<K, S, L, ES, SP, T, F>, _entropy_source: ES,
Expand Down
18 changes: 15 additions & 3 deletions lightning/src/events/bump_transaction/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -353,6 +353,9 @@ pub struct CoinSelection {
/// which can provide a default implementation of this trait when used with [`Wallet`].
///
/// For a synchronous version of this trait, see [`sync::CoinSelectionSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait CoinSelectionSource {
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
Expand DownExpand Up@@ -404,6 +407,9 @@ pub trait CoinSelectionSource {
/// provide a default implementation to [`CoinSelectionSource`].
///
/// For a synchronous version of this trait, see [`sync::WalletSourceSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this trait should be copied to the synchronous version.
pub trait WalletSource {
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos<'a>(&'a self) -> AsyncResult<'a, Vec<Utxo>, ()>;
Expand All@@ -419,11 +425,14 @@ pub trait WalletSource {
fn sign_psbt<'a>(&'a self, psbt: Psbt) -> AsyncResult<'a, Transaction, ()>;
}

/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would
/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double
/// spends may happen.
/// A wrapper over [`WalletSource`] that implements [`CoinSelectionSource`] by preferring UTXOs
/// that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For a synchronous version of this wrapper, see [`sync::WalletSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct Wallet<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSource + MaybeSend,
Expand DownExpand Up@@ -670,7 +679,10 @@ where
///
/// For a synchronous version of this handler, see [`sync::BumpTransactionEventHandlerSync`].
///
/// This is not exported to bindings users as async is only supported in Rust.
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandler<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
87 changes: 78 additions & 9 deletions lightning/src/events/bump_transaction/sync.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,13 +28,26 @@ use super::{
WalletSource,
};

/// A synchronous version of the [`WalletSource`] trait.
/// An alternative to [`CoinSelectionSourceSync`] that can be implemented and used along
/// [`WalletSync`] to provide a default implementation to [`CoinSelectionSourceSync`].

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to link in the reverse direction to not duplicate?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but previously we wanted to avoid that because it it felt like it implied that sync was the "main" way of doing things in Rust, and that async was just a special mode, which isn't what we wanted. I don't feel super strongly, but it did seem simple enough to just copy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the intention indeed. Hopefully the duplication comment is sufficient.

///
/// For an asynchronous version of this trait, see [`WalletSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait WalletSourceSync {
/// A synchronous version of [`WalletSource::list_confirmed_utxos`].
/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend.
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()>;
/// A synchronous version of [`WalletSource::get_change_script`].
/// Returns a script to use for change above dust resulting from a successful coin selection
/// attempt.
fn get_change_script(&self) -> Result<ScriptBuf, ()>;
/// A Synchronous version of [`WalletSource::sign_psbt`].
/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within
/// the transaction known to the wallet (i.e., any provided via
/// [`WalletSource::list_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
///
/// [`TxIn::script_sig`]: bitcoin::TxIn::script_sig
/// [`TxIn::witness`]: bitcoin::TxIn::witness
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -74,7 +87,12 @@ where
}
}

/// A synchronous wrapper around [`Wallet`] to be used in contexts where async is not available.
/// A wrapper over [`WalletSourceSync`] that implements [`CoinSelectionSourceSync`] by preferring
/// UTXOs that would avoid conflicting double spends. If not enough UTXOs are available to do so,
/// conflicting double spends may happen.
///
/// For an asynchronous version of this wrapper, see [`Wallet`].
// Note that updates to documentation on this struct should be copied to the asynchronous version.
pub struct WalletSync<W: Deref + MaybeSync + MaybeSend, L: Deref + MaybeSync + MaybeSend>
where
W::Target: WalletSourceSync + MaybeSend,
Expand DownExpand Up@@ -136,15 +154,59 @@ where
}
}

/// A synchronous version of the [`CoinSelectionSource`] trait.
/// An abstraction over a bitcoin wallet that can perform coin selection over a set of UTXOs and can
/// sign for them. The coin selection method aims to mimic Bitcoin Core's `fundrawtransaction` RPC,
/// which most wallets should be able to satisfy. Otherwise, consider implementing
/// [`WalletSourceSync`], which can provide a default implementation of this trait when used with
/// [`WalletSync`].
///
/// For an asynchronous version of this trait, see [`CoinSelectionSource`].
// Note that updates to documentation on this trait should be copied to the asynchronous version.
pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
/// Performs coin selection of a set of UTXOs, with at least 1 confirmation each, that are
/// available to spend. Implementations are free to pick their coin selection algorithm of
/// choice, as long as the following requirements are met:
///
/// 1. `must_spend` contains a set of [`Input`]s that must be included in the transaction
/// throughout coin selection, but must not be returned as part of the result.
/// 2. `must_pay_to` contains a set of [`TxOut`]s that must be included in the transaction
/// throughout coin selection. In some cases, like when funding an anchor transaction, this
/// set is empty. Implementations should ensure they handle this correctly on their end,
/// e.g., Bitcoin Core's `fundrawtransaction` RPC requires at least one output to be
/// provided, in which case a zero-value empty OP_RETURN output can be used instead.
/// 3. Enough inputs must be selected/contributed for the resulting transaction (including the
/// inputs and outputs noted above) to meet `target_feerate_sat_per_1000_weight`.
/// 4. The final transaction must have a weight smaller than `max_tx_weight`; if this
/// constraint can't be met, return an `Err`. In the case of counterparty-signed HTLC
/// transactions, we will remove a chunk of HTLCs and try your algorithm again. As for
/// anchor transactions, we will try your coin selection again with the same input-output
/// set when you call [`ChannelMonitor::rebroadcast_pending_claims`], as anchor transactions
/// cannot be downsized.
///
/// Implementations must take note that [`Input::satisfaction_weight`] only tracks the weight of
/// the input's `script_sig` and `witness`. Some wallets, like Bitcoin Core's, may require
/// providing the full input weight. Failing to do so may lead to underestimating fee bumps and
/// delaying block inclusion.
///
/// The `claim_id` must map to the set of external UTXOs assigned to the claim, such that they
/// can be re-used within new fee-bumped iterations of the original claiming transaction,
/// ensuring that claims don't double spend each other. If a specific `claim_id` has never had a
/// transaction associated with it, and all of the available UTXOs have already been assigned to
/// other claims, implementations must be willing to double spend their UTXOs. The choice of
/// which UTXOs to double spend is left to the implementation, but it must strive to keep the
/// set of other claims being double spent to a minimum.
///
/// [`ChannelMonitor::rebroadcast_pending_claims`]: crate::chain::channelmonitor::ChannelMonitor::rebroadcast_pending_claims
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
/// Signs and provides the full witness for all inputs within the transaction known to the
/// trait (i.e., any provided via [`CoinSelectionSourceSync::select_confirmed_utxos`]).
///
/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the
/// unsigned transaction and then sign it with your wallet.
fn sign_psbt(&self, psbt: Psbt) -> Result<Transaction, ()>;
}

Expand DownExpand Up@@ -188,7 +250,14 @@ where
}
}

/// A synchronous wrapper around [`BumpTransactionEventHandler`] to be used in contexts where async is not available.
/// A handler for [`Event::BumpTransaction`] events that sources confirmed UTXOs from a
/// [`CoinSelectionSourceSync`] to fee bump transactions via Child-Pays-For-Parent (CPFP) or
/// Replace-By-Fee (RBF).
///
/// For an asynchronous version of this handler, see [`BumpTransactionEventHandler`].
///
/// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
// Note that updates to documentation on this struct should be copied to the synchronous version.
pub struct BumpTransactionEventHandlerSync<B: Deref, C: Deref, SP: Deref, L: Deref>
where
B::Target: BroadcasterInterface,
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,13 @@

//! Types pertaining to funding channels.

use alloc::vec::Vec;

use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

/// The components of a splice's funding transaction that are contributed by one party.
Expand Down
16 changes: 16 additions & 0 deletions lightning/src/offers/flow.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -597,6 +597,8 @@ where
///
/// Returns an error 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.
Comment thread
joostjager marked this conversation as resolved.
///
/// [`DefaultMessageRouter`]: crate::onion_message::messenger::DefaultMessageRouter
pub fn create_offer_builder<ES: Deref>(
&self, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -618,6 +620,8 @@ where
/// This gives users full control over how the [`BlindedMessagePath`] is constructed,
/// including the option to omit it entirely.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
///
/// See [`Self::create_offer_builder`] for more details on usage.
pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
&self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
Expand All@@ -644,6 +648,8 @@ where
/// 2. Use [`Self::create_static_invoice_builder`] to create a [`StaticInvoice`] from this
/// [`Offer`] plus the returned [`Nonce`], and provide the static invoice to the
/// aforementioned always-online node.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_async_receive_offer_builder<ES: Deref>(
&self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
Expand DownExpand Up@@ -726,6 +732,8 @@ where
/// - `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.
///
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
/// [`RouteParameters::from_payment_params_and_value`]: crate::routing::router::RouteParameters::from_payment_params_and_value
pub fn create_refund_builder<ES: Deref>(
Expand DownExpand Up@@ -762,6 +770,8 @@ where
/// return an error if the provided [`MessageRouter`] fails to construct a valid
/// [`BlindedMessagePath`] 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
/// [`BlindedMessagePath`]: crate::blinded_path::message::BlindedMessagePath
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
Expand DownExpand Up@@ -797,6 +807,8 @@ where
/// # Nonce
/// The nonce is used to create a unique [`InvoiceRequest::payer_metadata`] for the invoice request.
/// These will be used to verify the corresponding [`Bolt12Invoice`] when it is received.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_request_builder<'a>(
&'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
Expand All@@ -812,6 +824,8 @@ where

/// Creates a [`StaticInvoiceBuilder`] from the corresponding [`Offer`] and [`Nonce`] that were
/// created via [`Self::create_async_receive_offer_builder`].
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
&self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
payment_secret: PaymentSecret, relative_expiry_secs: u32,
Expand DownExpand Up@@ -884,6 +898,8 @@ where
///
/// Returns an error if the refund targets a different chain or if no valid
/// blinded path can be constructed.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref, F>(
&'a self, router: &R, entropy_source: ES, refund: &'a Refund,
usable_channels: Vec<ChannelDetails>, get_payment_info: F,
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/offers/merkle.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,6 +94,9 @@ pub enum SignError {
}

/// A function for signing a [`TaggedHash`].
///
/// This is not exported to bindings users as signing functions should just be used per-signed-type
/// instead.
Comment thread
joostjager marked this conversation as resolved.
pub trait SignFn<T: AsRef<TaggedHash>> {
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
fn sign(&self, message: &T) -> Result<Signature, ()>;
Expand Down
5 changes: 4 additions & 1 deletion lightning/src/offers/parse.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -142,7 +142,10 @@ pub enum Bolt12ParseError {
/// being parsed.
InvalidBech32Hrp,
/// The string could not be bech32 decoded.
Bech32(CheckedHrpstringError),
Bech32(
/// This is not exported to bindings users as the details don't matter much
CheckedHrpstringError,
),
/// The bech32 decoded string could not be decoded as the expected message type.
Decode(DecodeError),
/// The parsed message has invalid semantics.
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/sign/ecdsa.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,15 +7,16 @@ use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use crate::ln::chan_utils::{
ClosingTransaction, CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
HTLCOutputInCommitment, HolderCommitmentTransaction,
};
use crate::ln::msgs::UnsignedChannelAnnouncement;
use crate::types::payment::PaymentPreimage;

#[allow(unused_imports)]
use crate::prelude::*;

use crate::sign::{ChannelSigner, ChannelTransactionParameters, HTLCDescriptor};
use crate::sign::{ChannelSigner, HTLCDescriptor};

/// A trait to sign Lightning channel transactions as described in
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/sign/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1058,6 +1058,8 @@ pub trait SignerProvider {

/// A helper trait that describes an on-chain wallet capable of returning a (change) destination
/// script.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait ChangeDestinationSource {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
Expand All@@ -1069,6 +1071,9 @@ pub trait ChangeDestinationSource {

/// A synchronous helper trait that describes an on-chain wallet capable of returning a (change) destination script.
pub trait ChangeDestinationSourceSync {
/// Returns a script pubkey which can be used as a change destination for
/// [`OutputSpender::spend_spendable_outputs`].
///
/// This method should return a different value each time it is called, to avoid linking
/// on-chain funds controlled to the same user.
fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
Expand Down
12 changes: 12 additions & 0 deletions lightning/src/util/async_poll.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,27 +94,39 @@ pub(crate) fn dummy_waker() -> Waker {

#[cfg(feature = "std")]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;
#[cfg(not(feature = "std"))]
/// A type alias for a future that returns a result of type `T` or error `E`.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub type AsyncResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Sync as MaybeSync;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Sync` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope: some of the Maybe* markers were needed for rust 1.63. With the MSRV bump, perhaps some clean up is possible.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, yea, would be good to go back and remove what we can now.

@joostjagerjoostjagerNov 4, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MIssing the hypothetical rust 'unnecessary bound' warning.

pub trait MaybeSync {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSync for T where T: ?Sized {}

/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
#[cfg(feature = "std")]
pub use core::marker::Send as MaybeSend;

#[cfg(not(feature = "std"))]
/// Marker trait to optionally implement `Send` under std.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait MaybeSend {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSend for T where T: ?Sized {}
2 changes: 2 additions & 0 deletions lightning/src/util/native_async.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ use core::future::Future;
use core::pin::Pin;

/// A generic trait which is able to spawn futures in the background.
///
/// This is not exported to bindings users as async is only supported in Rust.
pub trait FutureSpawner: MaybeSend + MaybeSync + 'static {
/// Spawns the given future as a background task.
///
Expand Down
Loading
Loading