22
22
#include < util/vector.h>
23
23
24
24
#include < memory>
25
+ #include < numeric>
25
26
#include < optional>
26
27
#include < string>
27
28
#include < vector>
@@ -706,6 +707,17 @@ class DescriptorImpl : public Descriptor
706
707
}
707
708
708
709
std::optional<OutputType> GetOutputType () const override { return std::nullopt; }
710
+
711
+ std::optional<int64_t > ScriptSize () const override { return {}; }
712
+
713
+ /* * A helper for MaxSatisfactionWeight.
714
+ *
715
+ * @param use_max_sig Whether to assume ECDSA signatures will have a high-r.
716
+ * @return The maximum size of the satisfaction in raw bytes (with no witness meaning).
717
+ */
718
+ virtual std::optional<int64_t > MaxSatSize (bool use_max_sig) const { return {}; }
719
+
720
+ std::optional<int64_t > MaxSatisfactionWeight (bool ) const override { return {}; }
709
721
};
710
722
711
723
/* * A parsed addr(A) descriptor. */
@@ -725,6 +737,8 @@ class AddressDescriptor final : public DescriptorImpl
725
737
}
726
738
bool IsSingleType () const final { return true ; }
727
739
bool ToPrivateString (const SigningProvider& arg, std::string& out) const final { return false ; }
740
+
741
+ std::optional<int64_t > ScriptSize () const override { return GetScriptForDestination (m_destination).size (); }
728
742
};
729
743
730
744
/* * A parsed raw(H) descriptor. */
@@ -746,6 +760,8 @@ class RawDescriptor final : public DescriptorImpl
746
760
}
747
761
bool IsSingleType () const final { return true ; }
748
762
bool ToPrivateString (const SigningProvider& arg, std::string& out) const final { return false ; }
763
+
764
+ std::optional<int64_t > ScriptSize () const override { return m_script.size (); }
749
765
};
750
766
751
767
/* * A parsed pk(P) descriptor. */
@@ -766,6 +782,19 @@ class PKDescriptor final : public DescriptorImpl
766
782
public:
767
783
PKDescriptor (std::unique_ptr<PubkeyProvider> prov, bool xonly = false ) : DescriptorImpl(Vector(std::move(prov)), " pk" ), m_xonly(xonly) {}
768
784
bool IsSingleType () const final { return true ; }
785
+
786
+ std::optional<int64_t > ScriptSize () const override {
787
+ return 1 + (m_xonly ? 32 : m_pubkey_args[0 ]->GetSize ()) + 1 ;
788
+ }
789
+
790
+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
791
+ const auto ecdsa_sig_size = use_max_sig ? 72 : 71 ;
792
+ return 1 + (m_xonly ? 65 : ecdsa_sig_size);
793
+ }
794
+
795
+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
796
+ return *MaxSatSize (use_max_sig) * WITNESS_SCALE_FACTOR;
797
+ }
769
798
};
770
799
771
800
/* * A parsed pkh(P) descriptor. */
@@ -782,6 +811,17 @@ class PKHDescriptor final : public DescriptorImpl
782
811
PKHDescriptor (std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), " pkh" ) {}
783
812
std::optional<OutputType> GetOutputType () const override { return OutputType::LEGACY; }
784
813
bool IsSingleType () const final { return true ; }
814
+
815
+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 1 + 20 + 1 + 1 ; }
816
+
817
+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
818
+ const auto sig_size = use_max_sig ? 72 : 71 ;
819
+ return 1 + sig_size + 1 + m_pubkey_args[0 ]->GetSize ();
820
+ }
821
+
822
+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
823
+ return *MaxSatSize (use_max_sig) * WITNESS_SCALE_FACTOR;
824
+ }
785
825
};
786
826
787
827
/* * A parsed wpkh(P) descriptor. */
@@ -798,6 +838,17 @@ class WPKHDescriptor final : public DescriptorImpl
798
838
WPKHDescriptor (std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), " wpkh" ) {}
799
839
std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32; }
800
840
bool IsSingleType () const final { return true ; }
841
+
842
+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 20 ; }
843
+
844
+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
845
+ const auto sig_size = use_max_sig ? 72 : 71 ;
846
+ return (1 + sig_size + 1 + 33 );
847
+ }
848
+
849
+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
850
+ return MaxSatSize (use_max_sig);
851
+ }
801
852
};
802
853
803
854
/* * A parsed combo(P) descriptor. */
@@ -842,6 +893,22 @@ class MultisigDescriptor final : public DescriptorImpl
842
893
public:
843
894
MultisigDescriptor (int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false ) : DescriptorImpl(std::move(providers), sorted ? " sortedmulti" : " multi" ), m_threshold(threshold), m_sorted(sorted) {}
844
895
bool IsSingleType () const final { return true ; }
896
+
897
+ std::optional<int64_t > ScriptSize () const override {
898
+ const auto n_keys = m_pubkey_args.size ();
899
+ auto op = [](int64_t acc, const std::unique_ptr<PubkeyProvider>& pk) { return acc + 1 + pk->GetSize ();};
900
+ const auto pubkeys_size{std::accumulate (m_pubkey_args.begin (), m_pubkey_args.end (), int64_t {0 }, op)};
901
+ return 1 + BuildScript (n_keys).size () + BuildScript (m_threshold).size () + pubkeys_size;
902
+ }
903
+
904
+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
905
+ const auto sig_size = use_max_sig ? 72 : 71 ;
906
+ return (1 + (1 + sig_size) * m_threshold);
907
+ }
908
+
909
+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
910
+ return *MaxSatSize (use_max_sig) * WITNESS_SCALE_FACTOR;
911
+ }
845
912
};
846
913
847
914
/* * A parsed (sorted)multi_a(...) descriptor. Always uses x-only pubkeys. */
@@ -867,6 +934,15 @@ class MultiADescriptor final : public DescriptorImpl
867
934
public:
868
935
MultiADescriptor (int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false ) : DescriptorImpl(std::move(providers), sorted ? " sortedmulti_a" : " multi_a" ), m_threshold(threshold), m_sorted(sorted) {}
869
936
bool IsSingleType () const final { return true ; }
937
+
938
+ std::optional<int64_t > ScriptSize () const override {
939
+ const auto n_keys = m_pubkey_args.size ();
940
+ return (1 + 32 + 1 ) * n_keys + BuildScript (m_threshold).size () + 1 ;
941
+ }
942
+
943
+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
944
+ return (1 + 65 ) * m_threshold + (m_pubkey_args.size () - m_threshold);
945
+ }
870
946
};
871
947
872
948
/* * A parsed sh(...) descriptor. */
@@ -879,16 +955,34 @@ class SHDescriptor final : public DescriptorImpl
879
955
if (ret.size ()) out.scripts .emplace (CScriptID (scripts[0 ]), scripts[0 ]);
880
956
return ret;
881
957
}
958
+
959
+ bool IsSegwit () const { return m_subdescriptor_args[0 ]->GetOutputType () == OutputType::BECH32; }
960
+
882
961
public:
883
962
SHDescriptor (std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), " sh" ) {}
884
963
885
964
std::optional<OutputType> GetOutputType () const override
886
965
{
887
966
assert (m_subdescriptor_args.size () == 1 );
888
- if (m_subdescriptor_args[ 0 ]-> GetOutputType () == OutputType::BECH32 ) return OutputType::P2SH_SEGWIT;
967
+ if (IsSegwit () ) return OutputType::P2SH_SEGWIT;
889
968
return OutputType::LEGACY;
890
969
}
891
970
bool IsSingleType () const final { return true ; }
971
+
972
+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 20 + 1 ; }
973
+
974
+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
975
+ if (const auto sat_size = m_subdescriptor_args[0 ]->MaxSatSize (use_max_sig)) {
976
+ if (const auto subscript_size = m_subdescriptor_args[0 ]->ScriptSize ()) {
977
+ // The subscript is never witness data.
978
+ const auto subscript_weight = (1 + *subscript_size) * WITNESS_SCALE_FACTOR;
979
+ // The weight depends on whether the inner descriptor is satisfied using the witness stack.
980
+ if (IsSegwit ()) return subscript_weight + *sat_size;
981
+ return subscript_weight + *sat_size * WITNESS_SCALE_FACTOR;
982
+ }
983
+ }
984
+ return {};
985
+ }
892
986
};
893
987
894
988
/* * A parsed wsh(...) descriptor. */
@@ -905,6 +999,21 @@ class WSHDescriptor final : public DescriptorImpl
905
999
WSHDescriptor (std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), " wsh" ) {}
906
1000
std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32; }
907
1001
bool IsSingleType () const final { return true ; }
1002
+
1003
+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 32 ; }
1004
+
1005
+ std::optional<int64_t > MaxSatSize (bool use_max_sig) const override {
1006
+ if (const auto sat_size = m_subdescriptor_args[0 ]->MaxSatSize (use_max_sig)) {
1007
+ if (const auto subscript_size = m_subdescriptor_args[0 ]->ScriptSize ()) {
1008
+ return GetSizeOfCompactSize (*subscript_size) + *subscript_size + *sat_size;
1009
+ }
1010
+ }
1011
+ return {};
1012
+ }
1013
+
1014
+ std::optional<int64_t > MaxSatisfactionWeight (bool use_max_sig) const override {
1015
+ return MaxSatSize (use_max_sig);
1016
+ }
908
1017
};
909
1018
910
1019
/* * A parsed tr(...) descriptor. */
@@ -958,6 +1067,13 @@ class TRDescriptor final : public DescriptorImpl
958
1067
}
959
1068
std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32M; }
960
1069
bool IsSingleType () const final { return true ; }
1070
+
1071
+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 32 ; }
1072
+
1073
+ std::optional<int64_t > MaxSatisfactionWeight (bool ) const override {
1074
+ // FIXME: We assume keypath spend, which can lead to very large underestimations.
1075
+ return 1 + 65 ;
1076
+ }
961
1077
};
962
1078
963
1079
/* We instantiate Miniscript here with a simple integer as key type.
@@ -1041,6 +1157,13 @@ class MiniscriptDescriptor final : public DescriptorImpl
1041
1157
1042
1158
bool IsSolvable () const override { return true ; }
1043
1159
bool IsSingleType () const final { return true ; }
1160
+
1161
+ std::optional<int64_t > ScriptSize () const override { return m_node->ScriptSize (); }
1162
+
1163
+ std::optional<int64_t > MaxSatSize (bool ) const override {
1164
+ // For Miniscript we always assume high-R ECDSA signatures.
1165
+ return m_node->GetWitnessSize ();
1166
+ }
1044
1167
};
1045
1168
1046
1169
/* * A parsed rawtr(...) descriptor. */
@@ -1059,6 +1182,13 @@ class RawTRDescriptor final : public DescriptorImpl
1059
1182
RawTRDescriptor (std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(Vector(std::move(output_key)), " rawtr" ) {}
1060
1183
std::optional<OutputType> GetOutputType () const override { return OutputType::BECH32M; }
1061
1184
bool IsSingleType () const final { return true ; }
1185
+
1186
+ std::optional<int64_t > ScriptSize () const override { return 1 + 1 + 32 ; }
1187
+
1188
+ std::optional<int64_t > MaxSatisfactionWeight (bool ) const override {
1189
+ // We can't know whether there is a script path, so assume key path spend.
1190
+ return 1 + 65 ;
1191
+ }
1062
1192
};
1063
1193
1064
1194
// //////////////////////////////////////////////////////////////////////////
0 commit comments