Skip to content
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

Create Taproot feature and introduce signer type enum #2289

Closed
wants to merge 3 commits into from
Closed
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
66 changes: 34 additions & 32 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use core::ops::Deref;
#[cfg(any(test, fuzzing, debug_assertions))]
use crate::sync::Mutex;
use bitcoin::hashes::hex::ToHex;
use crate::sign::type_resolver::ChannelSignerType;

#[cfg(test)]
pub struct ChannelValueStat {
Expand Down Expand Up @@ -534,7 +535,7 @@ pub(super) struct Channel<Signer: ChannelSigner> {

latest_monitor_update_id: u64,

holder_signer: Signer,
holder_signer: ChannelSignerType<Signer>,
shutdown_scriptpubkey: Option<ShutdownScript>,
destination_script: Script,

Expand Down Expand Up @@ -1042,7 +1043,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {

latest_monitor_update_id: 0,

holder_signer,
holder_signer: ChannelSignerType::Ecdsa(holder_signer),
shutdown_scriptpubkey,
destination_script,

Expand Down Expand Up @@ -1397,7 +1398,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {

latest_monitor_update_id: 0,

holder_signer,
holder_signer: ChannelSignerType::Ecdsa(holder_signer),
shutdown_scriptpubkey,
destination_script,

Expand Down Expand Up @@ -1836,7 +1837,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
/// The result is a transaction which we can revoke broadcastership of (ie a "local" transaction)
/// TODO Some magic rust shit to compile-time check this?
fn build_holder_transaction_keys(&self, commitment_number: u64) -> TxCreationKeys {
let per_commitment_point = self.holder_signer.get_per_commitment_point(commitment_number, &self.secp_ctx);
let per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(commitment_number, &self.secp_ctx);
let delayed_payment_base = &self.get_holder_pubkeys().delayed_payment_basepoint;
let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint;
let counterparty_pubkeys = self.get_counterparty_pubkeys();
Expand Down Expand Up @@ -2323,7 +2324,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
log_trace!(logger, "Initial counterparty tx for channel {} is: txid {} tx {}",
log_bytes!(self.channel_id()), counterparty_initial_bitcoin_tx.txid, encode::serialize_hex(&counterparty_initial_bitcoin_tx.transaction));

let counterparty_signature = self.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
let counterparty_signature = self.holder_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign "counterparty" commitment transaction, allowing them to broadcast the tx if they wish.
Expand Down Expand Up @@ -2363,7 +2364,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
self.channel_transaction_parameters.funding_outpoint = Some(funding_txo);
// This is an externally observable change before we finish all our checks. In particular
// funding_created_signature may fail.
self.holder_signer.provide_channel_parameters(&self.channel_transaction_parameters);
self.holder_signer.as_mut().provide_channel_parameters(&self.channel_transaction_parameters);

let (counterparty_initial_commitment_txid, initial_commitment_tx, signature) = match self.funding_created_signature(&msg.signature, logger) {
Ok(res) => res,
Expand All @@ -2386,7 +2387,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
self.counterparty_funding_pubkey()
);

self.holder_signer.validate_holder_commitment(&holder_commitment_tx, Vec::new())
self.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, Vec::new())
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;

// Now that we're past error-generating stuff, update our local state:
Expand Down Expand Up @@ -2476,7 +2477,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
self.counterparty_funding_pubkey()
);

self.holder_signer.validate_holder_commitment(&holder_commitment_tx, Vec::new())
self.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, Vec::new())
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;


Expand Down Expand Up @@ -3245,7 +3246,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
self.counterparty_funding_pubkey()
);

self.holder_signer.validate_holder_commitment(&holder_commitment_tx, commitment_stats.preimages)
self.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_stats.preimages)
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;

// Update state now that we've passed all the can-fail calls...
Expand Down Expand Up @@ -3505,7 +3506,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
*self.next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
}

