Skip to content

Remove the async_signing cfg flag #3486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 17, 2024
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
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ check-cfg = [
"cfg(ldk_bench)",
"cfg(ldk_test_vectors)",
"cfg(taproot)",
"cfg(async_signing)",
"cfg(require_route_graph_test)",
"cfg(splicing)",
"cfg(async_payments)",
Expand Down
2 changes: 0 additions & 2 deletions ci/ci-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,6 @@ fi
echo -e "\n\nTest cfg-flag builds"
RUSTFLAGS="--cfg=taproot" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=async_signing" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=splicing" cargo test --verbose --color always -p lightning
[ "$CI_MINIMIZE_DISK_USAGE" != "" ] && cargo clean
RUSTFLAGS="--cfg=async_payments" cargo test --verbose --color always -p lightning
82 changes: 24 additions & 58 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,6 @@ pub(super) struct MonitorRestoreUpdates {
}

/// The return value of `signer_maybe_unblocked`
#[allow(unused)]
pub(super) struct SignerResumeUpdates {
pub commitment_update: Option<msgs::CommitmentUpdate>,
pub revoke_and_ack: Option<msgs::RevokeAndACK>,
Expand Down Expand Up @@ -3959,13 +3958,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
log_trace!(logger, "Counterparty commitment signature available for funding_signed message; clearing signer_pending_funding");
self.signer_pending_funding = false;
} else if signature.is_none() {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for funding_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for funding_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
}
log_trace!(logger, "Counterparty commitment signature not available for funding_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
}

signature.map(|(signature, _)| msgs::FundingSigned {
Expand Down Expand Up @@ -6114,7 +6108,6 @@ impl<SP: Deref> Channel<SP> where

/// Indicates that the signer may have some signatures for us, so we should retry if we're
/// blocked.
#[cfg(async_signing)]
pub fn signer_maybe_unblocked<L: Deref>(&mut self, logger: &L) -> SignerResumeUpdates where L::Target: Logger {
if !self.holder_commitment_point.is_available() {
log_trace!(logger, "Attempting to update holder per-commitment point...");
Expand Down Expand Up @@ -6231,21 +6224,16 @@ impl<SP: Deref> Channel<SP> where
&self.context.channel_id(), self.holder_commitment_point.transaction_number(),
self.holder_commitment_point.transaction_number() + 2);
}
#[cfg(not(async_signing))] {
panic!("Holder commitment point and per commitment secret must be available when generating revoke_and_ack");
}
#[cfg(async_signing)] {
// Technically if we're at HolderCommitmentPoint::PendingNext,
// we have a commitment point ready to send in an RAA, however we
// choose to wait since if we send RAA now, we could get another
// CS before we have any commitment point available. Blocking our
// RAA here is a convenient way to make sure that post-funding
// we're only ever waiting on one commitment point at a time.
log_trace!(logger, "Last revoke-and-ack pending in channel {} for sequence {} because the next per-commitment point is not available",
&self.context.channel_id(), self.holder_commitment_point.transaction_number());
self.context.signer_pending_revoke_and_ack = true;
None
}
// Technically if we're at HolderCommitmentPoint::PendingNext,
// we have a commitment point ready to send in an RAA, however we
// choose to wait since if we send RAA now, we could get another
// CS before we have any commitment point available. Blocking our
// RAA here is a convenient way to make sure that post-funding
// we're only ever waiting on one commitment point at a time.
log_trace!(logger, "Last revoke-and-ack pending in channel {} for sequence {} because the next per-commitment point is not available",
&self.context.channel_id(), self.holder_commitment_point.transaction_number());
self.context.signer_pending_revoke_and_ack = true;
None
}

