Skip to content

Commit a8dbede

Browse files
committed
Introduce DynSigner, a dynamically dispatched signer
DynSigner provides an abstraction for specifying an external signer for functional tests.
1 parent 240a1e3 commit a8dbede

File tree

6 files changed

+513
-66
lines changed

6 files changed

+513
-66
lines changed

lightning/src/sign/ecdsa.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub trait EcdsaChannelSigner: ChannelSigner {
8282
/// only ever get called once.
8383
///
8484
/// This method is *not* async as it is intended only for testing purposes.
85-
#[cfg(any(test, feature = "unsafe_revoked_tx_signing"))]
85+
#[cfg(any(test, feature = "_test_utils", feature = "unsafe_revoked_tx_signing"))]
8686
fn unsafe_sign_holder_commitment(
8787
&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>,
8888
) -> Result<Signature, ()>;

lightning/src/sign/mod.rs

Lines changed: 66 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ use bitcoin::hashes::{Hash, HashEngine};
3131
use bitcoin::secp256k1::ecdh::SharedSecret;
3232
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
3333
use bitcoin::secp256k1::schnorr;
34-
#[cfg(taproot)]
3534
use bitcoin::secp256k1::All;
3635
use bitcoin::secp256k1::{Keypair, PublicKey, Scalar, Secp256k1, SecretKey, Signing};
3736
use bitcoin::{secp256k1, Psbt, Sequence, Txid, WPubkeyHash, Witness};
@@ -725,6 +724,36 @@ impl HTLCDescriptor {
725724
}
726725
}
727726

727+
/// Extension trait for [`ChannelSigner`] providing access to additional channel-specific
728+
/// details. In particular, this is useful for functional tests.
729+
pub trait ChannelSignerExt: ChannelSigner {
730+
/// Returns the commitment seed for the channel.
731+
fn commitment_seed(&self) -> [u8; 32];
732+
/// Returns the counterparty's pubkeys.
733+
///
734+
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
735+
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
736+
fn counterparty_pubkeys(&self) -> Option<&ChannelPublicKeys>;
737+
/// Funding outpoint
738+
///
739+
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
740+
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
741+
fn funding_outpoint(&self) -> Option<&OutPoint>;
742+
/// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
743+
/// building transactions.
744+
///
745+
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
746+
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
747+
fn get_channel_parameters(&self) -> Option<&ChannelTransactionParameters>;
748+
749+
/// Returns the channel type features of the channel parameters. Should be helpful for
750+
/// determining a channel's category, i.e. legacy/anchors/taproot/etc.
751+
///
752+
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
753+
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
754+
fn channel_type_features(&self) -> Option<&ChannelTypeFeatures>;
755+
}
756+
728757
/// A trait to handle Lightning channel key material without concretizing the channel type or
729758
/// the signature mechanism.
730759
///
@@ -930,10 +959,10 @@ pub trait OutputSpender {
930959
/// Returns `Err(())` if the output value is greater than the input value minus required fee,
931960
/// if a descriptor was duplicated, or if an output descriptor `script_pubkey`
932961
/// does not match the one we can spend.
933-
fn spend_spendable_outputs<C: Signing>(
962+
fn spend_spendable_outputs(
934963
&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
935964
change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
936-
locktime: Option<LockTime>, secp_ctx: &Secp256k1<C>,
965+
locktime: Option<LockTime>, secp_ctx: &Secp256k1<All>,
937966
) -> Result<Transaction, ()>;
938967
}
939968

@@ -1139,16 +1168,6 @@ impl InMemorySigner {
11391168
}
11401169
}
11411170

1142-
/// Returns the counterparty's pubkeys.
1143-
///
1144-
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
1145-
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
1146-
pub fn counterparty_pubkeys(&self) -> Option<&ChannelPublicKeys> {
1147-
self.get_channel_parameters().and_then(|params| {
1148-
params.counterparty_parameters.as_ref().map(|params| &params.pubkeys)
1149-
})
1150-
}
1151-
11521171
/// Returns the `contest_delay` value specified by our counterparty and applied on holder-broadcastable
11531172
/// transactions, i.e., the amount of time that we have to wait to recover our funds if we
11541173
/// broadcast a transaction.
@@ -1179,14 +1198,6 @@ impl InMemorySigner {
11791198
self.get_channel_parameters().map(|params| params.is_outbound_from_holder)
11801199
}
11811200

