@@ -893,42 +893,61 @@ impl InMemorySigner {
893893
894894 /// Returns the counterparty's pubkeys.
895895 ///
896- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
897- pub fn counterparty_pubkeys ( & self ) -> & ChannelPublicKeys { & self . get_channel_parameters ( ) . counterparty_parameters . as_ref ( ) . unwrap ( ) . pubkeys }
896+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
897+ pub fn counterparty_pubkeys ( & self ) -> Option < & ChannelPublicKeys > {
898+ self . get_channel_parameters ( )
899+ . and_then ( |params| params. counterparty_parameters . as_ref ( ) . map ( |params| & params. pubkeys ) )
900+ }
901+
898902 /// Returns the `contest_delay` value specified by our counterparty and applied on holder-broadcastable
899903 /// transactions, i.e., the amount of time that we have to wait to recover our funds if we
900904 /// broadcast a transaction.
901905 ///
902- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
903- pub fn counterparty_selected_contest_delay ( & self ) -> u16 { self . get_channel_parameters ( ) . counterparty_parameters . as_ref ( ) . unwrap ( ) . selected_contest_delay }
906+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
907+ pub fn counterparty_selected_contest_delay ( & self ) -> Option < u16 > {
908+ self . get_channel_parameters ( )
909+ . and_then ( |params| params. counterparty_parameters . as_ref ( ) . map ( |params| params. selected_contest_delay ) )
910+ }
911+
904912 /// Returns the `contest_delay` value specified by us and applied on transactions broadcastable
905913 /// by our counterparty, i.e., the amount of time that they have to wait to recover their funds
906914 /// if they broadcast a transaction.
907915 ///
908- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
909- pub fn holder_selected_contest_delay ( & self ) -> u16 { self . get_channel_parameters ( ) . holder_selected_contest_delay }
916+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
917+ pub fn holder_selected_contest_delay ( & self ) -> Option < u16 > {
918+ self . get_channel_parameters ( ) . map ( |params| params. holder_selected_contest_delay )
919+ }
920+
910921 /// Returns whether the holder is the initiator.
911922 ///
912- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
913- pub fn is_outbound ( & self ) -> bool { self . get_channel_parameters ( ) . is_outbound_from_holder }
923+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
924+ pub fn is_outbound ( & self ) -> Option < bool > {
925+ self . get_channel_parameters ( ) . map ( |params| params. is_outbound_from_holder )
926+ }
927+
914928 /// Funding outpoint
915929 ///
916- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
917- pub fn funding_outpoint ( & self ) -> & OutPoint { self . get_channel_parameters ( ) . funding_outpoint . as_ref ( ) . unwrap ( ) }
930+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
931+ pub fn funding_outpoint ( & self ) -> Option < & OutPoint > {
932+ self . get_channel_parameters ( ) . map ( |params| params. funding_outpoint . as_ref ( ) ) . flatten ( )
933+ }
934+
918935 /// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
919936 /// building transactions.
920937 ///
921- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before .
922- pub fn get_channel_parameters ( & self ) -> & ChannelTransactionParameters {
923- self . channel_parameters . as_ref ( ) . unwrap ( )
938+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
939+ pub fn get_channel_parameters ( & self ) -> Option < & ChannelTransactionParameters > {
940+ self . channel_parameters . as_ref ( )
924941 }
942+
925943 /// Returns the channel type features of the channel parameters. Should be helpful for
926944 /// determining a channel's category, i. e. legacy/anchors/taproot/etc.
927945 ///
928- /// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before .
929- pub fn channel_type_features ( & self ) -> & ChannelTypeFeatures {
930- & self . get_channel_parameters ( ) . channel_type_features
946+ /// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
947+ pub fn channel_type_features ( & self ) -> Option < & ChannelTypeFeatures > {
948+ self . get_channel_parameters ( ) . map ( |params| & params . channel_type_features )
931949 }
950+
932951 /// Sign the single input of `spend_tx` at index `input_idx`, which spends the output described
933952 /// by `descriptor`, returning the witness stack for the input.
934953 ///
@@ -949,8 +968,8 @@ impl InMemorySigner {
949968 let remotepubkey = bitcoin:: PublicKey :: new ( self . pubkeys ( ) . payment_point ) ;
950969 // We cannot always assume that `channel_parameters` is set, so can't just call
951970 // `self.channel_parameters()` or anything that relies on it
952- let supports_anchors_zero_fee_htlc_tx = self . channel_parameters . as_ref ( )
953- . map ( |params| params . channel_type_features . supports_anchors_zero_fee_htlc_tx ( ) )
971+ let supports_anchors_zero_fee_htlc_tx = self . channel_type_features ( )
972+ . map ( |features| features . supports_anchors_zero_fee_htlc_tx ( ) )
954973 . unwrap_or ( false ) ;
955974
956975 let witness_script = if supports_anchors_zero_fee_htlc_tx {
@@ -1055,24 +1074,30 @@ impl ChannelSigner for InMemorySigner {
10551074 }
10561075}
10571076
1077+ const MISSING_PARAMS_ERR : & ' static str = "ChannelSigner::provide_channel_parameters must be called before signing operations" ;
1078+
10581079impl EcdsaChannelSigner for InMemorySigner {
10591080 fn sign_counterparty_commitment ( & self , commitment_tx : & CommitmentTransaction , _preimages : Vec < PaymentPreimage > , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
10601081 let trusted_tx = commitment_tx. trust ( ) ;
10611082 let keys = trusted_tx. keys ( ) ;
10621083
10631084 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1064- let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1085+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1086+ let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & counterparty_keys. funding_pubkey ) ;
10651087
10661088 let built_tx = trusted_tx. built_transaction ( ) ;
10671089 let commitment_sig = built_tx. sign_counterparty_commitment ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) ;
10681090 let commitment_txid = built_tx. txid ;
10691091
10701092 let mut htlc_sigs = Vec :: with_capacity ( commitment_tx. htlcs ( ) . len ( ) ) ;
10711093 for htlc in commitment_tx. htlcs ( ) {
1072- let channel_parameters = self . get_channel_parameters ( ) ;
1073- 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 ) ;
1074- let htlc_redeemscript = chan_utils:: get_htlc_redeemscript ( & htlc, self . channel_type_features ( ) , & keys) ;
1075- let htlc_sighashtype = if self . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) { EcdsaSighashType :: SinglePlusAnyoneCanPay } else { EcdsaSighashType :: All } ;
1094+ let channel_parameters = self . get_channel_parameters ( ) . expect ( MISSING_PARAMS_ERR ) ;
1095+ let holder_selected_contest_delay =
1096+ self . holder_selected_contest_delay ( ) . expect ( MISSING_PARAMS_ERR ) ;
1097+ let chan_type = & channel_parameters. channel_type_features ;
1098+ 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 ) ;
1099+ let htlc_redeemscript = chan_utils:: get_htlc_redeemscript ( & htlc, chan_type, & keys) ;
1100+ let htlc_sighashtype = if chan_type. supports_anchors_zero_fee_htlc_tx ( ) { EcdsaSighashType :: SinglePlusAnyoneCanPay } else { EcdsaSighashType :: All } ;
10761101 let htlc_sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & htlc_tx) . segwit_signature_hash( 0 , & htlc_redeemscript, htlc. amount_msat / 1000 , htlc_sighashtype) . unwrap( ) [ ..] ) ;
10771102 let holder_htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & keys. per_commitment_point , & self . htlc_base_key ) ;
10781103 htlc_sigs. push ( sign ( secp_ctx, & htlc_sighash, & holder_htlc_key) ) ;
@@ -1087,21 +1112,23 @@ impl EcdsaChannelSigner for InMemorySigner {
10871112
10881113 fn sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
10891114 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1090- let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1115+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1116+ let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & counterparty_keys. funding_pubkey ) ;
10911117 let trusted_tx = commitment_tx. trust ( ) ;
10921118 let sig = trusted_tx. built_transaction ( ) . sign_holder_commitment ( & self . funding_key , & funding_redeemscript, self . channel_value_satoshis , & self , secp_ctx) ;
1093- let channel_parameters = self . get_channel_parameters ( ) ;
1119+ let channel_parameters = self . get_channel_parameters ( ) . expect ( MISSING_PARAMS_ERR ) ;
10941120 let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
10951121 Ok ( ( sig, htlc_sigs) )
10961122 }
10971123
10981124 #[ cfg( any( test, feature = "unsafe_revoked_tx_signing" ) ) ]
10991125 fn unsafe_sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
11001126 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1101- let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1127+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1128+ let funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & counterparty_keys. funding_pubkey ) ;
11021129 let trusted_tx = commitment_tx. trust ( ) ;
11031130 let sig = trusted_tx. built_transaction ( ) . sign_holder_commitment ( & self . funding_key , & funding_redeemscript, self . channel_value_satoshis , & self , secp_ctx) ;
1104- let channel_parameters = self . get_channel_parameters ( ) ;
1131+ let channel_parameters = self . get_channel_parameters ( ) . expect ( MISSING_PARAMS_ERR ) ;
11051132 let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
11061133 Ok ( ( sig, htlc_sigs) )
11071134 }
@@ -1111,8 +1138,11 @@ impl EcdsaChannelSigner for InMemorySigner {
11111138 let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
11121139 let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
11131140 let witness_script = {
1114- let counterparty_delayedpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . counterparty_pubkeys ( ) . delayed_payment_basepoint ) ;
1115- chan_utils:: get_revokeable_redeemscript ( & revocation_pubkey, self . holder_selected_contest_delay ( ) , & counterparty_delayedpubkey)
1141+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1142+ let holder_selected_contest_delay =
1143+ self . holder_selected_contest_delay ( ) . expect ( MISSING_PARAMS_ERR ) ;
1144+ let counterparty_delayedpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & counterparty_keys. delayed_payment_basepoint ) ;
1145+ chan_utils:: get_revokeable_redeemscript ( & revocation_pubkey, holder_selected_contest_delay, & counterparty_delayedpubkey)
11161146 } ;
11171147 let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
11181148 let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
@@ -1124,9 +1154,11 @@ impl EcdsaChannelSigner for InMemorySigner {
11241154 let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
11251155 let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
11261156 let witness_script = {
1127- let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . counterparty_pubkeys ( ) . htlc_basepoint ) ;
1157+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1158+ let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & counterparty_keys. htlc_basepoint ) ;
11281159 let holder_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . htlc_basepoint ) ;
1129- chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, self . channel_type_features ( ) , & counterparty_htlcpubkey, & holder_htlcpubkey, & revocation_pubkey)
1160+ let chan_type = self . channel_type_features ( ) . expect ( MISSING_PARAMS_ERR ) ;
1161+ chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, chan_type, & counterparty_htlcpubkey, & holder_htlcpubkey, & revocation_pubkey)
11301162 } ;
11311163 let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
11321164 let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
@@ -1150,17 +1182,20 @@ impl EcdsaChannelSigner for InMemorySigner {
11501182 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 , ( ) > {
11511183 let htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & per_commitment_point, & self . htlc_base_key ) ;
11521184 let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
1153- let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . counterparty_pubkeys ( ) . htlc_basepoint ) ;
1185+ let counterparty_keys = self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) ;
1186+ let counterparty_htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & counterparty_keys. htlc_basepoint ) ;
11541187 let htlcpubkey = chan_utils:: derive_public_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . htlc_basepoint ) ;
1155- let witness_script = chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, self . channel_type_features ( ) , & counterparty_htlcpubkey, & htlcpubkey, & revocation_pubkey) ;
1188+ let chan_type = self . channel_type_features ( ) . expect ( MISSING_PARAMS_ERR ) ;
1189+ let witness_script = chan_utils:: get_htlc_redeemscript_with_explicit_keys ( & htlc, chan_type, & counterparty_htlcpubkey, & htlcpubkey, & revocation_pubkey) ;
11561190 let mut sighash_parts = sighash:: SighashCache :: new ( htlc_tx) ;
11571191 let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
11581192 Ok ( sign_with_aux_rand ( secp_ctx, & sighash, & htlc_key, & self ) )
11591193 }
11601194
11611195 fn sign_closing_transaction ( & self , closing_tx : & ClosingTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < Signature , ( ) > {
11621196 let funding_pubkey = PublicKey :: from_secret_key ( secp_ctx, & self . funding_key ) ;
1163- let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, & self . counterparty_pubkeys ( ) . funding_pubkey ) ;
1197+ let counterparty_funding_key = & self . counterparty_pubkeys ( ) . expect ( MISSING_PARAMS_ERR ) . funding_pubkey ;
1198+ let channel_funding_redeemscript = make_funding_redeemscript ( & funding_pubkey, counterparty_funding_key) ;
11641199 Ok ( closing_tx. trust ( ) . sign ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) )
11651200 }
11661201
0 commit comments