self.holder_signer.validate_counterparty_revocation(
self.holder_signer.as_ecdsa().unwrap().validate_counterparty_revocation(
self.cur_counterparty_commitment_transaction_number + 1,
&secret
).map_err(|_| ChannelError::Close("Failed to validate revocation from peer".to_owned()))?;
Expand Down Expand Up @@ -3913,7 +3914,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
assert!(!self.is_outbound() || self.minimum_depth == Some(0),
"Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
self.monitor_pending_channel_ready = false;
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let next_per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
Some(msgs::ChannelReady {
channel_id: self.channel_id(),
next_per_commitment_point,
Expand Down Expand Up @@ -3993,8 +3994,8 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
}

fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK {
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let per_commitment_secret = self.holder_signer.release_commitment_secret(self.cur_holder_commitment_transaction_number + 2);
let next_per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let per_commitment_secret = self.holder_signer.as_ref().release_commitment_secret(self.cur_holder_commitment_transaction_number + 2);
msgs::RevokeAndACK {
channel_id: self.channel_id,
per_commitment_secret,
Expand Down Expand Up @@ -4096,7 +4097,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
}

if msg.next_remote_commitment_number > 0 {
let expected_point = self.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1, &self.secp_ctx);
let expected_point = self.holder_signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1, &self.secp_ctx);
let given_secret = SecretKey::from_slice(&msg.your_last_per_commitment_secret)
.map_err(|_| ChannelError::Close("Peer sent a garbage channel_reestablish with unparseable secret key".to_owned()))?;
if expected_point != PublicKey::from_secret_key(&self.secp_ctx, &given_secret) {
Expand Down Expand Up @@ -4160,7 +4161,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
}

// We have OurChannelReady set!
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let next_per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
return Ok(ReestablishResponses {
channel_ready: Some(msgs::ChannelReady {
channel_id: self.channel_id(),
Expand Down Expand Up @@ -4196,7 +4197,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {

let channel_ready = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.cur_holder_commitment_transaction_number == 1 {
// We should never have to worry about MonitorUpdateInProgress resending ChannelReady
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let next_per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
Copy link
Collaborator

Choose a reason for hiding this comment

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

While you're at it can we clean up a lot of the long lines in this file (that are now worse).

Some(msgs::ChannelReady {
channel_id: self.channel_id(),
next_per_commitment_point,
Expand Down Expand Up @@ -4345,7 +4346,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
log_trace!(logger, "Proposing initial closing_signed for our counterparty with a fee range of {}-{} sat (with initial proposal {} sats)",
our_min_fee, our_max_fee, total_fee_satoshis);

let sig = self.holder_signer
let sig = self.holder_signer.as_ecdsa().unwrap()
.sign_closing_transaction(&closing_tx, &self.secp_ctx)
.map_err(|()| ChannelError::Close("Failed to get signature for closing transaction.".to_owned()))?;

Expand Down Expand Up @@ -4555,7 +4556,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
self.build_closing_transaction($new_fee, false)
};

let sig = self.holder_signer
let sig = self.holder_signer.as_ecdsa().unwrap()
.sign_closing_transaction(&closing_tx, &self.secp_ctx)
.map_err(|_| ChannelError::Close("External signer refused to sign closing transaction".to_owned()))?;

Expand Down Expand Up @@ -4927,7 +4928,8 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {

#[cfg(test)]
pub fn get_signer(&self) -> &Signer {
&self.holder_signer
// the Signer parameterization will only ever be used for the ECDSA signer
self.holder_signer.as_ecdsa().unwrap()
}

#[cfg(test)]
Expand Down Expand Up @@ -5170,7 +5172,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
if self.channel_state & (ChannelState::MonitorUpdateInProgress as u32) == 0 {
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
let next_per_commitment_point =
self.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.secp_ctx);
self.holder_signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.secp_ctx);
return Some(msgs::ChannelReady {
channel_id: self.channel_id,
next_per_commitment_point,
Expand Down Expand Up @@ -5394,7 +5396,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
panic!("Tried to send an open_channel for a channel that has already advanced");
}

let first_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let first_per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let keys = self.get_holder_pubkeys();

msgs::OpenChannel {
Expand Down Expand Up @@ -5464,7 +5466,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
///
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
fn generate_accept_channel_message(&self) -> msgs::AcceptChannel {
let first_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let first_per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
let keys = self.get_holder_pubkeys();

msgs::AcceptChannel {
Expand Down Expand Up @@ -5505,7 +5507,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let counterparty_keys = self.build_remote_transaction_keys();
let counterparty_initial_commitment_tx = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
Ok(self.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
Ok(self.holder_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand All @@ -5530,7 +5532,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
}

self.channel_transaction_parameters.funding_outpoint = Some(funding_txo);
self.holder_signer.provide_channel_parameters(&self.channel_transaction_parameters);
self.holder_signer.as_mut().provide_channel_parameters(&self.channel_transaction_parameters);

let signature = match self.get_outbound_funding_created_signature(logger) {
Ok(res) => res,
Expand Down Expand Up @@ -5639,7 +5641,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
},
Ok(v) => v
};
let our_bitcoin_sig = match self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx) {
let our_bitcoin_sig = match self.holder_signer.as_ecdsa().unwrap().sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx) {
Err(_) => {
log_error!(logger, "Signer rejected channel_announcement signing. Channel will not be announced!");
return None;
Expand Down Expand Up @@ -5668,7 +5670,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {

let our_node_sig = node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement))
.map_err(|_| ChannelError::Ignore("Failed to generate node signature for channel_announcement".to_owned()))?;
let our_bitcoin_sig = self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx)
let our_bitcoin_sig = self.holder_signer.as_ecdsa().unwrap().sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx)
.map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement".to_owned()))?;
Ok(msgs::ChannelAnnouncement {
node_signature_1: if were_node_one { our_node_sig } else { their_node_sig },
Expand Down Expand Up @@ -6048,7 +6050,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
htlcs.push(htlc);
}

let res = self.holder_signer.sign_counterparty_commitment(&commitment_stats.tx, commitment_stats.preimages, &self.secp_ctx)
let res = self.holder_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_stats.tx, commitment_stats.preimages, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
Expand Down Expand Up @@ -6360,7 +6362,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
self.latest_monitor_update_id.write(writer)?;

let mut key_data = VecWriter(Vec::new());
self.holder_signer.write(&mut key_data)?;
self.holder_signer.as_ecdsa().unwrap().write(&mut key_data)?;
assert!(key_data.0.len() < core::usize::MAX);
assert!(key_data.0.len() < core::u32::MAX as usize);
(key_data.0.len() as u32).write(writer)?;
Expand Down Expand Up @@ -7005,7 +7007,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch

latest_monitor_update_id,

holder_signer,
holder_signer: ChannelSignerType::Ecdsa(holder_signer),
shutdown_scriptpubkey,
destination_script,

Expand Down Expand Up @@ -7688,10 +7690,10 @@ mod tests {
// We can't just use build_holder_transaction_keys here as the per_commitment_secret is not
// derived from a commitment_seed, so instead we copy it here and call
// build_commitment_transaction.
let delayed_payment_base = &chan.holder_signer.pubkeys().delayed_payment_basepoint;
let delayed_payment_base = &chan.holder_signer.as_ref().pubkeys().delayed_payment_basepoint;
let per_commitment_secret = SecretKey::from_slice(&hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..]).unwrap();
let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
let htlc_basepoint = &chan.holder_signer.pubkeys().htlc_basepoint;
let htlc_basepoint = &chan.holder_signer.as_ref().pubkeys().htlc_basepoint;
let keys = TxCreationKeys::derive_new(&secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint);

macro_rules! test_commitment {
Expand Down Expand Up @@ -7743,7 +7745,7 @@ mod tests {
commitment_tx.clone(),
counterparty_signature,
counterparty_htlc_sigs,
&chan.holder_signer.pubkeys().funding_pubkey,
&chan.holder_signer.as_ref().pubkeys().funding_pubkey,
chan.counterparty_funding_pubkey()
);
let (holder_sig, htlc_sigs) = signer.sign_holder_commitment_and_htlcs(&holder_commitment_tx, &secp_ctx).unwrap();
Expand Down
9 changes: 6 additions & 3 deletions lightning/src/ln/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ mod sealed {
// Byte 2
BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx,
// Byte 3
ShutdownAnySegwit,
ShutdownAnySegwit | Taproot,
// Byte 4
OnionMessages,
// Byte 5
Expand All @@ -152,7 +152,7 @@ mod sealed {
// Byte 2
BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx,
// Byte 3
ShutdownAnySegwit,
ShutdownAnySegwit | Taproot,
// Byte 4
OnionMessages,
// Byte 5
Expand Down Expand Up @@ -198,7 +198,7 @@ mod sealed {
// Byte 2
AnchorsZeroFeeHtlcTx,
// Byte 3
,
Taproot,
// Byte 4
,
// Byte 5
Expand Down Expand Up @@ -384,6 +384,9 @@ mod sealed {
define_feature!(27, ShutdownAnySegwit, [InitContext, NodeContext],
"Feature flags for `opt_shutdown_anysegwit`.", set_shutdown_any_segwit_optional,
set_shutdown_any_segwit_required, supports_shutdown_anysegwit, requires_shutdown_anysegwit);
define_feature!(31, Taproot, [InitContext, NodeContext, ChannelTypeContext],
Copy link

Choose a reason for hiding this comment

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

wpaulino marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add a TODO(taproot) to the module docs above to remember to document support for simple taproot channels when the time comes?

"Feature flags for `option_taproot`.", set_taproot_optional,
set_taproot_required, supports_taproot, requires_taproot);
define_feature!(39, OnionMessages, [InitContext, NodeContext],
"Feature flags for `option_onion_messages`.", set_onion_messages_optional,
set_onion_messages_required, supports_onion_messages, requires_onion_messages);
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/sign/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,13 @@ use core::ops::Deref;
use core::sync::atomic::{AtomicUsize, Ordering};
use crate::io::{self, Error};
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
use crate::sign::type_resolver::AsChannelSigner;
use crate::util::atomic_counter::AtomicCounter;
use crate::util::chacha20::ChaCha20;
use crate::util::invoice::construct_invoice_preimage;

pub(crate) mod type_resolver;

/// Used as initial key material, to be expanded into multiple secret keys (but not to be used
/// directly). This is used within LDK to encrypt/decrypt inbound payment data.
///
Expand Down
52 changes: 52 additions & 0 deletions lightning/src/sign/type_resolver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::sign::{ChannelSigner, EcdsaChannelSigner};

pub(crate) enum ChannelSignerType<ECS: ChannelSigner> {
// in practice, this will only ever be an EcdsaChannelSigner
Ecdsa(ECS)
}

impl<ECS: EcdsaChannelSigner> ChannelSignerType<ECS> {
pub(crate) fn as_ref(&self) -> &dyn ChannelSigner {
wpaulino marked this conversation as resolved.
Show resolved Hide resolved
match self {
ChannelSignerType::Ecdsa(cs) => cs.as_channel_signer()
}
}

pub(crate) fn as_mut(&mut self) -> &mut dyn ChannelSigner {
match self {
ChannelSignerType::Ecdsa(cs) => cs.as_mut_channel_signer()
}
}

pub(crate) fn as_ecdsa(&self) -> Option<&ECS> {
match self {
ChannelSignerType::Ecdsa(ecs) => Some(ecs),
#[cfg(taproot)]
_ => None
}
}

pub(crate) fn as_mut_ecdsa(&mut self) -> Option<&mut ECS> {
match self {
ChannelSignerType::Ecdsa(ecs) => Some(ecs),
#[cfg(taproot)]
_ => None
}
}
}

/// Helper trait for accessing common channel signer methods between different implementations
pub trait AsChannelSigner {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this needs to be public, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh I guess it doesn't matter since we make the module pub(crate).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It actually does, unfortunately. Rust is complaining that ChannelSigner (public) inherits from a trait that would otherwise have a lower visibility, which is a no-no. Thankfully, the compiler doesn't yet detect that that's meaningless. So 🤫

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this means a downstream crate is unable to implement ChannelSigner (you've sealed it). Instead, you can impl<C: ChannelSigner> AsChannelSigner for C and not inherit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not inheriting will break the functionality, unfortunately. It's a crucial aspect. But I have a different idea.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is the inheritance critical here? Maybe we don't land this PR until we get a few more commits so that reviewers can better understand where its going?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

Huh, TIL, but you can take that sample and simply remove the extension and it still compiles?

trait Base {
    fn a(&self) -> ();
}

trait AsBase {
    fn as_base(&self) -> &dyn Base;
}

impl<T: Base> AsBase for T {
    fn as_base(&self) -> &dyn Base {
        self
    }
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Here's a more self-contained example of what we're trying to achieve: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4d9d295a47d6da11e2fd58c27ffc3fda

Copy link
Collaborator

Choose a reason for hiding this comment

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

The issue is the Bar(Box<dyn Bar>), which seems like it should be fixed instead of adding a new public trait. ISTM we should just include additional commits here so that the whole context can be reviewed, rather than reviewing something in part that doesn't make sense on its own.

fn as_channel_signer(&self) -> &dyn ChannelSigner;
fn as_mut_channel_signer(&mut self) -> &mut dyn ChannelSigner;
}

impl<CS: ChannelSigner> AsChannelSigner for CS {
fn as_channel_signer(&self) -> &dyn ChannelSigner {
self
}

fn as_mut_channel_signer(&mut self) -> &mut dyn ChannelSigner {
self
}
}