1182-
/// Funding outpoint
1183-
///
1184-
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
1185-
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
1186-
pub fn funding_outpoint(&self) -> Option<&OutPoint> {
1187-
self.get_channel_parameters().map(|params| params.funding_outpoint.as_ref()).flatten()
1188-
}
1189-
11901201
/// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
11911202
/// building transactions.
11921203
///
@@ -1196,15 +1207,6 @@ impl InMemorySigner {
11961207
self.channel_parameters.as_ref()
11971208
}
11981209

1199-
/// Returns the channel type features of the channel parameters. Should be helpful for
1200-
/// determining a channel's category, i. e. legacy/anchors/taproot/etc.
1201-
///
1202-
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
1203-
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
1204-
pub fn channel_type_features(&self) -> Option<&ChannelTypeFeatures> {
1205-
self.get_channel_parameters().map(|params| &params.channel_type_features)
1206-
}
1207-
12081210
/// Sign the single input of `spend_tx` at index `input_idx`, which spends the output described
12091211
/// by `descriptor`, returning the witness stack for the input.
12101212
///
@@ -1356,6 +1358,35 @@ impl EntropySource for InMemorySigner {
13561358
}
13571359
}
13581360

1361+
impl ChannelSignerExt for InMemorySigner {
1362+
fn commitment_seed(&self) -> [u8; 32] {
1363+
self.commitment_seed
1364+
}
1365+
1366+
fn counterparty_pubkeys(&self) -> Option<&ChannelPublicKeys> {
1367+
self.get_channel_parameters().and_then(|params| {
1368+
params.counterparty_parameters.as_ref().map(|params| &params.pubkeys)
1369+
})
1370+
}
1371+
1372+
fn funding_outpoint(&self) -> Option<&OutPoint> {
1373+
self.get_channel_parameters().map(|params| params.funding_outpoint.as_ref()).flatten()
1374+
}
1375+
1376+
fn get_channel_parameters(&self) -> Option<&ChannelTransactionParameters> {
1377+
self.channel_parameters.as_ref()
1378+
}
1379+
1380+
/// Returns the channel type features of the channel parameters. Should be helpful for
1381+
/// determining a channel's category, i. e. legacy/anchors/taproot/etc.
1382+
///
1383+
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
1384+
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
1385+
fn channel_type_features(&self) -> Option<&ChannelTypeFeatures> {
1386+
self.get_channel_parameters().map(|params| &params.channel_type_features)
1387+
}
1388+
}
1389+
13591390
impl ChannelSigner for InMemorySigner {
13601391
fn get_per_commitment_point(
13611392
&self, idx: u64, secp_ctx: &Secp256k1<secp256k1::All>,
@@ -1488,7 +1519,7 @@ impl EcdsaChannelSigner for InMemorySigner {
14881519
))
14891520
}
14901521

1491-
#[cfg(any(test, feature = "unsafe_revoked_tx_signing"))]
1522+
#[cfg(any(test, feature = "_test_utils", feature = "unsafe_revoked_tx_signing"))]
14921523
fn unsafe_sign_holder_commitment(
14931524
&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>,
14941525
) -> Result<Signature, ()> {
@@ -2237,10 +2268,10 @@ impl OutputSpender for KeysManager {
22372268
///
22382269
/// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
22392270
/// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
2240-
fn spend_spendable_outputs<C: Signing>(
2271+
fn spend_spendable_outputs(
22412272
&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
22422273
change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
2243-
locktime: Option<LockTime>, secp_ctx: &Secp256k1<C>,
2274+
locktime: Option<LockTime>, secp_ctx: &Secp256k1<All>,
22442275
) -> Result<Transaction, ()> {
22452276
let (mut psbt, expected_max_weight) =
22462277
SpendableOutputDescriptor::create_spendable_outputs_psbt(
@@ -2395,10 +2426,10 @@ impl NodeSigner for PhantomKeysManager {
23952426
impl OutputSpender for PhantomKeysManager {
23962427
/// See [`OutputSpender::spend_spendable_outputs`] and [`KeysManager::spend_spendable_outputs`]
23972428
/// for documentation on this method.
2398-
fn spend_spendable_outputs<C: Signing>(
2429+
fn spend_spendable_outputs(
23992430
&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
24002431
change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
2401-
locktime: Option<LockTime>, secp_ctx: &Secp256k1<C>,
2432+
locktime: Option<LockTime>, secp_ctx: &Secp256k1<All>,
24022433
) -> Result<Transaction, ()> {
24032434
self.inner.spend_spendable_outputs(
24042435
descriptors,

0 commit comments

Comments
 (0)