@@ -896,42 +896,68 @@ impl InMemorySigner {
896
896
897
897
/// Returns the counterparty's pubkeys.
898
898
///
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
+
901
906
/// Returns the `contest_delay` value specified by our counterparty and applied on holder-broadcastable
902
907
/// transactions, i.e., the amount of time that we have to wait to recover our funds if we
903
908
/// broadcast a transaction.
904
909
///
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
+
907
917
/// Returns the `contest_delay` value specified by us and applied on transactions broadcastable
908
918
/// by our counterparty, i.e., the amount of time that they have to wait to recover their funds
909
919
/// if they broadcast a transaction.
910
920
///
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
+
913
927
/// Returns whether the holder is the initiator.
914
928
///
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
+
917
935
/// Funding outpoint
918
936
///
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
+
921
943
/// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
922
944
/// building transactions.
923
945
///
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 ( )
927
950
}
951
+
928
952
/// Returns the channel type features of the channel parameters. Should be helpful for
929
953
/// determining a channel's category, i. e. legacy/anchors/taproot/etc.
930
954
///
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 )
934
959
}
960
+
935
961
/// Sign the single input of `spend_tx` at index `input_idx`, which spends the output described
936
962
/// by `descriptor`, returning the witness stack for the input.
937
963
///
@@ -950,14 +976,20 @@ impl InMemorySigner {
950
976
if spend_tx. input [ input_idx] . previous_output != descriptor. outpoint . into_bitcoin_outpoint ( ) { return Err ( ( ) ) ; }
951
977
952
978
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 {
954
986
chan_utils:: get_to_countersignatory_with_anchors_redeemscript ( & remotepubkey. inner )
955
987
} else {
956
988
Script :: new_p2pkh ( & remotepubkey. pubkey_hash ( ) )
957
989
} ;
958
990
let sighash = hash_to_message ! ( & sighash:: SighashCache :: new( spend_tx) . segwit_signature_hash( input_idx, & witness_script, descriptor. output. value, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
959
991
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 {
961
993
witness_script. to_v0_p2wsh ( )
962
994
} else {
963
995
Script :: new_v0_p2wpkh ( & remotepubkey. wpubkey_hash ( ) . unwrap ( ) )
@@ -968,7 +1000,7 @@ impl InMemorySigner {
968
1000
let mut witness = Vec :: with_capacity ( 2 ) ;
969
1001
witness. push ( remotesig. serialize_der ( ) . to_vec ( ) ) ;
970
1002
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 {
972
1004
witness. push ( witness_script. to_bytes ( ) ) ;
973
1005
} else {
974
1006
witness. push ( remotepubkey. to_bytes ( ) ) ;
@@ -1052,24 +1084,30 @@ impl ChannelSigner for InMemorySigner {
1052
1084
}
1053
1085
}
1054
1086
1087
+ const MISSING_PARAMS_ERR : & ' static str = "ChannelSigner::provide_channel_parameters must be called before signing operations" ;
1088
+
1055
1089
impl EcdsaChannelSigner for InMemorySigner {
1056
1090
fn sign_counterparty_commitment ( & self , commitment_tx : & CommitmentTransaction , _preimages : Vec < PaymentPreimage > , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
1057
1091
let trusted_tx = commitment_tx. trust ( ) ;
1058
1092
let keys = trusted_tx. keys ( ) ;
1059
1093
1060
1094
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 ) ;
1062
1097
1063
1098
let built_tx = trusted_tx. built_transaction ( ) ;
1064
1099
let commitment_sig = built_tx. sign_counterparty_commitment ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) ;
1065
1100
let commitment_txid = built_tx. txid ;
1066
1101
1067
1102
let mut htlc_sigs = Vec :: with_capacity ( commitment_tx. htlcs ( ) . len ( ) ) ;
1068
1103
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 } ;
1073
1111
let htlc_sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & htlc_tx) . segwit_signature_hash( 0 , & htlc_redeemscript, htlc. amount_msat / 1000 , htlc_sighashtype) . unwrap( ) [ ..] ) ;
1074
1112
let holder_htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & keys. per_commitment_point , & self . htlc_base_key ) ;
1075
1113
htlc_sigs. push ( sign ( secp_ctx, & htlc_sighash, & holder_htlc_key) ) ;
@@ -1084,21 +1122,23 @@ impl EcdsaChannelSigner for InMemorySigner {
1084
1122
1085
1123
fn sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
1086
1124
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 ) ;
1088
1127
let trusted_tx = commitment_tx. trust ( ) ;
1089
1128
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 ) ;
1091
1130
let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
1092
1131
Ok ( ( sig, htlc_sigs) )
1093
1132
}
1094
1133
1095
1134
#[ cfg( any( test, feature = "unsafe_revoked_tx_signing" ) ) ]
1096
1135
fn unsafe_sign_holder_commitment_and_htlcs ( & self , commitment_tx : & HolderCommitmentTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < ( Signature , Vec < Signature > ) , ( ) > {
1097
1136
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 ) ;
1099
1139
let trusted_tx = commitment_tx. trust ( ) ;
1100
1140
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 ) ;
1102
1142
let htlc_sigs = trusted_tx. get_htlc_sigs ( & self . htlc_base_key , & channel_parameters. as_holder_broadcastable ( ) , & self , secp_ctx) ?;
1103
1143
Ok ( ( sig, htlc_sigs) )
1104
1144
}
@@ -1108,8 +1148,11 @@ impl EcdsaChannelSigner for InMemorySigner {
1108
1148
let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
1109
1149
let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
1110
1150
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)
1113
1156
} ;
1114
1157
let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
1115
1158
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 {
1121
1164
let per_commitment_point = PublicKey :: from_secret_key ( secp_ctx, & per_commitment_key) ;
1122
1165
let revocation_pubkey = chan_utils:: derive_public_revocation_key ( & secp_ctx, & per_commitment_point, & self . pubkeys ( ) . revocation_basepoint ) ;
1123
1166
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 ) ;
1125
1169
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)
1127
1172
} ;
1128
1173
let mut sighash_parts = sighash:: SighashCache :: new ( justice_tx) ;
1129
1174
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 {
1147
1192
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 , ( ) > {
1148
1193
let htlc_key = chan_utils:: derive_private_key ( & secp_ctx, & per_commitment_point, & self . htlc_base_key ) ;
1149
1194
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 ) ;
1151
1197
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) ;
1153
1200
let mut sighash_parts = sighash:: SighashCache :: new ( htlc_tx) ;
1154
1201
let sighash = hash_to_message ! ( & sighash_parts. segwit_signature_hash( input, & witness_script, amount, EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ;
1155
1202
Ok ( sign_with_aux_rand ( secp_ctx, & sighash, & htlc_key, & self ) )
1156
1203
}
1157
1204
1158
1205
fn sign_closing_transaction ( & self , closing_tx : & ClosingTransaction , secp_ctx : & Secp256k1 < secp256k1:: All > ) -> Result < Signature , ( ) > {
1159
1206
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) ;
1161
1209
Ok ( closing_tx. trust ( ) . sign ( & self . funding_key , & channel_funding_redeemscript, self . channel_value_satoshis , secp_ctx) )
1162
1210
}
1163
1211
0 commit comments