@@ -1160,88 +1160,96 @@ mod test {
11601160 assert_eq ! ( psbt_input. bip32_derivation. len( ) , 2 , "Unexpected number of bip32_derivation" ) ;
11611161 }
11621162
1163- #[ test]
1164- fn test_plan_satisfy_wsh ( ) {
1163+ fn test_plan_satisfy (
1164+ desc_str_fn : fn ( & [ bitcoin:: PublicKey ] ) -> String ,
1165+ exp_witness_len : usize ,
1166+ ) -> Vec < Vec < u8 > > {
11651167 use std:: collections:: BTreeMap ;
11661168
11671169 use bitcoin:: secp256k1:: { self , Secp256k1 } ;
11681170
11691171 let secp = Secp256k1 :: new ( ) ;
11701172
1171- let sk =
1172- secp256k1:: SecretKey :: from_slice ( & b"sally was a secret key, she said" [ ..] ) . unwrap ( ) ;
1173- let pk = bitcoin:: PublicKey :: new ( secp256k1:: PublicKey :: from_secret_key ( & secp, & sk) ) ;
1173+ let ( sks, pks) : ( Vec < _ > , Vec < _ > ) = [
1174+ & b"sally was a secret key, she said" [ ..] ,
1175+ & b"polly was a secret key, she said" [ ..] ,
1176+ & b"bonny was a secret key, she said" [ ..] ,
1177+ ]
1178+ . iter ( )
1179+ . map ( |d| {
1180+ let sk = secp256k1:: SecretKey :: from_slice ( d) . unwrap ( ) ;
1181+ let pk = bitcoin:: PublicKey :: new ( secp256k1:: PublicKey :: from_secret_key ( & secp, & sk) ) ;
1182+ ( sk, pk)
1183+ } )
1184+ . unzip ( ) ;
11741185
1175- let desc =
1176- Descriptor :: < DefiniteDescriptorKey > :: from_str ( & format ! ( "wsh(pk({}))" , pk) ) . unwrap ( ) ;
1186+ let desc = Descriptor :: < DefiniteDescriptorKey > :: from_str ( & desc_str_fn ( & pks) ) . unwrap ( ) ;
11771187
1178- let sighash =
1179- secp256k1:: Message :: from_digest_slice ( & b"michael was a message, amusingly" [ ..] )
1180- . expect ( "32 bytes" ) ;
1181- let ecdsa_sig = bitcoin:: ecdsa:: Signature {
1182- signature : secp. sign_ecdsa ( & sighash, & sk) ,
1183- sighash_type : bitcoin:: sighash:: EcdsaSighashType :: All ,
1184- } ;
1188+ let sigs = sks
1189+ . iter ( )
1190+ . map ( |sk| {
1191+ let sighash =
1192+ secp256k1:: Message :: from_digest_slice ( & b"michael was a message, amusingly" [ ..] )
1193+ . expect ( "32 bytes" ) ;
1194+ bitcoin:: ecdsa:: Signature {
1195+ signature : secp. sign_ecdsa ( & sighash, sk) ,
1196+ sighash_type : bitcoin:: sighash:: EcdsaSighashType :: All ,
1197+ }
1198+ } )
1199+ . collect :: < Vec < _ > > ( ) ;
11851200
11861201 // This witness script should exist in the witness stack returned by `Plan::satisfy`.
1187- let exp_witness_script = desc. explicit_script ( ) . expect ( "wsh has explicit script" ) ;
1202+ let exp_witness_script = desc. explicit_script ( ) . expect ( "has explicit script" ) ;
1203+ let exp_script_sig = desc. unsigned_script_sig ( ) ;
11881204
11891205 let mut satisfier = BTreeMap :: < DefiniteDescriptorKey , bitcoin:: ecdsa:: Signature > :: new ( ) ;
1190- satisfier. insert ( DefiniteDescriptorKey :: from_str ( & pk. to_string ( ) ) . unwrap ( ) , ecdsa_sig) ;
1206+ let mut assets = Assets :: new ( ) ;
1207+ for ( i, pk) in pks. iter ( ) . enumerate ( ) {
1208+ satisfier. insert ( DefiniteDescriptorKey :: from_str ( & pk. to_string ( ) ) . unwrap ( ) , sigs[ i] ) ;
1209+ assets = assets. add ( DescriptorPublicKey :: from_str ( & pk. to_string ( ) ) . unwrap ( ) ) ;
1210+ }
11911211
1192- let assets = Assets :: new ( ) . add ( DescriptorPublicKey :: from_str ( & pk. to_string ( ) ) . unwrap ( ) ) ;
11931212 let plan = desc. plan ( & assets) . expect ( "plan should succeed" ) ;
11941213
11951214 let ( witness, script_sig) = plan. satisfy ( & satisfier) . expect ( "satisfy should succeed" ) ;
1215+ assert_eq ! ( witness. last( ) . unwrap( ) , & exp_witness_script. into_bytes( ) ) ;
1216+ assert_eq ! ( script_sig, exp_script_sig) ;
1217+ assert_eq ! ( witness. len( ) , exp_witness_len) ;
11961218
1219+ witness
1220+ }
1221+
1222+ #[ test]
1223+ fn test_plan_satisfy_wsh ( ) {
11971224 // For native P2WSH:
11981225 // - script_sig should be empty
11991226 // - witness should contain [signature, witness_script]
1200- assert_eq ! ( script_sig, ScriptBuf :: new( ) ) ;
1201- assert_eq ! ( witness. len( ) , 2 ) ;
1202- assert_eq ! ( witness. last( ) . unwrap( ) , & exp_witness_script. into_bytes( ) ) ;
1227+ test_plan_satisfy ( |pks| format ! ( "wsh(pk({}))" , pks[ 0 ] ) , 2 ) ;
12031228 }
12041229
12051230 #[ test]
12061231 fn test_plan_satisfy_sh_wsh ( ) {
1207- use std:: collections:: BTreeMap ;
1208-
1209- use bitcoin:: secp256k1:: { self , Secp256k1 } ;
1210-
1211- let secp = Secp256k1 :: new ( ) ;
1212- let sk =
1213- secp256k1:: SecretKey :: from_slice ( & b"sally was a secret key, she said" [ ..] ) . unwrap ( ) ;
1214- let pk = bitcoin:: PublicKey :: new ( secp256k1:: PublicKey :: from_secret_key ( & secp, & sk) ) ;
1215-
1216- let desc =
1217- Descriptor :: < DefiniteDescriptorKey > :: from_str ( & format ! ( "sh(wsh(pk({})))" , pk) ) . unwrap ( ) ;
1218-
1219- let sighash =
1220- secp256k1:: Message :: from_digest_slice ( & b"michael was a message, amusingly" [ ..] )
1221- . expect ( "32 bytes" ) ;
1222- let ecdsa_sig = bitcoin:: ecdsa:: Signature {
1223- signature : secp. sign_ecdsa ( & sighash, & sk) ,
1224- sighash_type : bitcoin:: sighash:: EcdsaSighashType :: All ,
1225- } ;
1226-
1227- // Get expected values before plan() consumes the descriptor.
1228- let exp_witness_script = desc. explicit_script ( ) . expect ( "sh-wsh has explicit script" ) ;
1229- let exp_script_sig = desc. unsigned_script_sig ( ) ;
1230-
1231- let mut satisfier: BTreeMap < DefiniteDescriptorKey , bitcoin:: ecdsa:: Signature > =
1232- BTreeMap :: new ( ) ;
1233- satisfier. insert ( DefiniteDescriptorKey :: from_str ( & pk. to_string ( ) ) . unwrap ( ) , ecdsa_sig) ;
1234-
1235- let assets = Assets :: new ( ) . add ( DescriptorPublicKey :: from_str ( & pk. to_string ( ) ) . unwrap ( ) ) ;
1236- let plan = desc. plan ( & assets) . expect ( "plan should succeed" ) ;
1237-
1238- let ( witness, script_sig) = plan. satisfy ( & satisfier) . expect ( "satisfy should succeed" ) ;
1239-
12401232 // For P2SH-P2WSH:
12411233 // - script_sig should be the unsigned_script_sig (pushes the P2WSH redeemScript)
12421234 // - witness should contain [signature, witness_script]
1243- assert_eq ! ( script_sig, exp_script_sig) ;
1244- assert_eq ! ( witness. len( ) , 2 ) ;
1245- assert_eq ! ( witness. last( ) . unwrap( ) , & exp_witness_script. into_bytes( ) ) ;
1235+ test_plan_satisfy ( |pks| format ! ( "sh(wsh(pk({})))" , pks[ 0 ] ) , 2 ) ;
1236+ }
1237+
1238+ #[ test]
1239+ fn test_plan_satisfy_sortedmulti ( ) {
1240+ // For native P2WSH with sortedmulti:
1241+ // - script_sig should be empty
1242+ // - witness should contain [sig1, sig2, sig3, witness_script]
1243+ // - witness should be the same no matter the order of the keys
1244+ assert_eq ! (
1245+ test_plan_satisfy(
1246+ |pks| format!( "wsh(sortedmulti(2,{},{},{}))" , pks[ 0 ] , pks[ 1 ] , pks[ 2 ] ) ,
1247+ 4
1248+ ) ,
1249+ test_plan_satisfy(
1250+ |pks| format!( "wsh(sortedmulti(2,{},{},{}))" , pks[ 1 ] , pks[ 2 ] , pks[ 0 ] ) ,
1251+ 4
1252+ )
1253+ ) ;
12461254 }
12471255}
0 commit comments