@@ -893,42 +893,61 @@ impl InMemorySigner {
893
893
894
894
/// Returns the counterparty's pubkeys.
895
895
///
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
+
898
902
/// Returns the `contest_delay` value specified by our counterparty and applied on holder-broadcastable
899
903
/// transactions, i.e., the amount of time that we have to wait to recover our funds if we
900
904
/// broadcast a transaction.
901
905
///
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
+
904
912
/// Returns the `contest_delay` value specified by us and applied on transactions broadcastable
905
913
/// by our counterparty, i.e., the amount of time that they have to wait to recover their funds
906
914
/// if they broadcast a transaction.
907
915
///
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
+
910
921
/// Returns whether the holder is the initiator.
911
922
///
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
+
914
928
/// Funding outpoint
915
929
///
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
+
918
935
/// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
919
936
/// building transactions.
920
937
///
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 ( )
924
941
}
942
+
925
943
/// Returns the channel type features of the channel parameters. Should be helpful for
926
944
/// determining a channel's category, i. e. legacy/anchors/taproot/etc.
927
945
///
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 )
931
949
}
950
+
932
951
/// Sign the single input of `spend_tx` at index `input_idx`, which spends the output described
933
952
/// by `descriptor`, returning the witness stack for the input.
934
953
///
@@ -949,8 +968,8 @@ impl InMemorySigner {
949
968
let remotepubkey = bitcoin:: PublicKey :: new ( self . pubkeys ( ) . payment_point ) ;
950
969
// We cannot always assume that `channel_parameters` is set, so can't just call
951
970
// `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 ( ) )
954
973
. unwrap_or ( false ) ;
955
974
956
975
let witness_script = if supports_anchors_zero_fee_htlc_tx {
@@ -1055,24 +1074,30 @@ impl ChannelSigner for InMemorySigner {
1055
1074
}
1056
1075
}
1057
1076
1077
+ const MISSING_PARAMS_ERR : & ' static str = "ChannelSigner::provide_channel_parameters must be called before signing operations" ;
1078
+
1058
1079
impl EcdsaChannelSigner for InMemorySigner {
1059
1080
fn sign_counterparty_commitment ( & self , commitment_tx : & CommitmentTransaction , _preimages : Vec < PaymentPreimage > , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
1060
1081
let trusted_tx = commitment_tx. trust ( ) ;
1061
1082
let keys = trusted_tx. keys ( ) ;
1062
1083
1063
1084
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 ) ;
1065
1087
1066
1088
let built_tx = trusted_tx. built_transaction ( ) ;
1067
1089
let commitment_sig = built_tx. sign_counterparty_commitment ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) ;
1068
1090
let commitment_txid = built_tx. txid ;
1069
1091
1070
1092
let mut htlc_sigs = Vec :: with_capacity ( commitment_tx. htlcs ( ) . len ( ) ) ;
1071
1093
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 } ;
1076
1101
let htlc_sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & htlc_tx) . segwit_signature_hash( 0 , & htlc_redeemscript, htlc. amount_msat / 1000 , htlc_sighashtype) . unwrap( ) [ ..] ) ;
1077
1102
let holder_htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & keys. per_commitment_point , & self . htlc_base_key ) ;
1078
1103
htlc_sigs. push ( sign ( secp_ctx, & htlc_sighash, & holder_htlc_key) ) ;
@@ -1087,21 +1112,23 @@ impl EcdsaChannelSigner for InMemorySigner {
1087
1112
1088
1113
fn sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
1089
1114
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 ) ;
1091
1117
let trusted_tx = commitment_tx. trust ( ) ;
1092
1118
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 ) ;
1094
1120
let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
1095
1121
Ok ( ( sig, htlc_sigs) )
1096
1122
}
1097
1123
1098
1124
#[ cfg( any( test, feature = "unsafe_revoked_tx_signing" ) ) ]
1099
1125
fn unsafe_sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
1100
1126
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 ) ;
1102
1129
let trusted_tx = commitment_tx. trust ( ) ;
1103
1130
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 ) ;
1105
1132
let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
1106
1133
Ok ( ( sig, htlc_sigs) )
1107
1134
}
@@ -1111,8 +1138,11 @@ impl EcdsaChannelSigner for InMemorySigner {
1111
1138
let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
1112
1139
let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
1113
1140
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)
1116
1146
} ;
1117
1147
let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
1118
1148
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 {
1124
1154
let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
1125
1155
let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
1126
1156
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 ) ;
1128
1159
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)
1130
1162
} ;
1131
1163
let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
1132
1164
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 {
1150
1182
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 , ( ) > {
1151
1183
let htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & per_commitment_point, & self . htlc_base_key ) ;
1152
1184
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 ) ;
1154
1187
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) ;
1156
1190
let mut sighash_parts = sighash:: SighashCache :: new ( htlc_tx) ;
1157
1191
let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
1158
1192
Ok ( sign_with_aux_rand ( secp_ctx, & sighash, & htlc_key, & self ) )
1159
1193
}
1160
1194
1161
1195
fn sign_closing_transaction ( & self , closing_tx : & ClosingTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < Signature , ( ) > {
1162
1196
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) ;
1164
1199
Ok ( closing_tx. trust ( ) . sign ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) )
1165
1200
}
1166
1201
0 commit comments