/// Gets the last commitment update for immediate sending to our peer.
Expand Down Expand Up @@ -6316,16 +6304,11 @@ impl<SP: Deref> Channel<SP> where
}
update
} else {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for new commitment state");
}
#[cfg(async_signing)] {
if !self.context.signer_pending_commitment_update {
log_trace!(logger, "Commitment update awaiting signer: setting signer_pending_commitment_update");
self.context.signer_pending_commitment_update = true;
}
return Err(());
if !self.context.signer_pending_commitment_update {
log_trace!(logger, "Commitment update awaiting signer: setting signer_pending_commitment_update");
self.context.signer_pending_commitment_update = true;
}
return Err(());
};
Ok(msgs::CommitmentUpdate {
update_add_htlcs, update_fulfill_htlcs, update_fail_htlcs, update_fail_malformed_htlcs, update_fee,
Expand Down Expand Up @@ -8362,13 +8345,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
log_trace!(logger, "Counterparty commitment signature ready for funding_created message: clearing signer_pending_funding");
self.context.signer_pending_funding = false;
} else if signature.is_none() {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for new funding creation");
}
#[cfg(async_signing)] {
log_trace!(logger, "funding_created awaiting signer; setting signer_pending_funding");
self.context.signer_pending_funding = true;
}
log_trace!(logger, "funding_created awaiting signer; setting signer_pending_funding");
self.context.signer_pending_funding = true;
};

