@@ -896,42 +896,68 @@ impl InMemorySigner {
896896
897897 /// Returns the counterparty's pubkeys.
898898 ///
899- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
900- pub fn counterparty_pubkeys ( & self ) -> & ChannelPublicKeys { & self . get_channel_parameters ( ) . counterparty_parameters . as_ref ( ) . unwrap ( ) . pubkeys }
899+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
900+ /// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
901+ pub fn counterparty_pubkeys ( & self ) -> Option < & ChannelPublicKeys > {
902+ self . get_channel_parameters ( )
903+ . and_then ( |params| params. counterparty_parameters . as_ref ( ) . map ( |params| & params. pubkeys ) )
904+ }
905+
901906 /// Returns the `contest_delay` value specified by our counterparty and applied on holder-broadcastable
902907 /// transactions, i.e., the amount of time that we have to wait to recover our funds if we
903908 /// broadcast a transaction.
904909 ///
905- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
906- pub fn counterparty_selected_contest_delay ( & self ) -> u16 { self . get_channel_parameters ( ) . counterparty_parameters . as_ref ( ) . unwrap ( ) . selected_contest_delay }
910+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
911+ /// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
912+ pub fn counterparty_selected_contest_delay ( & self ) -> Option < u16 > {
913+ self . get_channel_parameters ( )
914+ . and_then ( |params| params. counterparty_parameters . as_ref ( ) . map ( |params| params. selected_contest_delay ) )
915+ }
916+
907917 /// Returns the `contest_delay` value specified by us and applied on transactions broadcastable
908918 /// by our counterparty, i.e., the amount of time that they have to wait to recover their funds
909919 /// if they broadcast a transaction.
910920 ///
911- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
912- pub fn holder_selected_contest_delay ( & self ) -> u16 { self . get_channel_parameters ( ) . holder_selected_contest_delay }
921+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
922+ /// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
923+ pub fn holder_selected_contest_delay ( & self ) -> Option < u16 > {
924+ self . get_channel_parameters ( ) . map ( |params| params. holder_selected_contest_delay )
925+ }
926+
913927 /// Returns whether the holder is the initiator.
914928 ///
915- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
916- pub fn is_outbound ( & self ) -> bool { self . get_channel_parameters ( ) . is_outbound_from_holder }
929+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
930+ /// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
931+ pub fn is_outbound ( & self ) -> Option < bool > {
932+ self . get_channel_parameters ( ) . map ( |params| params. is_outbound_from_holder )
933+ }
934+
917935 /// Funding outpoint
918936 ///
919- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
920- pub fn funding_outpoint ( & self ) -> & OutPoint { self . get_channel_parameters ( ) . funding_outpoint . as_ref ( ) . unwrap ( ) }
937+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
938+ /// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
939+ pub fn funding_outpoint ( & self ) -> Option < & OutPoint > {
940+ self . get_channel_parameters ( ) . map ( |params| params. funding_outpoint . as_ref ( ) ) . flatten ( )
941+ }
942+
921943 /// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
922944 /// building transactions.
923945 ///
924- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
925- pub fn get_channel_parameters ( & self ) -> & ChannelTransactionParameters {
926- self . channel_parameters . as_ref ( ) . unwrap ( )
946+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
947+ /// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
948+ pub fn get_channel_parameters ( & self ) -> Option < & ChannelTransactionParameters > {
949+ self . channel_parameters . as_ref ( )
927950 }
951+
928952 /// Returns the channel type features of the channel parameters. Should be helpful for
929953 /// determining a channel's category, i. e. legacy/anchors/taproot/etc.
930954 ///
931- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
932- pub fn channel_type_features ( & self ) -> & ChannelTypeFeatures {
933- & self . get_channel_parameters ( ) . channel_type_features
955+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
956+ /// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
957+ pub fn channel_type_features ( & self ) -> Option < & ChannelTypeFeatures > {
958+ self . get_channel_parameters ( ) . map ( |params| & params. channel_type_features )
934959 }
960+
935961 /// Sign the single input of `spend_tx` at index `input_idx`, which spends the output described
936962 /// by `descriptor`, returning the witness stack for the input.
937963 ///
@@ -950,14 +976,20 @@ impl InMemorySigner {
950976 if spend_tx. input [ input_idx] . previous_output != descriptor. outpoint . into_bitcoin_outpoint ( ) { return Err ( ( ) ) ; }
951977
952978 let remotepubkey = bitcoin:: PublicKey :: new ( self . pubkeys ( ) . payment_point ) ;
953- let witness_script = if self . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) {
979+ // We cannot always assume that `channel_parameters` is set, so can't just call
980+ // `self.channel_parameters()` or anything that relies on it
981+ let supports_anchors_zero_fee_htlc_tx = self . channel_type_features ( )
982+ . map ( |features| features. supports_anchors_zero_fee_htlc_tx ( ) )
983+ . unwrap_or ( false ) ;
984+
985+ let witness_script = if supports_anchors_zero_fee_htlc_tx {
954986 chan_utils:: get_to_countersignatory_with_anchors_redeemscript ( & remotepubkey. inner )
955987 } else {
956988 Script :: new_p2pkh ( & remotepubkey. pubkey_hash ( ) )
957989 } ;
958990 let sighash = hash_to_message ! ( & sighash:: SighashCache :: new( spend_tx) . segwit_signature_hash( input_idx, & witness_script, descriptor. output. value, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
959991 let remotesig = sign_with_aux_rand ( secp_ctx, & sighash, & self . payment_key , & self ) ;
960- let payment_script = if self . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) {
992+ let payment_script = if supports_anchors_zero_fee_htlc_tx {
961993 witness_script. to_v0_p2wsh ( )
962994 } else {
963995 Script :: new_v0_p2wpkh ( & remotepubkey. wpubkey_hash ( ) . unwrap ( ) )
@@ -968,7 +1000,7 @@ impl InMemorySigner {
9681000 let mut witness = Vec :: with_capacity ( 2 ) ;
9691001 witness. push ( remotesig. serialize_der ( ) . to_vec ( ) ) ;
9701002 witness[ 0 ] . push ( EcdsaSighashType :: All as u8 ) ;
971- if self . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) {
1003+ if supports_anchors_zero_fee_htlc_tx {
9721004 witness. push ( witness_script. to_bytes ( ) ) ;
9731005 } else {
9741006 witness. push ( remotepubkey. to_bytes ( ) ) ;
@@ -1052,24 +1084,30 @@ impl ChannelSigner for InMemorySigner {
10521084 }
10531085}
10541086
1087+ const MISSING_PARAMS_ERR : & ' static str = "ChannelSigner::provide_channel_parameters must be called before signing operations" ;
1088+
10551089impl EcdsaChannelSigner for InMemorySigner {
10561090 fn sign_counterparty_commitment ( & self , commitment_tx : & CommitmentTransaction , _preimages : Vec < PaymentPreimage > , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
10571091 let trusted_tx = commitment_tx. trust ( ) ;
10581092 let keys = trusted_tx. keys ( ) ;
10591093
10601094 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1061- let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1095+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1096+ let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & counterparty_keys. funding_pubkey ) ;
10621097
10631098 let built_tx = trusted_tx. built_transaction ( ) ;
10641099 let commitment_sig = built_tx. sign_counterparty_commitment ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) ;
10651100 let commitment_txid = built_tx. txid ;
10661101
10671102 let mut htlc_sigs = Vec :: with_capacity ( commitment_tx. htlcs ( ) . len ( ) ) ;
10681103 for htlc in commitment_tx. htlcs ( ) {
1069- let channel_parameters = self . get_channel_parameters ( ) ;
1070- let htlc_tx = chan_utils:: build_htlc_transaction ( & commitment_txid, commitment_tx. feerate_per_kw ( ) , self . holder_selected_contest_delay ( ) , htlc, & channel_parameters. channel_type_features , & keys. broadcaster_delayed_payment_key , & keys. revocation_key ) ;
1071- let htlc_redeemscript = chan_utils:: get_htlc_redeemscript ( & htlc, self . channel_type_features ( ) , & keys) ;
1072- let htlc_sighashtype = if self . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) { EcdsaSighashType :: SinglePlusAnyoneCanPay } else { EcdsaSighashType :: All } ;
1104+ let channel_parameters = self . get_channel_parameters ( ) . expect ( MISSING_PARAMS_ERR ) ;
1105+ let holder_selected_contest_delay =
1106+ self . holder_selected_contest_delay ( ) . expect ( MISSING_PARAMS_ERR ) ;
1107+ let chan_type = & channel_parameters. channel_type_features ;
1108+ let htlc_tx = chan_utils:: build_htlc_transaction ( & commitment_txid, commitment_tx. feerate_per_kw ( ) , holder_selected_contest_delay, htlc, chan_type, & keys. broadcaster_delayed_payment_key , & keys. revocation_key ) ;
1109+ let htlc_redeemscript = chan_utils:: get_htlc_redeemscript ( & htlc, chan_type, & keys) ;
1110+ let htlc_sighashtype = if chan_type. supports_anchors_zero_fee_htlc_tx ( ) { EcdsaSighashType :: SinglePlusAnyoneCanPay } else { EcdsaSighashType :: All } ;
10731111 let htlc_sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & htlc_tx) . segwit_signature_hash( 0 , & htlc_redeemscript, htlc. amount_msat / 1000 , htlc_sighashtype) . unwrap( ) [ ..] ) ;
10741112 let holder_htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & keys. per_commitment_point , & self . htlc_base_key ) ;
10751113 htlc_sigs. push ( sign ( secp_ctx, & htlc_sighash, & holder_htlc_key) ) ;
@@ -1084,21 +1122,23 @@ impl EcdsaChannelSigner for InMemorySigner {
10841122
10851123 fn sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
10861124 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1087- let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1125+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1126+ let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & counterparty_keys. funding_pubkey ) ;
10881127 let trusted_tx = commitment_tx. trust ( ) ;
10891128 let sig = trusted_tx. built_transaction ( ) . sign_holder_commitment ( & self . funding_key , & funding_redeemscript, self . channel_value_satoshis , & self , secp_ctx) ;
1090- let channel_parameters = self . get_channel_parameters ( ) ;
1129+ let channel_parameters = self . get_channel_parameters ( ) . expect ( MISSING_PARAMS_ERR ) ;
10911130 let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
10921131 Ok ( ( sig, htlc_sigs) )
10931132 }
10941133
10951134 #[ cfg( any( test, feature = "unsafe_revoked_tx_signing" ) ) ]
10961135 fn unsafe_sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
10971136 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1098- let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1137+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1138+ let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & counterparty_keys. funding_pubkey ) ;
10991139 let trusted_tx = commitment_tx. trust ( ) ;
11001140 let sig = trusted_tx. built_transaction ( ) . sign_holder_commitment ( & self . funding_key , & funding_redeemscript, self . channel_value_satoshis , & self , secp_ctx) ;
1101- let channel_parameters = self . get_channel_parameters ( ) ;
1141+ let channel_parameters = self . get_channel_parameters ( ) . expect ( MISSING_PARAMS_ERR ) ;
11021142 let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
11031143 Ok ( ( sig, htlc_sigs) )
11041144 }
@@ -1108,8 +1148,11 @@ impl EcdsaChannelSigner for InMemorySigner {
11081148 let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
11091149 let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
11101150 let witness_script = {
1111- let counterparty_delayedpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . counterparty_pubkeys ( ) . delayed_payment_basepoint ) ;
1112- chan_utils:: get_revokeable_redeemscript ( & revocation_pubkey, self . holder_selected_contest_delay ( ) , & counterparty_delayedpubkey)
1151+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1152+ let holder_selected_contest_delay =
1153+ self . holder_selected_contest_delay ( ) . expect ( MISSING_PARAMS_ERR ) ;
1154+ let counterparty_delayedpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & counterparty_keys. delayed_payment_basepoint ) ;
1155+ chan_utils:: get_revokeable_redeemscript ( & revocation_pubkey, holder_selected_contest_delay, & counterparty_delayedpubkey)
11131156 } ;
11141157 let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
11151158 let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
@@ -1121,9 +1164,11 @@ impl EcdsaChannelSigner for InMemorySigner {
11211164 let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
11221165 let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
11231166 let witness_script = {
1124- let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . counterparty_pubkeys ( ) . htlc_basepoint ) ;
1167+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1168+ let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & counterparty_keys. htlc_basepoint ) ;
11251169 let holder_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . htlc_basepoint ) ;
1126- chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, self . channel_type_features ( ) , & counterparty_htlcpubkey, & holder_htlcpubkey, & revocation_pubkey)
1170+ let chan_type = self . channel_type_features ( ) . expect ( MISSING_PARAMS_ERR ) ;
1171+ chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, chan_type, & counterparty_htlcpubkey, & holder_htlcpubkey, & revocation_pubkey)
11271172 } ;
11281173 let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
11291174 let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
@@ -1147,17 +1192,20 @@ impl EcdsaChannelSigner for InMemorySigner {
11471192 fn sign_counterparty_htlc_transaction ( & self , htlc_tx : & Transaction , input : usize , amount : u64 , per_commitment_point : & PublicKey , htlc : & HTLCOutputInCommitment , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < Signature , ( ) > {
11481193 let htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & per_commitment_point, & self . htlc_base_key ) ;
11491194 let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
1150- let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . counterparty_pubkeys ( ) . htlc_basepoint ) ;
1195+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1196+ let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & counterparty_keys. htlc_basepoint ) ;
11511197 let htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . htlc_basepoint ) ;
1152- let witness_script = chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, self . channel_type_features ( ) , & counterparty_htlcpubkey, & htlcpubkey, & revocation_pubkey) ;
1198+ let chan_type = self . channel_type_features ( ) . expect ( MISSING_PARAMS_ERR ) ;
1199+ let witness_script = chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, chan_type, & counterparty_htlcpubkey, & htlcpubkey, & revocation_pubkey) ;
11531200 let mut sighash_parts = sighash:: SighashCache :: new ( htlc_tx) ;
11541201 let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
11551202 Ok ( sign_with_aux_rand ( secp_ctx, & sighash, & htlc_key, & self ) )
11561203 }
11571204
11581205 fn sign_closing_transaction ( & self , closing_tx : & ClosingTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < Signature , ( ) > {
11591206 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1160- let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1207+ let counterparty_funding_key = & self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) . funding_pubkey ;
1208+ let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, counterparty_funding_key) ;
11611209 Ok ( closing_tx. trust ( ) . sign ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) )
11621210 }
11631211
0 commit comments