@@ -374,6 +374,8 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
374
374
Some ( tree) => tree,
375
375
} ;
376
376
377
+ // TODO: Max weight calculation for Simplicity policies
378
+
377
379
tree. iter ( )
378
380
. filter_map ( |( depth, ms) | {
379
381
let script_size = ms. script_size ( ) ;
@@ -820,54 +822,102 @@ where
820
822
S : Satisfier < Pk > ,
821
823
Ext : ParseableExt ,
822
824
{
823
- let spend_info = desc. spend_info ( ) ;
824
825
// First try the key spend path
825
826
if let Some ( sig) = satisfier. lookup_tap_key_spend_sig ( ) {
826
827
Ok ( ( vec ! [ sig. to_vec( ) ] , Script :: new ( ) ) )
827
828
} else {
828
- // Since we have the complete descriptor we can ignore the satisfier. We don't use the control block
829
- // map (lookup_control_block) from the satisfier here.
830
- let ( mut min_wit, mut min_wit_len) = ( None , None ) ;
831
- for ( depth, ms) in desc. iter_scripts ( ) {
832
- let mut wit = if allow_mall {
833
- match ms. satisfy_malleable ( & satisfier) {
834
- Ok ( wit) => wit,
835
- Err ( ..) => continue , // No witness for this script in tr descriptor, look for next one
836
- }
837
- } else {
838
- match ms. satisfy ( & satisfier) {
839
- Ok ( wit) => wit,
840
- Err ( ..) => continue , // No witness for this script in tr descriptor, look for next one
841
- }
842
- } ;
843
- // Compute the final witness size
844
- // Control block len + script len + witnesssize + varint(wit.len + 2)
845
- // The extra +2 elements are control block and script itself
846
- let wit_size = witness_size ( & wit)
847
- + control_block_len ( depth)
848
- + ms. script_size ( )
849
- + varint_len ( ms. script_size ( ) ) ;
850
- if min_wit_len. is_some ( ) && Some ( wit_size) > min_wit_len {
851
- continue ;
852
- } else {
853
- let leaf_script = ( ms. encode ( ) , LeafVersion :: default ( ) ) ;
854
- let control_block = spend_info
855
- . control_block ( & leaf_script)
856
- . expect ( "Control block must exist in script map for every known leaf" ) ;
857
- wit. push ( leaf_script. 0 . into_bytes ( ) ) ; // Push the leaf script
858
- // There can be multiple control blocks for a (script, ver) pair
859
- // Find the smallest one amongst those
860
- wit. push ( control_block. serialize ( ) ) ;
861
- // Finally, save the minimum
862
- min_wit = Some ( wit) ;
863
- min_wit_len = Some ( wit_size) ;
864
- }
829
+ if desc. get_simplicity ( ) . is_some ( ) {
830
+ best_simplicity_spend ( desc, satisfier)
831
+ } else {
832
+ best_miniscript_spend ( desc, satisfier, allow_mall)
865
833
}
866
- match min_wit {
867
- Some ( wit) => Ok ( ( wit, Script :: new ( ) ) ) ,
868
- None => Err ( Error :: CouldNotSatisfy ) , // Could not satisfy all miniscripts inside Tr
834
+ }
835
+ }
836
+
837
+ fn best_miniscript_spend < Pk , S , Ext > (
838
+ desc : & Tr < Pk , Ext > ,
839
+ satisfier : S ,
840
+ allow_mall : bool ,
841
+ ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
842
+ where
843
+ Pk : ToPublicKey ,
844
+ S : Satisfier < Pk > ,
845
+ Ext : ParseableExt ,
846
+ {
847
+ // Since we have the complete descriptor we can ignore the satisfier. We don't use the control block
848
+ // map (lookup_control_block) from the satisfier here.
849
+ let ( mut min_wit, mut min_wit_len) = ( None , None ) ;
850
+ for ( depth, ms) in desc. iter_scripts ( ) {
851
+ let mut wit = if allow_mall {
852
+ match ms. satisfy_malleable ( & satisfier) {
853
+ Ok ( wit) => wit,
854
+ Err ( ..) => continue , // No witness for this script in tr descriptor, look for next one
855
+ }
856
+ } else {
857
+ match ms. satisfy ( & satisfier) {
858
+ Ok ( wit) => wit,
859
+ Err ( ..) => continue , // No witness for this script in tr descriptor, look for next one
860
+ }
861
+ } ;
862
+ // Compute the final witness size
863
+ // Control block len + script len + witnesssize + varint(wit.len + 2)
864
+ // The extra +2 elements are control block and script itself
865
+ let wit_size = witness_size ( & wit)
866
+ + control_block_len ( depth)
867
+ + ms. script_size ( )
868
+ + varint_len ( ms. script_size ( ) ) ;
869
+ if min_wit_len. is_some ( ) && Some ( wit_size) > min_wit_len {
870
+ continue ;
871
+ } else {
872
+ let leaf_script = ( ms. encode ( ) , LeafVersion :: default ( ) ) ;
873
+ let control_block = desc
874
+ . spend_info ( )
875
+ . control_block ( & leaf_script)
876
+ . expect ( "Control block must exist in script map for every known leaf" ) ;
877
+ wit. push ( leaf_script. 0 . into_bytes ( ) ) ; // Push the leaf script
878
+ // There can be multiple control blocks for a (script, ver) pair
879
+ // Find the smallest one amongst those
880
+ wit. push ( control_block. serialize ( ) ) ;
881
+ // Finally, save the minimum
882
+ min_wit = Some ( wit) ;
883
+ min_wit_len = Some ( wit_size) ;
869
884
}
870
885
}
886
+ match min_wit {
887
+ Some ( wit) => Ok ( ( wit, Script :: new ( ) ) ) ,
888
+ None => Err ( Error :: CouldNotSatisfy ) , // Could not satisfy all miniscripts inside Tr
889
+ }
890
+ }
891
+
892
+ fn best_simplicity_spend < Pk , S , Ext > (
893
+ desc : & Tr < Pk , Ext > ,
894
+ satisfier : S ,
895
+ ) -> Result < ( Vec < Vec < u8 > > , Script ) , Error >
896
+ where
897
+ Pk : ToPublicKey ,
898
+ S : Satisfier < Pk > ,
899
+ Ext : ParseableExt ,
900
+ {
901
+ let policy = desc. get_simplicity ( ) . ok_or ( Error :: CouldNotSatisfy ) ?;
902
+ let satisfier = crate :: simplicity:: SatisfierWrapper :: new ( satisfier) ;
903
+ let program = policy. satisfy ( & satisfier) . map_err ( |_| Error :: CouldNotSatisfy ) ?;
904
+
905
+ let program_and_witness_bytes = program. encode_to_vec ( ) ;
906
+ let cmr_bytes = Vec :: from ( program. cmr ( ) . as_ref ( ) ) ;
907
+
908
+ let script = elements:: Script :: from ( program. cmr ( ) . as_ref ( ) . to_vec ( ) ) ;
909
+ let script_ver = ( script, simplicity:: leaf_version ( ) ) ;
910
+ let control_block = desc
911
+ . spend_info ( )
912
+ . control_block ( & script_ver)
913
+ . expect ( "Control block must exist in script map for every known leaf" ) ;
914
+
915
+ let witness = vec ! [
916
+ program_and_witness_bytes,
917
+ cmr_bytes,
918
+ control_block. serialize( ) ,
919
+ ] ;
920
+ Ok ( ( witness, Script :: new ( ) ) )
871
921
}
872
922
873
923
#[ cfg( test) ]
0 commit comments