signature.map(|signature| msgs::FundingCreated {
Expand Down Expand Up @@ -8467,14 +8445,9 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
holder_commitment_point.current_point()
},
_ => {
#[cfg(not(async_signing))] {
panic!("Failed getting commitment point for open_channel message");
}
#[cfg(async_signing)] {
log_trace!(_logger, "Unable to generate open_channel message, waiting for commitment point");
self.signer_pending_open_channel = true;
return None;
}
log_trace!(_logger, "Unable to generate open_channel message, waiting for commitment point");
self.signer_pending_open_channel = true;
return None;
}
};
let keys = self.context.get_holder_pubkeys();
Expand Down Expand Up @@ -8562,7 +8535,6 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {

/// Indicates that the signer may have some signatures for us, so we should retry if we're
/// blocked.
#[cfg(async_signing)]
pub fn signer_maybe_unblocked<L: Deref>(
&mut self, chain_hash: ChainHash, logger: &L
) -> (Option<msgs::OpenChannel>, Option<msgs::FundingCreated>) where L::Target: Logger {
Expand Down Expand Up @@ -8723,14 +8695,9 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
holder_commitment_point.current_point()
},
_ => {
#[cfg(not(async_signing))] {
panic!("Failed getting commitment point for accept_channel message");
}
#[cfg(async_signing)] {
log_trace!(_logger, "Unable to generate accept_channel message, waiting for commitment point");
self.signer_pending_accept_channel = true;
return None;
}
log_trace!(_logger, "Unable to generate accept_channel message, waiting for commitment point");
self.signer_pending_accept_channel = true;
return None;
}
};
let keys = self.context.get_holder_pubkeys();
Expand Down Expand Up @@ -8833,7 +8800,6 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {

/// Indicates that the signer may have some signatures for us, so we should retry if we're
/// blocked.
#[allow(unused)]
pub fn signer_maybe_unblocked<L: Deref>(
&mut self, logger: &L
) -> Option<msgs::AcceptChannel> where L::Target: Logger {
Expand Down
1 change: 0 additions & 1 deletion lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9512,7 +9512,6 @@ where
/// attempted in every channel, or in the specifically provided channel.
///
/// [`ChannelSigner`]: crate::sign::ChannelSigner
#[cfg(async_signing)]
pub fn signer_unblocked(&self, channel_opt: Option<(PublicKey, ChannelId)>) {
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);

Expand Down
2 changes: 1 addition & 1 deletion lightning/src/ln/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ mod monitor_tests;
#[cfg(test)]
#[allow(unused_mut)]
mod shutdown_tests;
#[cfg(all(test, async_signing))]
#[cfg(test)]
#[allow(unused_mut)]
mod async_signer_tests;
#[cfg(test)]
Expand Down
56 changes: 41 additions & 15 deletions lightning/src/sign/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ use crate::sign::{ChannelSigner, HTLCDescriptor};
/// policies in order to be secure. Please refer to the [VLS Policy
/// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md)
/// for an example of such policies.
///
/// Like [`ChannelSigner`], many of the methods allow errors to be returned to support async
/// signing. In such cases, the signing operation can be replayed by calling
/// [`ChannelManager::signer_unblocked`] or [`ChainMonitor::signer_unblocked`] (see individual
/// method documentation for which method should be called) once the result is ready, at which
/// point the channel operation will resume.
Comment on lines +30 to +32
Copy link
Contributor

Choose a reason for hiding this comment

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

I noticed that ChannelManager::signer_unblocked docs sound like it needs to be called whenever any of these methods errors. It's clear in these docs which signer_unblocked method needs to be called, but there it could be clearer and {Chain,Channel}Monitor::signer_unblocked could also benefit from referencing these docs IMO. Doesn't need to happen in this PR though.

///
/// [`ChannelManager::signer_unblocked`]: crate::ln::channelmanager::ChannelManager::signer_unblocked
/// [`ChainMonitor::signer_unblocked`]: crate::chain::chainmonitor::ChainMonitor::signer_unblocked
pub trait EcdsaChannelSigner: ChannelSigner {
/// Create a signature for a counterparty's commitment transaction and associated HTLC transactions.
///
/// Note that if signing fails or is rejected, the channel will be force-closed.
///
/// Policy checks should be implemented in this function, including checking the amount
/// sent to us and checking the HTLCs.
///
Expand All @@ -39,8 +46,12 @@ pub trait EcdsaChannelSigner: ChannelSigner {
///
/// Note that all the relevant preimages will be provided, but there may also be additional
/// irrelevant or duplicate preimages.
//
// TODO: Document the things someone using this interface should enforce before signing.
///
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelManager::signer_unblocked`] must be called.
///
/// [`ChannelManager::signer_unblocked`]: crate::ln::channelmanager::ChannelManager::signer_unblocked
fn sign_counterparty_commitment(
&self, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>,
outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>,
Expand All @@ -58,18 +69,19 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelMonitor::signer_unblocked`] must be called on its
/// monitor.
/// monitor or [`ChainMonitor::signer_unblocked`] called to attempt unblocking all monitors.
///
/// [`ChannelMonitor::signer_unblocked`]: crate::chain::channelmonitor::ChannelMonitor::signer_unblocked
//
// TODO: Document the things someone using this interface should enforce before signing.
/// [`ChainMonitor::signer_unblocked`]: crate::chain::chainmonitor::ChainMonitor::signer_unblocked
fn sign_holder_commitment(
&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>,
) -> Result<Signature, ()>;
/// Same as [`sign_holder_commitment`], but exists only for tests to get access to holder
/// commitment transactions which will be broadcasted later, after the channel has moved on to a
/// newer state. Thus, needs its own method as [`sign_holder_commitment`] may enforce that we
/// only ever get called once.
///
/// This method is *not* async as it is intended only for testing purposes.
#[cfg(any(test, feature = "unsafe_revoked_tx_signing"))]
fn unsafe_sign_holder_commitment(
&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>,
Expand All @@ -92,9 +104,10 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelMonitor::signer_unblocked`] must be called on its
/// monitor.
/// monitor or [`ChainMonitor::signer_unblocked`] called to attempt unblocking all monitors.
///
/// [`ChannelMonitor::signer_unblocked`]: crate::chain::channelmonitor::ChannelMonitor::signer_unblocked
/// [`ChainMonitor::signer_unblocked`]: crate::chain::chainmonitor::ChainMonitor::signer_unblocked
fn sign_justice_revoked_output(
&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey,
secp_ctx: &Secp256k1<secp256k1::All>,
Expand All @@ -121,9 +134,10 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelMonitor::signer_unblocked`] must be called on its
/// monitor.
/// monitor or [`ChainMonitor::signer_unblocked`] called to attempt unblocking all monitors.
///
/// [`ChannelMonitor::signer_unblocked`]: crate::chain::channelmonitor::ChannelMonitor::signer_unblocked
/// [`ChainMonitor::signer_unblocked`]: crate::chain::chainmonitor::ChainMonitor::signer_unblocked
fn sign_justice_revoked_htlc(
&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey,
htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<secp256k1::All>,
Expand All @@ -139,11 +153,12 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelMonitor::signer_unblocked`] must be called on its
/// monitor.
/// monitor or [`ChainMonitor::signer_unblocked`] called to attempt unblocking all monitors.
///
/// [`EcdsaSighashType::All`]: bitcoin::sighash::EcdsaSighashType::All
/// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
/// [`ChannelMonitor::signer_unblocked`]: crate::chain::channelmonitor::ChannelMonitor::signer_unblocked
/// [`ChainMonitor::signer_unblocked`]: crate::chain::chainmonitor::ChainMonitor::signer_unblocked
fn sign_holder_htlc_transaction(
&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
secp_ctx: &Secp256k1<secp256k1::All>,
Expand All @@ -169,9 +184,10 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelMonitor::signer_unblocked`] must be called on its
/// monitor.
/// monitor or [`ChainMonitor::signer_unblocked`] called to attempt unblocking all monitors.
///
/// [`ChannelMonitor::signer_unblocked`]: crate::chain::channelmonitor::ChannelMonitor::signer_unblocked
/// [`ChainMonitor::signer_unblocked`]: crate::chain::chainmonitor::ChainMonitor::signer_unblocked
fn sign_counterparty_htlc_transaction(
&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey,
htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<secp256k1::All>,
Expand All @@ -180,6 +196,12 @@ pub trait EcdsaChannelSigner: ChannelSigner {
///
/// Note that, due to rounding, there may be one "missing" satoshi, and either party may have
/// chosen to forgo their output as dust.
///
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelManager::signer_unblocked`] must be called.
///
/// [`ChannelManager::signer_unblocked`]: crate::ln::channelmanager::ChannelManager::signer_unblocked
fn sign_closing_transaction(
&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1<secp256k1::All>,
) -> Result<Signature, ()>;
Expand All @@ -189,9 +211,10 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// An `Err` can be returned to signal that the signer is unavailable/cannot produce a valid
/// signature and should be retried later. Once the signer is ready to provide a signature after
/// previously returning an `Err`, [`ChannelMonitor::signer_unblocked`] must be called on its
/// monitor.
/// monitor or [`ChainMonitor::signer_unblocked`] called to attempt unblocking all monitors.
///
/// [`ChannelMonitor::signer_unblocked`]: crate::chain::channelmonitor::ChannelMonitor::signer_unblocked
/// [`ChainMonitor::signer_unblocked`]: crate::chain::chainmonitor::ChainMonitor::signer_unblocked
fn sign_holder_anchor_input(
&self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
) -> Result<Signature, ()>;
Expand All @@ -201,9 +224,9 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// Channel announcements also require a signature from each node's network key. Our node
/// signature is computed through [`NodeSigner::sign_gossip_message`].
///
/// Note that if this fails or is rejected, the channel will not be publicly announced and
/// our counterparty may (though likely will not) close the channel on us for violating the
/// protocol.
/// This method is *not* asynchronous. If an `Err` is returned, the channel will not be
/// publicly announced and our counterparty may (though likely will not) close the channel on
/// us for violating the protocol.
///
/// [`NodeSigner::sign_gossip_message`]: crate::sign::NodeSigner::sign_gossip_message
fn sign_channel_announcement_with_funding_key(
Expand All @@ -219,6 +242,9 @@ pub trait EcdsaChannelSigner: ChannelSigner {
/// spending the previous funding transaction's output
///
/// `input_value`: The value of the previous funding transaction output.
///
/// This method is *not* asynchronous. If an `Err` is returned, the channel will be immediately
/// closed.
fn sign_splicing_funding_input(
&self, tx: &Transaction, input_index: usize, input_value: u64,
secp_ctx: &Secp256k1<secp256k1::All>,
Expand Down
Loading
Loading